Программа, демонстрирующая иерархию окон Windows

height="154" align="left" hspace="12" />

 

Рис..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>; последовательности символов 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

        push    L 0                      ; parent hwnd

        push    L CW_USEDEFAULT          ; height

        push    L CW_USEDEFAULT          ; width

        push    L CW_USEDEFAULT          ; y

        push    L CW_USEDEFAULT          ; x

        push    L WS_OVERLAPPEDWINDOW    ; Style

        push    offset szTitleName       ; Title string

        push    offset szClassName       ;>

        push    L 0                      ; extra style

        call    CreateWindowExA                        

        mov     [newhwnd], eax

        push    L SW_SHOWNORMAL

        push    [newhwnd]

        call    ShowWindow

        push    [newhwnd]

        call    UpdateWindow

        push    L 0                      ; lpParam

        push    [hInst]                  ; hInstance

        push    L 0                      ; menu

        push    L [newhwnd]                      ; parent hwnd

        push    L CW_USEDEFAULT          ; height

        push    L CW_USEDEFAULT          ; width

        push    L CW_USEDEFAULT          ; y

        push    L CW_USEDEFAULT          ; x

        push    L WS_OVERLAPPEDWINDOW    ; Style

        push    offset szTitleName1       ; Title string

        push    offset szClassName       ;>

        push    L 0                      ; extra style

        call    CreateWindowExA                        

        mov     [new1hwnd], eax

        push    L SW_SHOWNORMAL

        push    [new1hwnd]

        call    ShowWindow

        push    [new1hwnd]

        call    UpdateWindow

msg_loop:

        push    L 0

        push    L 0

        push    L 0

        push    offset msg

        call    GetMessageA

        cmp     ax, 0

        je      end_loop

        push    offset msg

        call    TranslateMessage

        push    offset msg

        call    DispatchMessageA

        jmp     msg_loop

end_loop:

        push    [msg.msWPARAM]

        call    ExitProcess

        ; we never get to here

;оконная процедура

;-----------------------------------------------------------------------------

WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD,

                                                wparam:DWORD, lparam:DWORD

;               

; WARNING: Win32 requires that EBX, EDI, and ESI be preserved!  We comply

; with this by listing those regs after the 'uses' statement in the 'proc'

; line.  This allows the Assembler to save them for us.

;

LOCAL   hDC:DWORD

        cmp     [wmsg], WM_DESTROY

        je      wmdestroy

        cmp     [wmsg], WM_SIZE

        je      wmsize

        cmp     [wmsg], WM_CREATE

        je      wmcreate

        cmp         [wmsg],WM_PAINT

         je                   wmpaint

        jmp     defwndproc

        wmcreate:

        mov     eax, 0

        jmp     finish

        defwndproc:

        push    [lparam]

        push    [wparam]

        push    [wmsg]

        push    [hwnd]

        call    DefWindowProcA

        jmp     finish

        wmdestroy:

        push    L 0

        call    PostQuitMessage

        mov     eax, 0

        jmp     finish

        wmsize:

        mov     eax, 0

        jmp     finish

         wmpaint:

        push    offset  lppaint

        push    [hwnd]

        call    BeginPaint

        mov     [hDC],eax

        push         L 17

        ;   push     ecx

            push     offset    Buffer

            push     L 5

            push     L 5

            push     [hDC]

            call       TextOutA

         push    offset lppaint

        push    [hwnd]

        call    EndPaint

            mov     eax,0

            jmp      finish

finish:

        ret

WndProc          endp

;-----------------------------------------------------------------------------

public WndProc

end start

Библиографический список

1. Использование Turbo Assembler при разработке программ / Составитель А.А. Чекатков. Киев: Диалектика, 1995.

2. Рихтер Д. Windows  для профессионалов ( программирование  в Win32 API для Windows

NT 3.5 и  Windows  95) пер. С англ. М.: Издательский отдел «Русский Редакция» ТОО  «Channel Trading Ltd», 1995.

3. Зубков С.В. Assembler. Для DOS, Windows и Unix. М. : ДМК. 1999.