Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОСНОВЫ ОФИСНОГО ПРОГРАММИРОВАНИЯ И ЯЗЫК VBA - 2....doc
Скачиваний:
79
Добавлен:
17.12.2018
Размер:
1.62 Mб
Скачать

Примеры работы с Win32 api функциями

Разговор об особенностях вызова Win32 API функций еще не закончен. Тем не менее, пора прервать общее изложение и обратиться к примерам. Многое из того, что было сказано, целесообразно проиллюстрировать примерами работы с конкретными функциями Win 32 API. Каждый из наших примеров будет посвящен работе с некоторой группой функций.

Работа с окнами

Как мы уже говорили, окна - это один из основных объектов операционной системы. Функции для работы с ними находятся, в основном, в библиотеке User32. Из большого множества функций мы отобрали несколько функций, позволяющих продемонстрировать, как можно получать описатели окон, как, зная описатель, можно получать характеристики окон и как можно изменять характеристики окон. Начнем с приведения программного текста, а уж потом подробно прокомментируем его. Заметим, что для получения корректного описания операторов Declare, используемых типов данных и констант мы использовали API Viewer и описание функций, которое можно найти на уже упоминавшемся сервере Microsoft.

В проекте нашего тестового документа был создан модуль "Окна" и в разделе его объявлений помещен следующий текст:

Option Explicit

'Константы

Public Const SW_HIDE = 0

Public Const SW_SHOWNORMAL = 1

Public Const SW_SHOWMINIMIZED = 2

Public Const SW_SHOWMAXIMIZED = 3

'Типы

Public Type RECT

Left As Long

Top As Long

Right As Long

Bottom As Long

End Type

'Функции

Public Declare Function GetActiveWindow Lib "user32" () As Long

Public Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, _

lpRect As RECT) As Long

Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _

