Пособие-самоучитель on-line "Visual Basic с нуля"
§ 3. Окна. Иерархия окон. Десктоп - разрешение экрана. Структура RECT.
Скачать исходник примера
Дата создания 26.06.2005{Автор 4us}

Новые API-функции, используемые в этом параграфе.
Функция GetDesktopWindow
Назначение Возвращает хендл Десктопа (или экрана или рабочего стола)
Объявление Declare Function GetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Long
Аргументы нет
Функция GetDesktopWindow возвращает хендл окна рабочего стола.
Функция GetWindowRect
Назначение Получает в структуру RECT прямоугольник, содержащий все окно, включая рамки, заголовок, полсы прокрутки и т.д.
Объявление Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Аргументы hwnd (Long) - хендл окна, для которого получают прямоугольник
lpRect (RECT) - прямоугольник для размеров окна в экранных координатах
Объявление структуры RECT:
Type RECT '16 Байт
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Поля Left и Top определяют координаты первого (обычно левого верхнего) угла, поля Right и Bottom - противоположного. Точка с координатами left; bottom в сам прямоугольник не входит.
Далее любая переменная объявляется с типом RECT, например
retval :
Public retval As RECT 'если в модуле
Private
retval As RECT 'если в форме
Функция GetWindowRect возвращает ненулевое значение в случае успеха операции и ноль при неудаче.

Итак, друг мой, снова засучим рукава и своей грубой мозолистой рабоче-крестьянской рукой полезем в кишочки Windows. По-скольку мы гимназиев не кончали, то не будем делать умного лица и говорить непонятных слов. Открываем VB и объявляем функции.
Но прежде чем продолжать измываться над API, скажу пару слов о том, что всем и так известно - об иерахии окон, т.е. об отношении окон друг к другу (типа: кто здесь главный). Может не совсем к месту, но я давно нарисовал картиночку с окнами и ужас как хочу ее куда-нибудь влепить.
Ну так вот. Во-первых, самое главное окно, специфическое окно это - Desktop - т.е. наш экран монитора - там где ты любишь ставить свои дурацкие обои, где висят иконки и на который выскакивает ScreenSaver в самый неподходящий момент.
Думаю, я не смогу поразить тебя следующими заявлением:
Окно может иметь дочерние и родительские окна.
Посмотрим на все ж на мою картиночку - рисунок 5.


Рисунок 5.

Для окна 1 окна 3 и 4 являются дочерними, поскольку они физически находятся внутри этого окна. А окно 1 для них является родительским. Окно 5 тоже имеет родителем окно 1. Но оно находится в другом месте экрана и называется собственным. Окна, которые не имеют родителей (окно 1 и окно 2) называются окнами верхнего уровня. Кроме того они находятся на одном уровне иерархии, поэтому являются соседями. Окна 3 и 4 - тоже соседи. А по отношению к Десктопу окна 1 и 2 являются дочерними. Все это будет важно при наших попытках работать с окнами, потому что ряд API-функций конкретно предназначены для нахождения окна, исходя именно из его иерархического положения.

В принципе, окна 1 и 2 на самом деле являются дочерними окнами к десктопу. Для чего я это говорю. Часто поиск хендла окна начинается именно с десктопа - специфического окна, хендл которого всегда под рукой.
Итак, поскольку десктоп всегда под рукой, то искать его не надо. Чтобы определить хендл десктопа, надо просто объявить и использовать функцию GetDesktopWindow. Например в коде формы (не создавая стандартного модуля) в процедуре кнопки Command1 это выглядит так:

Option Explicit
Private Declare Function
GetDesktopWindow Lib "user32" () As Long

Private Sub Command1_Click()
'объявляем переменную, в которую функция возвратит хендл десктопа
Dim HandleDesktop As Long
'используем функцию
HandleDesktop = GetDesktopWindow()
'выводим значение хендла десктопа в Text1
Text1 = HandleDesktop
End Sub

Обычно хендл не надо присваивать в переменную, здесь это сделано чисто иллюстративно. Если нам нужен хендл десктопа, можно сразу, вместо хендла использовать функцию GetDesktopWindow.

Мы, например, можем получить разрешение экрана. Конечно, это можно сделать и внутренними возможностями VB (объект Screen), но тем не менее. Для этого используем функцию GetWindowRect. С помощью этой функции мы на самом деле можем получить размеры окна. А размер окна desktop собственно и есть разрешение экрана. Создадим новый exe-проект, положим на форму Label1 и Command1, в процедуре которой и будем писать код. Создавать стандартный модуль опять-таки не будем.

'Сперва в разделе Declaration объявим функцию для определения хендла десктопа:
Option Explicit
Private Declare Function GetDesktopWindow Lib "user32" () As Long
'и нашу функцию для определения размеров прямоугольника
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long


Здесь, как мы видим, требуется структура RECT, в которую возвращаются размеры окна. Ранее мы уже использовали структуру POINTAPI в параграфе 2. Наша новая структура RECT тоже очень нужная структура, и мы разберем ее поподробней, но сначала объявим:

Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type


Итак в структуру входят четыре поля, из которых первые два Left и Top определяют координаты первого угла прямоугольника, а два других Right и Bottom - противоположного. Совсем необязательно первый угол будет верхним левым. На самом деле он может быть и внизу и справа. Координаты его могут быть и положительными и отрицательными, т.е. реально все зависит, как данные будут прописаны в структуру, так как расположение противоположных углов выбирается условно.
Кроме того имеется еще один нюанс: точка, определенная полями Right и Bottom сама не входит в прямоугольник, а выдвинута из него на 1 пиксель. Из это вытекает, что ширина и высота прямоугольника вычисляется простым вычитанием (если первый угол - верхний левый, т.е. нормальная ситуация):
Ширина = .right - .left
Высота = .bottom - .top
или их модулей (абсолютных величин), если прямоугольник как бы вывернутый. А кроме того прямоугольник вообще может не содержать ни одного пиксела, т.е. быть пустым. На нижеследующим рисунке показана типичная экранная система координат. На ней красным обозначено классическое расположение точек углов прямоугольника:

Однако может быть, например и наоборот (показано голубым цветом). Все эти сведения нам несомненно понадобятся в будущем.

Вернемся к нашему коду. Дальнейший код будем писать в процедуре кнопки Command1:

Private Sub Command1_Click()
'объявим переменную для возвращаемого значения функции GetWindowRect
Dim ddd As Long
'и переменную как RECT для структуры нашего десктопа
Dim SizeScreen As RECT
'используем функциюGetWindowRect, причем в ней вместо хендла десктопа сразу применяем функцию GetDesktopWindow
ddd = GetWindowRect (GetDesktopWindow(), SizeScreen)
'выводим готовый результат на экран
Label1 = "Разрешение " & SizeScreen.Right & " x " & SizeScreen.Bottom
End Sub


Если что не так, скачать этот малюсенький код можно вверху страницы.

Copyright © 2005 4us




Сайт создан в системе uCoz