ПРОГРАММИРОВАНИЕ И ДИЗАЙН
Выпуск #19 - 26 июня 2002 года (архив рассылки)
Всего подписчиков: 5915
В этом выпуске:
 > Новости сайта
 > Вопросы читателей (0)
 > Ответы на предыдущие вопросы (12)
 > Примеры кода на VB
 > API функции
 > Ссылки
 > Авторам
Новости сайта
26 июня 2002
 > Вышел 19й выпуск рассылки.
 > Добавлены 3 новых модуля для VB

http://prs.narod.ru - всё для программиста и WEB мастера.
Вопросы читателей
На все присланные вопросы ответил автор рассылки, т.е. я :-)
поэтому новых писем нет. Те, кто прислал вопросы могут сразу смотреть раздел Ответы на предыдущие вопросы.

Вопросы задавайте на этой странице, на e-mail: prs@narod.ru, или заполнив эту форму (отправляется через почтовый клиент):
Вопрос:

(откроется в почтовом клиенте)
Ответы на предыдущие вопросы
34. У кого-нибудь есть исходник архиватора на VB?

Ответ прислал Татарников Виктор
В просторах интернета нашел этот пример - закатал на диск.
Пример интересный, но пока не было времени с ним разбираться.
Смотрю человеку надо - получайте!

С уважением Татарников Виктор.

Скачать приложение к письму (513 КБ)
36. Помогите пожалуйста. Проблема такая: в браузере IE 5.0 при открытии сохраненной страницы не отображаются GIF'ы, хотя все картинки сохранены в папке ****.files. Заранее благодарю.

Ответ прислал Bogdan Maetchkin
Была у меня такая проблема: вставляю в страницу gif'ы или jpg'и и у меня
вместо них - пустое место. Возможные причины:
1. неправильно указан src (проверить, указать полный путь).
2. расширение GIF и gif - две разные разницы (привести в соответствие)
3. частный случай: я на машину (98 мастдай) апач поставил и файлы
графики клал в cgi-bin (да, вот такой я чайник), естессно ни фига не
отображалось. (файлы графики надо было класть в htdocs, желательно в
отдельную папку).
4. другой частный случай: под UNIX'ами надо права соответствующие
установить для папки и для кажного файла (chmod golayababa.gif 0755).

Ответ прислал bitos@mail.ru
Доброе время суток!

Присылай, помогу!
С уважением.
--
|--------------------------------------------|
|URL: http://www.novopavlovsk.dem.ru/
|E-mail: webmaster@novopavlovsk.dem.ru
|            THE BAT!
|----------------------|
38. Почему при вызове функции RasDial моя программа завиает на время подкючения?

Ответ прислал Андрей Исаков
Скорее всего она у тебя ОДНОПОТОЧНАЯ. Она не зависает. Она ждет, пока сервис диалапа ответит, произошло соединение или нет. Вынеси вызов сервиса диалапа в отдельный поток. Только не забудь сделать синхронизацию, т.е., чтобы процедуры приема/передачи данных не могли выполняться, пока сервис диалапа не выдаст ОК.

Ответ прислал Zero Cool
Все правильно. Программа запускает функцию RasDial и ждет, пока она выполнится. Чтоб этого не происходило, создай в своей программе нить (функция CreateThread) и вызывай RasDial в этой нитке.

Ответ прислал neo
Вы что-то делаете и начинается процедура (ну, типа, отклик по событию), и пока процедура выполняется (пока значение функция не вернёт) прога висит. Это нормально, даже Outlook Express зависает в момент подключения, многозадачность ведь :-)
40. Как в меню напротив текста положить картинку?

Ответ прислал Павел
Вот откапал среди кучи файлов целых 2 примера (ссылки ниже).

Скачать приложение к письму #1 (2.8 КБ)
Скачать приложение к письму #2 (12.4 КБ)
41. Что вписать в строку инициализации (Extra param.), дабы коннектиться только на V34 ?

Ответ прислал Павел
Нужно воспользоваться командой AT+MS:
AT+MS=протокол, режим выбора протокола, минимальная скорость, максимальная скорость.

Для ограничения скорости до 21600 на протоколе v34 нужно писать:
AT+MS=11,1,300,21600
Для ограничения скорости до 56000 на протоколе v90 нужно писать:
AT+MS=12,1,28000,56000
Для ограничения скорости до 56000 на протоколе K56 нужно писать:
AT+MS=56,1,32000,56000

