Программа демонстрирующая иерархию окон Windows
, а вспомогательное
окно.
Из всех концепций системы управления окнами наиболее фундаментальной
является отношение предок/ потомок/ сосед. Как мы видели при описании
структуры данных WND, каждое окно содержит логический номер окна своего
предка, логический номер своего первого дочернего окна и логический номер
следующего соседнего окна. Соседними являются окна, имеющие одинаковое
родительское окно. В действительности значения HWND являются просто
ближними указателями в локальной "куче" модуля USER, поэтому вы можете
рассматривать их как указатели связного списка, которые позволяют обходить
пути в иерархии окон. Иерархия окон, создаваемая модулем USER, показана на
рис.1.
Иерархия окон обходится во всех трех направлениях - от предка к потомку, от
потомка к предку и от соседа к соседу. Примеры обхода иерархии включают
следующее:
• При уничтожении окна модуль USER должен уничтожить всех его потомков, а
также их потомков. USER обходит всю иерархию, используя поля hWndChild и
hWndNext- Напомним, логические номера окон являются просто ближними
указателями в локальной "куче" модуля USER.
• Когда происходит передача фокуса ввода при нажатии клавиши Tab между
элементами управления в окне диалога (которые являются потомками окна
диалога), указатели на соседнее окна (или поле hWndNext) соединяют друг с
другом элементы управления. Кроме того, упорядочение окон в списке
hWndChild и hWndNext отражает Z-порядок окон на экране. Z-порядок
представляет собой относительную позицию окон в третьем измерении (в
направлении от экрана к вам). Если вы щелчком кнопки мыши выбираете
различные основные окна;
чтобы поместить их в вершину Z-порядка, их относительные позиции в списке
hWndNext сдвигаются.
Рис..1 Иерархия окон, созданная модулем USER.
• Когда с помощью щелчка кнопки мыши вы выбираете диалоговое управляющее
окно, это приводит к тому, что менеджер диалогов просмаривает цепочку
указателей предка, чтобы посмотреть, необходимо ли сделать активным окно
приложения верхнего уровня (основное).
В корне дерева окон находится desktop-окно. Это окно покрывает весь экран и
всегда находится на вершине Z-порядка. Это означает, что оно всегда
находится позади всех других окон. Desktop-окно является первым созданным
окном, и это единственное окно в системе, которое не имеет окна родителя
или владельца. (Окна-владельцы описаны далее.) Окраска окна фона отвечает
за "обои" Windows.
Desktop-окно ничем особенным не выделяется в смысле установки специальных
битов или т.п. Оно создается с битами стиля (обсуждаются ниже) WS_POPUP и
WS_CLIPCHILDREN. Нет никакого недокументированного бита стиля WS_DESKTOP.
Вместо этого логический номер desktop-окна сохраняется в глобальной
переменной модуля USER с именем HWndDesktop. Когда системе управления
окнами нужно знать, имеет ли она дело с desktop-окном, она просто
сравнивает HWND, о котором идет речь, с HWndDesktop. Вы можете получить
значение переменной HWndDesktop, используя документированную API-функцию
GetDesktopWindow().
ВЛАДЕНИЕ ОКНАМИ В Windows
Наряду с отношением предок/потомок. Windows также поддерживает совершенно
другое понятие владения. Каждое окно имеет поле в своей структуре данных,
которое содержит логический номер окна, которое владеет этим окном. В
отличии от отношения предок/потомок, отношение владения окна является
однонаправленным. Окну известен логический номер его окна-владельца, но оно
не знает логических номеров окон, которыми оно владеет.
Владелец окна - это окно, которое получает уведомления для окна, которым
оно владеет. Например, когда вы создаете окно меню WS_POPUP с помощью
функции TrackPopupMenu(), вы задаете владельца окна. Владелец окна получает
сообщение WM_COMMAND, порождаемое при выборе пункта меню. Важно отметить,
что в общем случае родительское окно и владелец окна совершенно различны.
Отношение предок/потомок устанавливает, где в иерархии окон находится окно,
тогда как владелец окна определяет, какие окна получают уведомления,
предназначенные для окон, которыми они владеют.
Особенность вышеприведенного правила относится и к окнам WS_CHILD. Для окон
WS_CHILD владелец HWND в структуре WND дочернего окна равен нулю, и вместо
него уведомительные сообщения посылаются родительскому окну. Например,
кнопка в окне диалога является потомком главного диалогового окна. Когда вы
нажимаете кнопку, окно кнопки уведомляет об этом событии своего предка,
т.е. главное диалоговое окно. Вы можете считать, что для ws_child-okhb
логический номер hWndOwner — то же самое, что и hWndParenfc, хотя на самом
деле они различны. В Presentati
on Manager нет необходимости в битах WS_CHILD или РWS_POPUP. Заполняется
как поле hWndPa-rent, так и поле hWndOwner. Это полностью определяет, кто
получает уведомительные сообщения потомка, а также положение окна в
иерархии. В Presentation Manager поля hWndParent и hWndOw-ner обычно
содержат одно и то же значение HWND.
Кроме посылки уведомлений своему владельцу, окно, которым владеют, также
всегда расположено впереди окна-владельца. Если окно превращено в
пиктограмму, то же происходит и с окнами, которыми оно владеет. Если окно-
владелец уничтожается, тто окна, которыми оно владеет, также уничтожаются.
Так как окно не следит за окнами, которыми оно владеет, нужно просматривать
списки указателей предок/сосед и сравнивать владельца каждого окна с HWND
окна, которое уничтожается.
Во всем этом немного странно то, что Windows не делает отношение владения
очень явным. Хотя в документации SDK кратко рассматривается отношение
владения, вам довольно трудно увидеть, в каких местах отношение владения
отличается от отношения предок/потомок. В Presentation Manager OS/2 при
создании окна вы задаете и родительское окно, и окно-владелец. В Windows вы
задаете только предка.
Если функции CreateWindow() передается только HWND родителя, как тогда вам
описать окно владельца в Windows? Одним из параметров функции
CreateWindow() является битовая маска стиля. Если стиль окна WS_CHILD,
параметр hWndParent интерпретируется как родительское окно. Однако, если вы
задаете WS_OVERLAPPED или WS_POPUP, параметр hWndParent в действительность
используется как владелец HWND, что позднее проясняется в некотором
псевдокоде. Родительским окном для окон WS_OVERLAPPED или WS_POPUP всегда
является HWND desktop-окна (HWndDes
ktop).
3. «Программа демонстрирующая иерархию окон Windows»
p386; эта директива разрешает транслятору обрабатывать команды процессора i
386
jumps;транслятор автоматически преобразует команду условной передачи
управления
;в комбинацию условной и безусловной команды, если условная в силу
ограниченности ;области своего действия не обеспечивает передачу управления
по нужному адресу
model flat,STDCALL;выбирает модель памяти для 32-разрядного
программирования и ;правила передачи параметров функции STDCALL, далее
действующие по умолчанию
UNICODE = 0
include win32.inc;файл, содержащий описание структур данных и констант
; some 32-bit constants and structures
L equ ; последовательности символов LARGE, являющейся именем
операции, объявляющей следующий за ней операнд 32-разрядным, присваивается
имя L
Define the external functions we will be linking to
;
extrn BeginPaint:PROC;описание импортируемых из Windows функций
extrn CreateWindowExA:PROC
extrn DefWindowProcA:PROC
extrn DispatchMessageA:PROC
extrn EndPaint:PROC
extrn ExitProcess:PROC
extrn GetMessageA:PROC
extrn GetModuleHandleA:PROC
extrn GetStockObject:PROC
extrn InvalidateRect:PROC
extrn LoadCursorA:PROC
extrn LoadIconA:PROC
extrn MessageBeep:PROC
extrn MessageBoxA:PROC
extrn PostQuitMessage:PROC
extrn RegisterClassA:PROC
extrn ShowWindow:PROC
extrn SetWindowPos:PROC
extrn TextOutA:PROC
extrn TranslateMessage:PROC
extrn UpdateWindow:PROC
extrn FindFirstFileA:PROC
.data;предопределенное имя, означающее начало сегмента данных
newhwnd dd 0
lppaint PAINTSTRUCT
msg MSGSTRUCT
wc WNDCLASS
hInst dd 0
szTitleName db 'Это окно УГТУ',0
szTitleName1 db 'Это окно группы СП-923',0 ;'Каркасное приложение Win32
на ассемблере'.0
szClassName db 'ASMCLASS32',0 ;'Приложение Win32’
Buffer db 'Привет из Нягани!',0
new1hwnd dd 0
MSG_L EQU 14
.code
start:
push L 0
call GetModuleHandleA ; get hmod (in eax)
mov [hInst], eax ; hInstance is same as HMODULE
; in the Win32 world
reg_class:
;
; initialize the WndClass structure ;Иинициализация сруктуры WndClass
;
mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS;тип
;класса
mov [wc.clsLpfnWndProc], offset WndProc; адрес оконной
процедуры
mov [wc.clsCbClsExtra], 0
mov [wc.clsCbWndExtra], 0
mov eax, [hInst]
mov [wc.clsHInstance], eax ;дикриптор модуля
push L IDI_APPLICATION;заданная по умолчанию пиктограмма
push L 0
call LoadIconA
mov [wc.clsHIcon], eax
push L IDC_ARROW
push L 0
call LoadCursorA
mov [wc.clsHCursor], eax
mov [wc.clsHbrBackground], COLOR_WINDOW + 1
mov dword ptr [wc.clsLpszMenuName], 0
mov dword ptr [wc.clsLpszClassName], offset szClassName
push offset wc
call RegisterClassA
push L 0 ; lpParam
push [hInst] ; hInstance
push L 0 ; menu
| | скачать работу |
Программа демонстрирующая иерархию окон Windows |