(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _

(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, _

ByVal nCmdShow As Long) As Long

Public Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" _

(ByVal hwnd As Long, ByVal lpString As String) As Long

Пример 6.1. (html, txt)

Дадим краткую характеристику используемых функций:

  1. GetActiveWindow возвращает описатель активного окна.

  2. GetWindowRect получает в качестве входного параметра описатель окна hwnd и возвращает значения полей структуры Rect, переданной функции в качестве второго параметра lpRect. Заметьте, тип Rect должен быть предварительно определен. Обратите внимание, первый параметр передается по значению, а второй по ссылке. Передача по ссылке позволяет функции заполнить значениями поля переданной ей структуры. Значения этих полей задают координаты прямоугольника, определяющего положение окна на экране дисплея. Возвращаемый функцией результат будет равен нулю, если выполнение функции закончится неуспехом, например, при некорректном задании описателя.

  3. GetWindowText по описателю окна возвращает его заголовок. Поскольку функция должна вернуть строку, то, как мы говорили ранее, ей передаются два параметра - lpString и cch, задающие строку и число символов, доступных для заполнения. Обратите внимание, здесь используется псевдоним с окончанием A, указывающим на использование кодировки ANSI. Опять-таки, результат, возвращаемый функцией, зависит от успеха операции.

  4. FindWindow возвращает описатель окна. Функция ищет окно и возвращает в случае успеха описатель этого окна. Окно ищется либо по имени класса, заданного параметром lpClassName, либо по заголовку, заданному параметром lpWindowName. При вызове может быть задан только один из этих параметров, второй может быть указателем с неопределенным значением.. Поскольку параметр может быть либо указателем, имеющим тип Long, либо строкой, то в предыдущих версиях по этой причине для обоих параметров следовало указывать тип Any. Теперь указывается тип String, поскольку введена специальная константа vbNullString, формально имеющая тип String, но позволяющая передать указатель со значением Null.

  5. ShowWindow позволяет сделать видимым или невидимым окно, заданное описателем, может также минимизировать, максимизировать или нормализовать его размеры. Соответствующее действие определяется вторым параметром, значения которого задаются соответствующей константой. В разделе объявлений модуля мы определили возможные значения этих констант, которые будут использованы в процессе вызова этой функции.

  6. SetWindowText позволяет установить новый заголовок окна. Является функцией, парной к функции GetWindowText, но, поскольку здесь строка заголовка передается функции, то функция устроена проще, имеет два, а не три параметра и передавать ей можно константу, что и будет продемонстрировано в нашем примере.

Приведем теперь процедуру, в которой поочередно запускаются описанные здесь функции (В примерах используются документы: DocOne6, DocTwo6

Public Sub WorkWithWindows()

Dim Res As Long 'Результат выполнения функции

Dim HandleAW As Long 'Описатель активного окна

Dim RectAW As RECT 'Структура, задающая прямоугольник окна

Dim TextAW As String 'Заголовок активного окна

Dim LenTextAW As Long 'Длина строки

Dim HandleW As Long 'Описатель окна

Dim TextW As String 'Заголовок окна

'Получить описатель активного окна

HandleAW = GetActiveWindow

Debug.Print HandleAW

'Получить прямоугольник, задающий положение активного окна

Res = GetWindowRect(HandleAW, RectAW)

Debug.Print Res

If Res > 0 Then 'OK

Debug.Print "Размеры окна: Left = ", RectAW.Left, " Top = ", _

RectAW.Top, " Right = ", RectAW.Right, " Bottom = ", RectAW.Bottom

Else:

MsgBox ("Не удалось получить размеры активного окна")

End If

'Получить заголовок окна

'Предварительная набивка результирующей строки нулевыми символами

TextAW = VBA.String$(255, vbNullChar)

LenTextAW = VBA.Len(TextAW)

Res = GetWindowText(HandleAW, TextAW, LenTextAW)

Debug.Print Res

If Res > 0 Then 'OK

TextAW = VBA.Left(TextAW, VBA.InStr(1, TextAW, vbNullChar) - 1)

Debug.Print TextAW

Else:

MsgBox ("Не удалось получить заголовок активного окна")

End If

'Поиск окна документа по его заголовку

'Возвращается описатель окна

TextW = "DocOne6 - Microsoft Word"

HandleW = FindWindow(vbNullString, TextW)

If HandleW > 0 Then 'OK

Debug.Print HandleW

Else:

MsgBox ("Не удалось найти окно с указанным заголовком" _

& vbCrLf & TextW)

End If

'Минимизация и нормализация окна документа

Res = ShowWindow(HandleW, SW_SHOWMINIMIZED)

If Res > 0 Then Debug.Print "Окно минимизировано"

Res = ShowWindow(HandleW, SW_SHOWNORMAL)

If Res > 0 Then Debug.Print "Окно в нормальном состоянии"

'Изменение заголовка окна

TextW = "Document1 - Microsoft Word"

HandleW = FindWindow(vbNullString, TextW)

If HandleW > 0 Then 'OK

Debug.Print HandleW

Else:

MsgBox ("Не удалось найти окно с указанным заголовком" _

& vbCrLf & TextW)

End If

Res = SetWindowText(HandleW, "DocTwo6 - Microsoft Word")

End Sub

Пример 6.2. (html, txt)

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

655706

1

Размеры окна: Left = 8 Top = 73 Right = 769 Bottom = 580

58

Microsoft Visual Basic - DocOne6 [running] - [Окна (Code)]

6684884

Окно минимизировано

Окно в нормальном состоянии

191103490

Дадим комментарии к работе этой процедуры:

  • Вначале, при вызове функции API GetActiveWindow был получен описатель активного окна. Заметим, что это было окно кода выполняемой процедуры. Значение этого описателя равно 655706.

  • Затем, при вызове функции GetWindowRect, был получен прямоугольник, определяющий положение окна на экране. Функция успешно завершила работу и вернула результат, равный 1 (истина). Как и в остальных случаях, по окончании выполнения функции мы проверили результат на успешность завершения.

  • На следующем шаге был получен заголовок активного окна. Как видно из распечатки заголовка, активным являлось выполняемое окно кода. Результат 58, который вернула функция GetWindowText, задает число символов результирующей строки. Обратите внимание, перед вызовом функции передаваемая ей строка была инициализирована нулевыми символами. После успешного завершения из строки был выделен результат, задающий заголовок. Его печать показывает, что активным в момент запуска функции было выполняемое окно кода. Для выделения заголовка из строки использовался нулевой символ, как признак окончания заголовка. Для решения этой задачи можно было использовать и число возвращаемых символов - значение, возвращаемое функцией.

  • Следующим шагом было получение описателя окна по заданному заголовку. В качестве такового был использован заголовок окна с тестовым документом. Функция FindWindow нашла такое окно и вернула его описатель, равный 6684884. Обратите внимание, первый параметр был задан константой vbNullString.

  • Окно, описатель которого был получен в последнем вызове, дважды перестраивалось, - вначале минимизировалось, затем нормализовалось, - при двух вызовах функции ShowWindow с различными значениями констант.

  • На последнем этапе снова вызывалась функция FindWindow для нахождения описателя вновь открытого документа. Затем при вызове функции SetWindowText был изменен заголовок этого окна. Заметьте, новое значение заголовка передавалось функции в виде обычной строковой константы.