Писать AT+MS=11,1,300,56000 нельзя, т.к протокол v34 "не умеет" работать на такой большой скорости.
42. Помогите пожалуйста!
Как в Visual Basic 6.0 узнать заголовок активного окна в системе с помощью Win32 АРI?
C заранее благодарен!

Ответ прислал Павел
Создай новый проект и добавь на форму таймер. Задай его свойству Interval значение "100", а затем добавь следующий код в форму:

'API для определения номера активного окна
Private Declare Function GetForegroundWindow _
Lib "user32" () As Long

'АПИ для определения длины заголовка окна
Private Declare Function GetWindowTextLength _
Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hwnd As Long) As Long

'АПИ для определения текста заголовка
Private Declare Function GetWindowText Lib _
"user32" Alias "GetWindowTextA" (ByVal hwnd As _
Long, ByVal lpString As String, ByVal cch As _
Long) As Long

Private Sub Timer1_Timer()
'Номер окна
Dim WndNum As Long
'Определяем активного номер окна
WndNum = GetForegroundWindow

'Длина заголовка окна
Dim TextLength As Long
'Определяем длину
TextLength = GetWindowTextLength(WndNum) + 1

'Заголовок
Dim Caption As String
'Заполняем строку пробелами
Caption = String(TextLength, " ")
'Определяем заголовок
GetWindowText WndNum, Caption, Len(Caption)
Caption = Left(Caption, Len(Caption) - 1)

'Очищаем форму и выводим заголовок
Cls
Print Caption
End Sub
43. Подскажите как открыть контретную папку?

Ответ прислал Павел
В VB это можно сделать, запустив "explorer.exe" с помощью функции Shell:
Shell "explorer.exe c:\", vbNormalFocus
Откроется корень диска C:

Можно с помощью WinApi.
В модуль:

'Все переменные необходимо объявлять заранее
Option Explicit

'АПИ для открытия файла с помощью связанной с
'ним программы
Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Function ExecuteFile(ExecuteFileProgramHWND As Long, ExecutableFile As String, Method As Integer)
'При ошибке переходим к следующему оператору
On Error Resume Next

'Вызываем АПИ
ShellExecute ExecuteFileProgramHWND, "Open", _
ExecutableFile, vbNullString, Empty, Method
End Function

В форму:

Private Sub Form_Load()
ExecuteFile Me.hWnd, "c:\", 1
End Sub

Функция Shell в VB может запускать только исполняемые файлы (exe, com, bat), поэтому в 1ом случае запускается Explorer.exe, и в командной строке ему прописывается путь до каталога.

API функция ShellExecute открывает все файлы и папки с помощью той программы, которая с ними связана (например для mp3 файлов WinAmp, т.е. после выполнения ExecuteFile Me.hWnd, "c:\my_music.mp3", 1 запуститься WinAmp или другая программа для проигрывания mp3 файлов), поэтому можно просто писать "c:\".
44. Страница http://sedmica.narod.ru
Сделал вставку куска html-кода с помощью JavaScript'а (document.write(...)). Но появилась новая проблема - страница не показывается, пока полностью (!) не загрузится (в отличие от простого html-a, страница которого показывается по мере загрузки). Это тем более неприятно, что размер странички - около 70 Кб, и ждать приходится долго.

Можно ли сделать так, чтобы страница показывалась по мере загрузки (не дожидаясь, пока вся страница полностью загрузится)?

Можно ли сделать так, чтобы сначала показывался файл index.htm, а когда загрузится нужная страница, осуществлялся автоматический переход на другую страницу? И можно ли сделать процентную строку, которая бы показывала, сколько процентов нужной страницы загрузилось?

С уважением

Paul Lebedev
pel@vinnitsa.com

Ответ прислал Павел
Cделать так, чтобы страница показывалась по мере загрузки, нельзя, т.к. сначала грузится HTML файл, затем скрипт, а уж потом браузер смотрит, что делает скрипт, и выводит результат на экран.

