Міністерство освіти РФ p>
ІНСТИТУТ ПЕРЕПІДГОТОВКИ КАДРІВ p>
Уральського державного технічного університету b> p>
Кафедра мікропроцесорної техніки p>
Курсова робота p>
Програма демонструє ієрархію вікон b> Windows b> p>
керівник: Кулюкін В.П. b> p>
слухач гр.СП-923: b> p>
2001р. b> p>
Зміст p>
Введення p>
1. Віконні програми Windows. P>
2. Каркасне Windows-додаток на асемблері p>
3. Ієрархія вікон p>
4. «Програма демонструє ієрархію вікон Windows» p>
5.Бібліографіческій список p>
Введення b> p>
У переважній більшості книг про програмування для Windows виклад, як правило, ведеться
на базі мови C/C + +, рідше - на базі Pascal. А що ж асемблер - осторонь? Звичайно, ні! Ми не раз звертали вашу увагу на правильне
розуміння місця асемблера в архітектурі комп'ютера. Будь-яка програма на мові самого високого рівня у своєму внутрішньому вигляді являє собою
послідовність машинних кодів. А раз так, то завжди залишається теоретична можливість написати ту ж програму, але вже на мові асемблера: Нерозуміння
або недооцінка такої можливості призводить до того, що досить часто доводиться чути фразу, подібну до наступного: «Ах, знову цей асемблер, але
адже це щось несерйозне! »Також важко погодитися з тезою, що частіше за все слід слідом за цією фразою. Суть його зводиться до утвердження того, що
потужність сучасних комп'ютерів дозволяє не розглядати проблему ефективності функціонування програми як першочергове. Набагато легше вирішити її
за рахунок збільшення обсягу пам'яті, швидкодії центрального процесора і якості комп'ютерної периферії. Чим обгрунтувати необхідність розробки Windows-додатків на мові асемблера? Наведемо наступні
аргументи: p>
мовою асемблера дозволяє програмісту повністю контролювати створюваний ним програмний код і оптимізувати його на свій розсуд; p>
компілятори мов високого рівня поміщають в завантажувальний модуль програми надлишкову інформацію. Еквівалентні
виконувані модулі, початковий текст яких написаний на мові асемблера, мають у декілька разів менший розмір; p>
при програмуванні на асемблері зберігається повний доступ до апаратних ресурсів комп'ютера; p>
додаток, написаний на мові асемблера, як правило, швидше завантажується в оперативну пам'ять комп'ютера; p>
додаток, написаний на мові асемблера, володіє, як правило, більш високою швидкістю роботи і
реактивністю відповіді на дії користувача. Зрозуміло, ці аргументи не слід сприймати, як деяку рекламну кампанію на підтримку мови
асемблера. Але не можна забувати і про те, що існує нескінченна безліч прикладних задач, що чекають своєї черги на комп'ютерну реалізацію. Далеко не
всі з цих завдань вимагають застосування великовагових засобів розробки, результатом роботи яких є настільки ж великовагові виконувані файли.
Багато прикладні задачі можуть бути витончено виконані на мові асемблера, не втрачаючи привабливості. P>
1. Віконні програми b> Windows. B> p>
Windows підтримує два типи програм: p>
віконне додаток - будується на базі спеціального набору функцій (API), що становлять графічний інтерфейс користувача (GUI, Graphic User Interface). Віконне додаток являє собою програму, яка
весь висновок на екран виробляє в графічному вигляді. Першим результатом роботи віконного програми є відображення на екрані спеціального об'єкта --
вікна. Після того як вікно відображено на екрані, вся робота програми спрямована на те, щоб підтримувати її в актуальному стані; p>
Основний тип програм в Windows - віконні, тому з них ми і почнемо знайомство з
процесом розробки програм для цієї операційної системи. p>
Будь-яке віконне Windows-додаток має типову структуру, основу якої складає так зване каркасне додаток. Ця програма містить
мінімально необхідний програмний код для забезпечення повноцінного функціонування Windows-програми. Не випадково у всіх джерелах як
перший Windows-програми рекомендується вивчати і досліджувати роботу певного каркасного програми, тому що саме воно відображає основні особливості
взаємодії програми з операційною системою Windows. Більш того, написав і налагодити один раз каркасне
додаток, ви будете використовувати його в необхідну термінологію і зможемо більше уваги приділити логіці роботи Windows-програми,
а не деталей його реалізації. p>
Мінімальна додаток Windows складається з трьох частин: p>
головної функції; p>
циклу обробки повідомлень; p>
віконної функції. p>
Виконання будь-якого віконного Windows-програми починається з головної функції. Вона
містить код, який здійснює настройку (ініціалізацію) додатки в середовищі операційної системи Windows. Видимим для користувача
результатом роботи головної функції є поява на екрані графічного об'єкта у вигляді вікна. Останнім дією коду головної функції є створення
циклу обробки повідомлень. Після його створення додаток стає пасивним і починає взаємодіяти із зовнішнім світом за допомогою спеціальних
чином оформлених даних - повідомлень. Обробка що надходять з додатком повідомлень здійснюється спеціальною функцією, званої віконної. Віконна
функція унікальна тим, що може бути викликана тільки з операційної системи, а не з програми, яка її містить. Таким чином, Windows-додаток, як мінімум, має складатися з трьох перерахованих
елементів. p>
Каркасне Windows-додаток на асемблері містить один сегмент даних. data і один сегмент коду. code.
Сегмент стека у вихідних текстах Windows-додатків безпосередньо описувати не потрібно. Windows виділяє для
стьобаючи обсяг пам'яті, розмір якого задано програмістом у файлі з розширенням. def. Текст лістингу 2 достатньо великий. Тому для
обговорення розіб'ємо erо коментарями на характерні фрагменти, кожен з яких потім пояснимо необхідним ступенем деталізації. p>
2. Каркасне b> Windows-додаток на асемблері b> p>
<1>; Приклад каркасного програми для Win32 p>
<2> .386 p>
<3> locals; дозволяє застосування локальних міток у програмі p>
<4>. model flat, STDCALL; модель пам'яті flat Я p>
<5>; STDCALL - передача параметрів в стилі С (справа наліво), p>
<6>; викликається процедура чистить за собою стек Ш p>
<7> include windowA.inc; що включається файл з описами базових структур p>
; і констант Win32 т p>
<8>; Оголошення зовнішніми що використовуються в даній програмі функцій Win32 (ASCII): p>
<9> extrn GetModuleHandleA: PROC p>
<10> extrn GetVersionExA: PROC В p>
<11> extrn GetCommandLineA: PROC p>
<12> extrn GetEnvironmentStringsA: PROC p>
<13> extrn GetEnvironmentStringsA: PROC p>
<14> extrn GetStartupInfoA: PROC p>
<15> extrn LoadIconA: PROC p>
<16> extrn LoadCursorA: PROC p>
<17> extrn GetStockObject: PROC p>
<18> extrn RegisterClassExA: PROC p>
<19> extrn CreateWindowExA: PROC p>
<20> extrn ShowWindow: PROC p>
<21> extrn UpdateWindow: PROC p>
<22> extrn GetMessageA: PROC p>
<23> extrn TranslateMessage: PROC p>
<24> extrn DispatchMessageA: PROC p>
<25> extrn ExitProcess: PROC p>
<26> extrn PostQuitMessage: PROC p>
<27> extrn DefWindowProcA: PROC p>
<28> extrn PlaySoundA: PROC p>
<29> extrn ReleaseDC: PROC p>
<30> extrn TextOutA: PROC p>
<31> extrn GetDC: PROC p>
<32> extrn BeginPaint: PROC p>
<33> extrn EndPaint: PROC p>
<34>; оголошення віконної функції об'єктом, видимим за межами даного коду p>
<35> public WindowProc p>
<36>. data p>
<37> hwnd dd 0 p>
<38> hInst dd 0 p>
<39> hdc dd 0 p>
<40>; lpVersionInformation OSVERSIONINFO > p>
<41> wcl WNDCLASSEX > p>
<42> message MSG > p>
<43> ps PAINTSTRUCT > p>
<44> szClassName db 'Додаток Win32', 0 p>
<45> szTitleName db 'Каркасне додаток Win32 на асемблері' .0 p>
<46> MesWindow db 'Це процес розробки програми p>
на асемблері? ' p>
<47> MesWindowLen = $-MesWindow p>
<48> playFileCreate db 'create.wav', 0 p>
<49> playFilePaint db 'paint.wav', 0 p>
<50> playFileDestroy db 'destroy.wav', 0 p>
<51>. code p>
<52> start proc near p>
<53>; точка входу в програму: p>
<54>; початок стартового коду p>
<55>; виклики розташованих нижче функцій можна при необхідності розкоментувати, p>
<56>: але вони не є обов'язковими в даній програмі p>
<57>; виклик BOOL GetVersionEx (LPOSVERSIONINFO lpVersionInformation) p>
<58>; push offset lpVersionInformation p>
<59>; call GetVersionExA p>
<60>; далі можна вставити код для аналізу інформації про версію Windows p>
<61>; виклик LPTSTR GetCommandLine (VOID) - отримати покажчик на командний рядок p>
<62>; call GetCommandLineA: врегістре ЕАХ адреса p>
<63>; виклик LPVOID GetEnvironmentStrings (VOID) - отримати покажчик p>
; на блок із змінними оточення p>
<64>; call GetEnvironmentStringsA; врегістре ЕАХ адреса p>
<65>; виклик VOIDGetStartupInfo (LPSTARTUPINFO lpStartupInfo); покажчик p>
; на структуру STARTUPINFO p>
<66>; push offset lpStartupInfo p>
<67>; call GetStartupInfoA p>
<68>; виклик HMODULE GetModuleHandleA (LPCTSTR lpModuleName) p>
<69> push NULL; 0 -> GetModuleHandle p>
<70> call GetModuleHandleA; отримати значення базової адреси, p>
<71> mov hInst, eax; no якому завантажений модуль. p>
<72>; далі hInst буде використовуватися в якості дескриптора даного застосування p>
<73>; кінець стартового коду p>
<74> WinMain: p>
<75>; визначити клас вікна ATOM RegisterClassEx (CONST WNDCLASSEX * lpWndClassEx), p>
<76>; де * lpWndClassEx - адреса структури WndClassEx p>
<77>; для початку ініціалізіруем поля структури WndClassEx p>
<78> mov wcl.cbSize, typeWNDCLASSEX -. розмір структури p>
: у wcl.cbCIZE p>
<79> mov wcl.style, CS_HREDRAW + CS_VREDRAW p>
<80> mov wcl.pfnWndProg, offsetWindowProg; адресу віконної процедури p>
<81> mov wcl.cbCisExtra, 0 p>
<82> mov wcl.cbWndExtra, 0 p>
<83> mov eax, hInst p>
<84> mov; дискриптор додатки в поле hInstance структури wcl p>
<85> mov wcl.hInstance, eax p>
<86>; готуємо виклик HICON LoadIcon (HINSTANCE hInstance, LPCTSTR lpIconName) p>
<87> push IDI_APPLICATION,-стандартний значок p>
<88> push 0; NULL p>
<89> сап LoadIconA p>
<90> mov wcl.hIcon, eax,-дескриптор значка в полі hIcon I p>
; структури wcl p>
<91>; готуємо виклик HCURSOR LoadCursorA (HINSTANCE hInstance, LPCTSTR M; lpCursorName) p>
<92> push IDC_ARROW,-стандартний курсор - стрілка p>
<93> push 0 p>
<94> саll LoadCursorA p>
<95> mov wcl.hCursor, eax; дескриптор курсору в полі hCursor p>
; структури wc1 p>
<96>; визначимо колір фону вікна - білий p>
<97>; готуємо виклик HGDIOBJ GetStockObject (int fnObject) p>
<98> push WHITE_BRUSH p>
<99> сап GetStockObject p>
<100> mov wcl.hbrBackground, eax p>
<101> mov dword ptrwcl.lpszMenuName, 0; без головного меню p>
<102> mov dwordptrwcl.lpszClassName, offsetszC1assName; ім'я p>
; класу вікна p>
<103> mov wcl.hIconSm, 0 p>
<104>; реєструємо клас вікна - готуємо виклик RegisterClassExA (& wndclass) p>
<105> push offset wcl p>
<106> сап RegisterClassExA p>
<107> test ax, ах; перевірити на успіх реєстрації класу вікна p>
<108> jz end_cyc1_msg; невдача p>
<109>; створюємо вікно: p>
<110>; готуємо визовHWND CreateWindowExA (DWORDdwExStyle, p>
LPCTSTR1pClassName, p>
<111>; LPCTSTR 1pW1ndowName, DWORD dwStyle, int x, int у, int nWidth, p>
|; int nHeight, p>
<112>; HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID p>
; lpParam) p>
<113> push 0; lpParam p>
<114> push hInst; hInstance p>
<115> push NULL; menu p>
<116> push NULL; parent hwnd p>
<117> push CW_USEDEFAULT; висота вікна p>
<118> push CW_USEDEFAULT; ширина вікна p>
<119> push CW_USEDEFAULT; координата біля лівого верхнього кута p>
; вікна p>
<120> push CW_USEDEFAULT; координата х лівого верхнього кута p>
<121> push WS_OVERLAPPEDWINDOW; стиль вікна p>
<122> push offset szTitleName; рядок заголовка вікна p>
<123> push offset szClassName; ім'я класу вікна p>
<124> push NULL p>
<125> саll CreateWindowExA p>
<126> mov hwnd, eax;-дескриптор вікна p>
<127>; показати вікно: p>
<128>; готуємо виклик BOOL ShowWindow (HWND hWnd, int nCmdShow) p>
<129> push SW_SHOWNORMAL p>
<130> push hwnd p>
<131> call ShowWindow p>
<132>; перемальовує вміст вікна p>
<133>; готуємо виклик BOOL UpdateWindow (HWND hWnd) p>
<134> push hwnd p>
<135> call UpdateWindow p>
<136>; запускаємо цикл повідомлень: p>
<137>; готуємо виклик BOOL GetMessageA (LPMSG lpMsg, HWND hWnd, p>
<138>; UINTwMsgFilterMin, UINTwMsgFilterMax) p>
<139> cycl_msg: p>
<140> push 0 p>
<141> push 0 p>
<142> push NULL p>
<143> push offset message p>
<144> cal 1 GetMessageA p>
<145> cmp ах, 0 p>
<146> je end_cycl_msg p>
<147>; трансляція введення з клавіатури p>
<148>; готуємо виклик BOOL Trans1ateMessage (CONST MSG * lpMsg) p>
<149> push offset message p>
<150> call TranslateMessage p>
<151>; відправимо повідомлення віконної процедури p>
<152>; готуємо виклик LONG D1spatchMessage (CONST MSG * lpmsg) p>
<153> push offset message p>
<154> call DispatchMessageA p>
<155> jmp cycl_msg p>
<156> end_cycl_msg: p>
<157> p>
<158>; вихід з програми p>
<159>; готуємо виклик VOID ExitProcess (UINT uExitCode) p>
<160> push NULL p>
<161> call ExitProcess p>
<162> start endp p>
<163>; - - - - - - - - - - - - - WindowProc - - - - - - - - - - - - --
- - - - - - - - - - - - - - - - - - - - - - - - P>
<164> WindowProc proc p>
<165> argP0nwnd: DWORD, PPmes: DWORD, @ @ wparam: DWORD, @ @ lparam: DWORD p>
<166> uses ebx, edi, es1; ці регістри обов'язково повинні зберігатися p>
<167> local @ @ hdc: DWORD p>
<168> cmp @ @ mes, WM_DESTROY p>
<169> je wmdestroy p>
<170> cmp @ @ mes, WM_CREATE p>
<171> je wmcreate p>
<172> cmp @ @ mes, WM_PAINT p>
<173> je wmpaint p>
<174> jmp default p>
<175> wmcreate: p>
<176>; позначимо створення вікна звуковим ефектом p>
<177>; готуємо виклик функції BOOL PlaySound (LPCSTR pszSound, HMODULE hmod, DWORD p>
; fdwSound) p>
<178> push SND_SYNC + SND_FILENAME p>
<179> push NULL p>
<180> push offset playFileCreate p>
<181> call PlaySoundA p>
<182> mov eax, О; повертається значення - 0 p>
<183> jmp exit_wndproc p>
<184> wmpaint: p>
<185> push SND_SYNC + SND_FILENAME p>
<186> push NULL p>
<187> push offset playFIilePaint p>
<188> call P1aySoundA p>
<189>; отримаємо контекст пристрою HDC BeginPaint (HWND nwnd, LPPAINTSTRUCT; LPpAINT) p>
<190> push offset ps p>
<191> push @ @ hwnd p>
<192> call BeginPaint p>
<193> mov @ @ hdc, eax p>
<194>; виведемо рядок тексту у вікно BOOL TextOut (HDC hdc. int nXStart, int p>
: nYStart. p>
<195>; LPCTSTR lpString, int cbString) p>
<196> push MesWindowLen p>
<197> push offset MesWindow p>
<198> push 100 p>
<199> push 10 p>
<200> push @ @ hdc p>
<201> call TextOutA p>
<202>: ocвoбoдітькoнтeкcтBOOLEndPaint (HWNDhWnd, CONSTPAINTSTRUCT * lpPai <203> push offset ps p>
<204> push @ @ hdc p>
<205> call EndPaint p>
<206> mov ЕАХ, 0; повертається значення-0 p>
<207> jmp exit_wndproc p>
<208> wmdestroy: p>
<209> push SND_SYNC + SND_FILENAME p>
<210> push NULL p>
<211> push offset playFileDestroy p>
<212> call PlaySoundA p>
<213>; відправити повідомлення WМ_QUIТ p>
<214>; готуємо виклик VOID PostQuitMessage (int nExitCode) p>
<215> push 0 p>
<216> call PostQuitMessage p>
<217> mov eax, О; повертається значення - 0 p>
<218> jmp exit_wndproc p>
<219> default: p>
<220>; обробка за замовчуванням p>
<221>; готуємо виклик LRESULTDefWindowProc (HWND hWnd, UINTMsg, p>
<222>; WPARAMwParam, LPARAMlParam) p>
<223> push @ @ lparam p>
<224> push @ @ wparam p>
<225> push @ @ mes p>
<226> push @ @ nwnd p>
<227> call DefWindowProcA p>
<228> jmp exit_wndproc p>
<229>; ... ... ... p>
<230> exit_wndproc: p>
<231> ret p>
<232> WindowProc endp p>
<233> end start p>
3.Іерархія b> вікон b> p>
Вивчивши з дисципліни «Системне програмне забезпечення» написання вікон Windows на мові Assembler та
розглядаючи графічну віконну систему не можна обійтися без докладного розгляду того, які вікна можна відображати на екрані. p>
Тип вікна задається 32-бітовим без знаковим цілим числом, що вказується третім параметром виклику функції Create Window. p>
Існує всього лише три основні типи вікон Window. p>
1 тип. Перекриваються вікна. Прапор WS_OVERLAPPED. P>
2 тип. Допоміжні вікна. Прапор WS_POPUP. P>
3 тип. Дочірні вікна. . Прапор WS_CHILD. P>
Для написання курсового проекту, який має тему «Програма демонструє
ієрархію вікон Windows »були використані саме ці типи вікон. p>
Потрібно про них пам'ятати наступне що: p>
перекриваються вікно ніколи не має батьків p>
Дочірнє вікно завжди має батька. p>
Допоміжне вікно може мати і не мати батька, якщо воно має батька, то все одно це не дочірнє, а
допоміжне вікно. p>
І b> З усіх концепцій системи управління вікнами найбільш фундаментальною є ставлення предок/нащадок/сусід. Як ми
бачили при описі структури даних WND, кожне вікно содержит логічний номер вікна свого предка, логічний номер свого першого дочірнього вікна і логічний
номер наступного сусіднього вікна. Сусідніми є вікна, які мають однакове батьківське вікно. Насправді значення HWND є просто ближніми
покажчиками в локальній "купі" модуля USER, тому ви можете розглядати їх як покажчики зв'язкового списку, які дозволяють обходити шляху
в ієрархії вікон. Ієрархія вікон, створювана модулем USER, показана на рис.1. P>
Ієрархія вікон обходиться в усіх трьох напрямках - від пращура до нащадка, від нащадка до предка і від
сусіда до сусіда. Приклади обходу ієрархії включають наступне: p>
• При знищенні вікна модуль USER повинен знищити всіх його нащадків, а також їхніх нащадків. USER обходить
всю ієрархію, використовуючи поля hWndChild і hWndNext-Нагадаємо, логічні номера вікон є просто ближніми покажчиками в локальній "купі" модуля
USER. P>
• Коли відбувається передача фокусу вводу при натисканні клавіші Tab між елементами управління у вікні
діалогу (що є нащадками вікна діалогу), покажчики на сусіднє вікна (або поле hWndNext) з'єднують один з одним елементи управління. Крім того,
упорядкування вікон у списку hWndChild і hWndNext відображає Z-порядок вікон на екрані. Z-порядок являє собою відносну позицію вікон у третьому
вимірі (у напрямку від екрану до вас). Якщо ви клацанням кнопки миші вибираєте різні основні вікна; p>
щоб помістити їх у вершину Z-порядку, їх відносні позиції в списку hWndNext зсуваються. p>
p>
p>
Рис .. 1 Ієрархія вікон, створена модулем USER. b> p>
• Коли з допомогою клацання кнопки миші ви вибираєте діалогове керуюче вікно, це призводить до того, що
менеджер діалогів просмарівает ланцюжок покажчиків предка, щоб подивитися, чи необхідно зробити активним вікно додатка верхнього рівня (основне). p>
У корені дерева вікон знаходиться desktop-вікно. Це вікно покриває весь екран і завжди знаходиться на
вершині Z-порядку. Це означає, що воно завжди знаходиться позаду всіх інших вікон. Desktop-вікно є першим створеним вікном, і це єдине вікно в
системі, яка не має вікна одного з батьків або власника. (Вікна-власники описані далі.) Фарбування вікна фону відповідає за "шпалери" Windows. P>
Desktop-вікно нічим особливим не виділяється в сенсі встановлення спеціальних бітів або т.п. Воно
створюється з битами стилю (обговорюються нижче) WS_POPUP і WS_CLIPCHILDREN. Немає ніякого недокументовані біта стилю WS_DESKTOP. Замість цього логічний
номер desktop-вікна зберігається в глобальній змінній модуля USER з ім'ям HWndDesktop. Коли системі управління вікнами потрібно знати, чи має вона справу з
desktop-вікном, вона просто порівнює HWND, про який йде мова, з HWndDesktop. Ви можете отримати значення змінної HWndDesktop, використовуючи документовану
API-функцію GetDesktopWindow (). p>
ВОЛОДІННЯ вікнами в Windows p>
Поряд зі ставленням предок/нащадок. Windows також підтримує зовсім інше поняття володіння.
Кожне вікно має поле в своїй структурі даних, що містить логічний номер вікна, яке володіє цим вікном. На відміну від ставлення предок/нащадок,
відношення володіння вікна є односпрямованим. Вікна відомий логічний номер його вікна-власника, але воно не знає логічних номерів вікон, якими воно
володіє. p>
Власник вікна - це вікно, яке отримує повідомлення для вікна, яким воно володіє. Наприклад,
коли ви створюєте вікно меню WS_POPUP за допомогою функції TrackPopupMenu (), ви ставите власника вікна. Власник вікна отримує повідомлення WM_COMMAND,
що виникає при виборі пункту меню. Важливо відзначити, що в загальному випадку батьківське вікно і власник вікна зовсім різні. Відношення предок/нащадок
встановлює, де в ієрархії вікон знаходиться вікно, тоді як власник вікна визначає, які вікна отримують повідомлення, призначені для вікон, якими
вони володіють. p>
Особливість вищенаведеного правила відноситься і до вікон WS_CHILD. Для вікон WS_CHILD
власник HWND в структурі WND дочірнього вікна дорівнює нулю, і замість нього надішле повідомлення надсилаються батьківському вікну. Наприклад, кнопка у вікні
діалогу є нащадком головного діалогового вікна. Коли ви натискаєте кнопку, вікно кнопки повідомляє про цю подію свого предка, тобто головне діалогове
вікно. Ви можете вважати, що для ws_child-okhb логічний номер hWndOwner - те ж саме, що і hWndParenfc, хоча насправді вони різні. У Presentati p>
on Manager немає необхідності в бітах WS_CHILD або РWS_POPUP. Заповнюється як поле hWndPa-rent,
так і поле hWndOwner. Це повністю визначає, хто отримує надішле повідомлення нащадка, а також положення вікна в ієрархії. У Presentation Manager
поля hWndParent і hWndOw-ner зазвичай містять одне і те ж значення HWND. p>
Крім посилки повідомлень своєму власникові, вікно, яким володіють, також завжди розташоване
попереду вікна-власника. Якщо вікно перетворено в піктограму, те саме відбувається і з вікнами, якими воно володіє. Якщо вікно-власник знищується, ТТО вікна,
якими воно володіє, також знищуються. Так як вікно не стежить за вікнами, якими воно володіє, потрібно переглядати списки покажчиків предок/сусід і порівнювати
власника кожного вікна з HWND вікна, яке знищується. p>
У всьому цьому трохи дивно те, що Windows не робить відношення володіння дуже явним. Хоча в
документації SDK коротко розглядається відношення володіння, вам досить важко побачити, в яких місцях відношення володіння відрізняється від ставлення
предок/нащадок. У Presentation Manager OS/2 при створенні вікна ви задаєте і батьківське вікно, і вікно-власник. У Windows, ви ставите тільки предка. P>
Якщо функції CreateWindow () передається тільки HWND батька, як тоді вам описати вікно
власника в Windows? Одним з параметрів функції CreateWindow () є бітова маска стилю. Якщо стиль вікна WS_CHILD, параметр hWndParent інтерпретується
як батьківське вікно. Однак, якщо ви задаєте WS_OVERLAPPED або WS_POPUP, параметр hWndParent в дійсність використовується як власник HWND, що
пізніше з'ясовується в деякому псевдокоді. Батьківським вікном для вікон WS_OVERLAPPED або WS_POPUP завжди є HWND desktop-вікна (HWndDes p>
ktop). p>
3. b> «Програма демонструє ієрархію вікон b> Windows» b> p>
p386; ця директива дозволяє транслятору обробляти команди процесора i 386 p>
jumps; транслятор автоматично перетворить команду умовної передачі управління p>
; в комбінацію умовної і безумовної команди, якщо умовна в силу обмеженості; області своєї дії не забезпечує передачу
управління за потрібною адресою p>
model flat, STDCALL; вибирає модель пам'яті для 32-розрядного програмування і; правила передачі параметрів
функції STDCALL, далі діють за замовчуванням p>
UNICODE = 0 b> p>
include win32.inc; файл, що містить опис структур даних і констант p>
; some 32-bit constants and structures p>
L equ ; послідовності символів LARGE, що є ім'ям операції, що оголошує наступний за нею операнд 32-розрядних,
присвоюється ім'я L p>
Define the external functions we will be linking to p>
; p>
extrn BeginPaint: PROC ; b> опис імпортованих з Windows функцій p>
extrn CreateWindowExA: PROC p>
extrn DefWindowProcA: PROC p>
extrn DispatchMessageA: PROC p>
extrn EndPaint: PROC p>
extrn ExitProcess: PROC p>
extrn GetMessageA: PROC p>
extrn GetModuleHandleA: PROC p>
extrn GetStockObject: PROC p>
extrn InvalidateRect: PROC p>
extrn LoadCursorA: PROC p>
extrn LoadIconA: PROC p>
extrn MessageBeep: PROC p>
extrn MessageBoxA: PROC p>
extrn PostQuitMessage: PROC p>
extrn RegisterClassA: PROC p>
extrn ShowWindow: PROC p>
extrn SetWindowPos: PROC p>
extrn TextOutA: PROC p>
extrn TranslateMessage: PROC p>
extrn UpdateWindow: PROC p>
extrn FindFirstFileA: PROC p>
. data; зумовлене ім'я, що означає початок сегменту даних p>
newhwnd dd 0 p>
lppaint PAINTSTRUCT > p>
msg MSGSTRUCT > p>
wc WNDCLASS > p>
hInst dd 0 p>
szTitleName db 'Це вікно УГТУ', 0 p>
szTitleName1 db 'Це вікно групи СП-923', 0; 'Каркасне додаток Win32 на асемблері' .0 p>
szClassName db 'ASMCLASS32', 0; 'Додаток Win32' p>
Buffer db 'Привет из Нягані!', 0 p>
new1hwnd dd 0 p>
MSG_L EQU 14 p>
. code p>
start: p>
push L 0 p>
call GetModuleHandleA; get hmod (in eax) p>
mov [hInst], eax; hInstance is same as HMODULE p>
; in the Win32 world p>
reg_class: p>
; p>
; initialize the WndClass structure; Іініціалізація сруктурам WndClass p>
; p>
mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS; тип; класу p>
mov [wc.clsLpfnWndProc], offset WndProc; адресу віконної процедури p>
mov [wc.clsCbClsExtra], 0 p>
mov [wc.clsCbWndExtra], 0 p>
mov eax, [hInst] p>
mov [wc.clsHInstance], eax; дікріптор модуля p>
push L IDI_APPLICATION; задана за замовчуванням піктограма p>
push L 0 p>
call LoadIconA p>
mov [wc.clsHIcon], eax p>
push L IDC_ARROW p>
push L 0 p>
call LoadCursorA p>
mov [wc.clsHCursor], eax p>
mov [wc.clsHbrBackground], COLOR_WINDOW + 1 p>
mov dword ptr [wc.clsLpszMenuName], 0 p>
mov dword ptr [wc.clsLpszClassName], offset szClassName p>
push offset wc p>
call RegisterClassA p>
push L 0; lpParam p>
push [hInst]; hInstance p>
push L 0; menu p>
push L 0; parent hwnd p>
push L CW_USEDEFAULT; height p>
push L CW_USEDEFAULT; width p>
push L CW_USEDEFAULT; y p>
push L CW_USEDEFAULT; x p>
push L WS_OVERLAPPEDWINDOW; Style p>
push offset szTitleName; Title string p>
push offset szClassName; Class name; ім'я класу p>
push L 0; extra style p>
call CreateWindowExA p>
mov [newhwnd], eax p>
push L SW_SHOWNORMAL p>
push [newhwnd] p>
call ShowWindow p>
push [newhwnd] p>
call UpdateWindow p>
push L 0; lpParam p>
push [hInst]; hInstance p>
push L 0; menu p>
push L [newhwnd]; parent hwnd p>
push L CW_USEDEFAULT; height p>
push L CW_USEDEFAULT; width p>
push L CW_USEDEFAULT; y p>
push L CW_USEDEFAULT; x p>
push L WS_OVERLAPPEDWINDOW; Style p>
push offset szTitleName1; Title string p>
push offset szClassName; Class name p>
push L 0; extra style p>
call CreateWindowExA p>
mov [new1hwnd], eax p>
push L SW_SHOWNORMAL p>
push [new1hwnd] p>
call ShowWindow p>
push [new1hwnd] p>
call UpdateWindow p>
msg_loop: p>
push L 0 p>
push L 0 p>
push L 0 p>
push offset msg p>
call GetMessageA p>
cmp ax, 0 p>
je end_loop p>
push offset msg p>
call TranslateMessage p>
push offset msg p>
call DispatchMessageA p>
jmp msg_loop p>
end_loop: p>
push [msg.msWPARAM] p>
call ExitProcess p>
; we never get to here p>
; віконна процедура p>
;---------------------------------------------- ------------------------------- p>
WndProc proc uses ebx edi esi, hwnd: DWORD, wmsg: DWORD, p>
wparam: DWORD, lparam: DWORD p>
; p>
; WARNING: Win32 requires that EBX, EDI, and ESI be preserved! We comply p>
; with this by listing those regs after the 'uses' statement in the 'proc' p>
; line. This allows the Assembler to save them for us. p>
; p>
LOCAL hDC: DWORD p>
cmp [wmsg], WM_DESTROY p>
je wmdestroy p>
cmp [wmsg], WM_SIZE p>
je wmsize p>
cmp [wmsg], WM_CREATE p>
je wmcreate p>
cmp [wmsg], WM_PAINT p>
je wmpaint p>
jmp defwndproc p>
wmcreate: p>
mov eax, 0 p>
jmp finish p>
defwndproc: p>
push [lparam] p>
push [wparam] p>
push [wmsg] p>
push [hwnd] p>
call DefWindowProcA p>
jmp finish p>
wmdestroy: p>
push L 0 p>
call PostQuitMessage p>
mov eax, 0 p>
jmp finish p>
wmsize: p>
mov eax, 0 p>
jmp finish p>
wmpaint: p>
push offset lppaint p>
push [hwnd] p>
call BeginPaint p>
mov [hDC], eax p>
push L 17 p>
; push ecx p>
push offset Buffer p>
push L 5 p>
push L 5 p>
push [hDC] p>
call TextOutA p>
push offset lppaint p>
push [hwnd] p>
call EndPaint p>
mov eax, 0 p>
jmp finish p>
finish: p>
ret p>
WndProc endp p>
;---------------------------------------------- ------------------------------- p>
public WndProc p>
end start p>
Бібліографічний список b> p>
1. Використання Turbo Assembler при розробці програм/Укладач А.А. Чекатков. Київ: Диалектика, 1995. P>
2. Рихтер Д. Windows для професіоналів (програмування в Win32 API для Windows p>
NT 3.5 і Windows 95) пер. З англ. М.: Видавничий відділ «Російський Редакція» ТОО «Channel Trading Ltd», 1995. P>
3. Зубков С.В. Assembler. Для DOS, Windows і Unix. М.: ДМК. 1999. p>