По поводу перехода на другую страницу вопрос не совсем понятен. Но вообще, чтобы перейти на другую страницу с помощью скрипта, нужно писать:
document.location.href='ваша_страница.html'
Если Вы хотите, чтобы браузер автоматически переходил на другую страницу после полной загрузки входной (т.е. когда она появится на экране), нужно вставить эту строку в самый последний скрипт (тот, на который ведёт ссылка в самом конце html файла, в Вашем случае bottom.js). Тогда страница успеет появится, но потом сразу же начнётся загрузка другой.

Процентную строку сделать сложно и тут простым JavaScript'ом не обойтись.

Вопросы задавайте на этой странице, на e-mail: prs@narod.ru, или заполнив эту форму (отправляется через почтовый клиент):
Вопрос:

(откроется в почтовом клиенте)
Примеры кода на VB
Определение всех запущенных процессов
Для этого необходимо воспользоваться API функциями Process32First, Process32Next, CreateToolhelp32Snapshot и CloseHandle. Создайте новый модуль и поместите туда этот код:

'Все переменные необходимо объявлять заранее
Option Explicit

'АПИ для создания SnapShot'а
Declare Function CreateToolhelp32Snapshot Lib "kernel32.dll" _
(ByVal lFlags As Long, ByVal lProcessID As Long) As Long

'АПИ для нахождения первого процесса
Declare Function Process32First Lib "kernel32.dll" (ByVal _
hSnapShot As Long, uProcess As PROCESSENTRY32) As Long

'АПИ для нахождения следующего процесса
Declare Function Process32Next Lib "kernel32.dll" (ByVal _
hSnapShot As Long, uProcess As PROCESSENTRY32) As Long

'АПИ для закрытия указателья
Declare Sub CloseHandle Lib "kernel32.dll" (ByVal hPass As Long)

'Свойства процесса
Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long
    th32DefaultHeapID As Long
    th32ModuleID As Long
    cntThreads As Long
    th32ParentProcessID As Long
    pcPriClassBase As Long
    dwFlags As Long
    szExeFile As String * MAX_PATH
End Type

Нам также понадобятся некоторые константы:

Global Const TH32CS_SNAPHEAPLIST = &H1
Global Const TH32CS_SNAPPROCESS = &H2
Global Const TH32CS_SNAPTHREAD = &H4
Global Const TH32CS_SNAPMODULE = &H8
Global Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
Global Const TH32CS_INHERIT = &H80000000
Global Const MAX_PATH As Integer = 260

Далее создайте функцию GetProcesses:

Function GetProcesses(ProcArray() As PROCESSENTRY32) As Long
'При ошибке переходим к
On Error GoTo GetProcesses_Err

'Переменные:
'SnapShot
Dim SnapShotHandle As Long
'Свойства процесса
Dim ProcessProp As PROCESSENTRY32
'Возвращаемое значение
Dim ProcRet As Long

'Очищаем массив
ReDim ProcArray(0)

'Определяем snapshot процессов, модулей, используемых процессами
SnapShotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&)
'Определяем длину массива
ProcessProp.dwSize = Len(ProcessProp)
'Определяем 1й процесс
ProcRet = Process32First(SnapShotHandle, ProcessProp)

'Если определён процесс, то
Do While ProcRet <> 0
    'Добавляем элемент в массив
    ReDim Preserve ProcArray(UBound(ProcArray) + 1)
    'Определяем его значение
    ProcArray(UBound(ProcArray)) = ProcessProp
    'Определяем следующий процесс
    ProcRet = Process32Next(SnapShotHandle, ProcessProp)
Loop

'Закрываем SnapShot
CloseHandle SnapShotHandle

'Возвращаем 0, т.к. не было ошибок
GetProcesses = 0
'Если возникли ошибки, то возвращаем номер ошибки
Exit Function
GetProcesses_Err:
GetProcesses = Err
End Function

Теперь добавьте на форму таймер, задайте его свойству Interval значение "100" и поместите этот код в форму:

Private Sub Timer1_Timer()
'Массив с процессами
Dim Processes() As PROCESSENTRY32
'Определяем все процессы и кладём их в массив
GetProcesses Processes

'Очищаем форму
Cls
'Для цикла
Dim I As Long
'Буфер
Dim Buf As String
'Устраиваем цикл
For I = 1 To UBound(Processes)
    'Определяем путь до файла процесса:
    'очищаем от нулевых символов
    Buf = Left(Processes(I).szExeFile, InStr(Processes(I).szExeFile, Chr(0)) - 1)
    'Выводим путь до файла процесса на форму
    Print Buf
Next I
End Sub

Таким образом мы получили массив с процессами, каждый элемент которого имеет характеристики отдельного процесса:
cntUsage - сколько процентов системных ресурсов использовано
th32ProcessID - номер процесса
cntThreads - количество потоков в процессе
th32ParentProcessID - номер родительского процесса
dwFlags - свойства процесса
szExeFile - файл процесса

Определение имени временного файла
В некоторых программах, которые Вы когда-то писали (или пишите), приходилось создавать временные файлы, в которые Вы записывали какую-то информацию. В каталоге Windows'а уже есть каталог "Temp", в котором хранятся временные файлы различных приложений. Чтобы "грамотно" сохранить туда файл, т.е. так, чтобы сама Windows "была в курсе", что какая-то программа туда что-то пишет, нужно сначала обратиться к системе, сделав у неё запрос на свободное имя файла. Почему свободное? Да потому что может быть такая ситуация, когда Ваша программа использует не 1 (в этом случае, можно было бы воспользоваться простым созданием файла "Temp.tmp" в каталоге с программой), а 10 или более файлов. И при этом их количество заранее не известно. Как, например, MS Word сохраняет копии открытых документов. Но ведь их может быть и 2 и 20. Тогда Windows определяет имя свободного файла по шаблону: xxx00000. Где "xxx" - любые 3 символа, а "00000" - какое-то число. Так вот чтобы определить имя временного файла нужно воспользоваться WinAPI. Создайте модуль и вставьте туда следующий код:

'Все переменные необходимо объявлять заранее
Option Explicit

'API для определения имени временного файла
Declare Function GetTempFileName Lib _
"kernel32.dll" Alias "GetTempFileNameA" (ByVal _
lpszPath As String, ByVal lpPrefixString As _
String, ByVal wUnique As Long, ByVal _
lpTempFileName As String) As Long

Function GetTempFile(Path As String, Prefix As String) As String
'При ошибке переходим к следующему оператору
On Error Resume Next

'Буфер
Dim TempFileName As String * 255
'Длина строки
Dim BufLen As Integer
'Вызываем функцию
BufLen = GetTempFileName(Path & Chr(0), Prefix & Chr(0), 0, TempFileName)
'Возвращаем имя файла:
'Очищаем от нулевых символов
If InStr(TempFileName, Chr(0)) <> 0 Then
GetTempFile = Left(TempFileName, InStr(TempFileName, Chr(0)) - 1)
Else
GetTempFile = TempFileName
End If
End Function

Теперь, вызывая функцию GetTempFile, Вы получаете имя временного файла в каталоге, который Вы указали в переменной Path. Для того, чтобы файл был в каталоге "windows\temp", нужно воспользоваться модулем gettempdir.bas, с помощью которого можно определить где находится временный каталог.

Как распаковать файл типа *.??_
Для этого воспользуемся АПИ функциями LZOpenFile, LZCopy и LZClose для открытия, копирования и закрытия файла соответственно (в модуль):

'Все переменные необходимо объявлять заранее
Option Explicit

'Открываем файл
Declare Function LZOpenFile Lib "lz32.dll" _
Alias "LZOpenFileA" (ByVal lpszFile As String, _
lpOf As OFSTRUCT, ByVal style As Long) As Long

'Копирует файл (и распаковывает, если копируемый файл запакован)
Declare Function LZCopy Lib "lz32.dll" _
(ByVal hfSource As Long, ByVal hfDest As Long) As Long

'Закрывает файл
Declare Sub LZClose Lib "lz32.dll" (ByVal _
hfFile As Long)

'Структура для открытия файлов
Type OFSTRUCT
    cBytes As Byte
    fFixedDisk As Byte
    nErrCode As Integer
    Reserved1 As Integer
    Reserved2 As Integer
    szPathName As String * 128
End Type

'Константы:
'Открыть файл
Const OF_READ = &H0
'Создать файл
Const OF_CREATE = &H1000
'Ошибки:
'Global Const LZERROR_BADINHANDLE = (-1)
'Global Const LZERROR_BADOUTHANDLE = (-2)
'Global Const LZERROR_BADVALUE = (-7)
'Global Const LZERROR_GLOBLOCK = (-6)
'Global Const LZERROR_PUBLICLOC = (-5)
'Global Const LZERROR_READ = (-3)
'Global Const LZERROR_UNKNOWNALG = (-8)
'Global Const LZERROR_WRITE = (-4)

Теперь функция для распаковки (тоже в модуль):

Function LZDecompress(SourceFile As String, DestFile As String) As Long
'При ошибке переходим к следующему оператору
On Error Resume Next

'Переменные с параметрами файлов
Dim SourceStruct As OFSTRUCT
Dim DestStruct As OFSTRUCT
'Указатель на исходный и конечный файл
Dim hSource As Long
Dim hDest As Long

'Открываем исходный и конечный файлы
hSource = LZOpenFile(SourceFile, SourceStruct, OF_READ)
hDest = LZOpenFile(DestFile, DestStruct, OF_CREATE)

'Копируем исходный в конечный
LZDecompress = LZCopy(hSource, hDest)

'Закрываем файлы
LZClose hSource
LZClose hDest
End Function

А теперь в форму:

Private Sub Form_Load()
LZDecompress "C:\MyFile.tx_", "C:\MyFile.txt"
End Sub

Вот, в принципе, и всё. Теперь, подключая этот модуль к проекту, Вы можете распаковывать такие файлы только одной строчкой.


Скачать все 3 модуля в отдельных файлах можно на этой странице

У Вас есть свои примеры, возможно даже не на VB? Тогда присылайте их к нам на e-mail! Опубликуем всё :-)
API функции
Процедура CreateThread
Описание: The CreateThread function creates a thread to execute within the address space of the calling process.
Объявление: Для Visual Basic:
Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type

Declare Function CreateThread Lib "kernel32" Alias "CreateThread" (lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal dwStackSize As Long, lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Параметры: lpThreadAttributes
Указатель на переменную типа SECURITY_ATTRIBUTES, которая определяет атрибуты потока. Windows NT: переменная lpSecurityDescriptor структуры определяет степень важности для нового потока. Если lpThreadAttributes принимает значение NULL, то поток получает значение по умолчанию. Windows 95: lpSecurityDescriptor игнорируется.

dwStackSize
Определяет размер, в байтах, стека для нового потока. Если указано 0, то размер стека принимает размер такой же, как и размер главного потока.

lpStartAddress
Начальный адрес нового потока. Это адрес функции, которая начнёт выполняться в новом потоке. Чтобы определить адрес функции в VB нужно воспользоваться функцией AddressOf:
AddressOf Ваша_функция

lpParameter
Определяет значение параметера, отправляемого в поток.

dwCreationFlags
Флаг, с которым будет создаваться поток (все константы типа CREATE_* можно посмотреть в API Viewer). Если этот параметер не нужен, то можно указать значение NULL (ByVal 0).

lpThreadId
Этот параметр содержит ID создаваемого потока.

Возвращаемое значение: В случае ошибки функция возвращает 0 или адрес потока, в успешном случае.

Функция TerminateThread
Описание: TerminateThread уничтожает поток.
Объявление: Для Visual Basic:
Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Параметры: hThread
Указатель на поток, который нужно уничтожить.
Windows NT: указатель должен иметь право доступа THREAD_TERMINATE.

dwExitCode
Определяет код выхода. Используйте функцию GetExitCodeThread для получения значения кода выхода.

Возвращаемое значение: В случае ошибки функция возвращает 0 или ненулевое значение, в успешном случае.
Ссылки
Program Studio
Всё для программиста и WEB мастера.

Хотите увидеть здесь Вашу ссылку? Тогда пишите на prs@narod.ru!
Авторам
Вы хотите, чтобы Ваши материалы были опубликованы в этой рассылке? Тогда пишите - prs@narod.ru. В качестве гонорара Вы получите от 100 до 10000 баннерных показов сети RLE (Gold), а также посетителей, которые зайдут к Вам на сайт со ссылок после статьи и в разделе "Ссылки". Давайте делать рассылку вместе!
Все выпуски рассылки, начиная с первого, Вы можете прочитать в архиве рассылки.

Сайт рассылки: Program Studio - всё для программиста и WEB мастера
Автор рассылки: Павел Николаевич

Ваши предложения, жалобы и рекомендации можете присылать на prs@narod.ru
be number one
Hosted by uCoz