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

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

Министерство образования РФ


ИНСТИТУТ ПЕРЕПОДГОТОВКИ КАДРОВ


Уральского государственного технического университета


Кафедра микропроцессорной техники


Курсовая работа


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


руководитель: Кулюкин В.П.


слушатель гр.СП-923:


2001г.


Содержание


Введение


1. Окон­ные приложения Windows.


2. Каркасное Windows-приложение на ассемблере


3. Иерархия окон


4. «Программа демонстрирующая иерархию окон Windows»


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


Введение


В подавляющем большинстве книг о программировании для Windows изложение, как правило, ведется на базе языка C/C++, реже — на базе Pascal. А что же ас­семблер — в стороне? Конечно, нет! Мы не раз обращали ваше внимание на пра­вильное понимание места ассемблера в архитектуре компьютера. Любая програм­ма на языке самого высокого уровня в своем внутреннем виде представляет собой последовательность машинных кодов. А раз так, то всегда остается теоретическая возможность написать ту же программу, но уже на языке ассемблера: Непонима­ние или недооценка такой возможности приводит к тому, что достаточно часто приходится слышать фразу, подобную следующей: «Ах, опять этот ассемблер, но ведь это что-то несерьезное!» Также трудно согласиться с тезисом, который чаще всего следует вслед за этой фразой. Суть его сводится к утверждению того, что мощность современных компьютеров позволяет не рассматривать проблему эф­фективности функционирования программы в качестве первоочередной. Гораздо легче решить ее за счет увеличения объема памяти, быстродействия центрально­го процессора и качества компьютерной периферии. Чем обосновать необходимость разработки Windows-приложений на языке ассем­блера? Приведем следующие аргументы:


языке ассемблера позволяет программисту полностью контролировать создава­емый им программный код и оптимизировать его по своему усмотрению;


компиляторы языков высокого уровня помещают в загрузочный модуль про­граммы избыточную информацию. Эквивалентные исполняемые модули, ис­ходный текст которых написан на языке ассемблера, имеют в несколько раз меньший размер;


при программировании на ассемблере сохраняется полный доступ к аппарат­ным ресурсам компьютера;


приложение, написанное на языке ассемблера, как правило, быстрее загружа­ется в оперативную память компьютера;


приложение, написанное на языке ассемблера, обладает, как правило, более высокой скоростью работы и реактивностью ответа на действия пользователя. Разумеется, эти аргументы не следует воспринимать, как некоторую рекламную кампанию в поддержку языка ассемблера. Но нельзя забывать и о том, что суще­ствует бесконечное множество прикладных задач, ждущих своей очереди на ком­пьютерную реализацию. Далеко не все из этих задач требуют применения тяже­ловесных средств разработки, результатом работы которых являются столь же тяжеловесные исполняемые файлы. Многие прикладные задачи могут быть изящ­но исполнены на языке ассемблера, не теряя привлекательности.


1. Окон­ные приложения
Windows.


Windows поддерживает два типа приложений:


оконное приложение
— строится на базе специального набора функций (API), составляющих графический интерфейс пользователя (GUI, GraphicUserInter­face). Оконное приложение представляет собой программу, которая весь вы­вод на экран производит в графическом виде. Первым результатом работы оконного приложения является отображение на экране специального объек­та — окна. После того как окно отображено на экране, вся работа приложения направлена на то, чтобы поддерживать его в актуальном состоянии;


Основной тип приложений в Windows — окон­ные, поэтому с них мы и начнем знакомство с процессом разработки программ для этой операционной системы.


Любое оконное Windows-приложение имеет типовую структуру, основу которой составляет так называемое каркасное приложение.
Это приложение содержит ми­нимально необходимый программный код для обеспечения функционирования полноценного Windows-приложения. Не случайно во всех источниках в качестве первого Windows-приложения рекомендуется изучать и исследовать работу не­которого каркасного приложения, так как именно оно отражает основные особен­ности взаимодействия программы с операционной системой Windows. Более того, написав и отладив один раз каркасное приложение, вы будете использовать его в необходимую терминологию и сможем больше внимания уделить логике работы Windows-приложения, а не деталям его реализации.


Минимальное приложение Windows состоит из трех частей:


главной функции;


цикла обработки сообщений;


оконной функции.


Выполнение любого оконного Windows-приложения начинается с главной функ­ции.
Она содержит код, осуществляющий настройку (инициализацию) приложе­ния в среде операционной системы Windows. Видимым для пользователя резуль­татом работы главной функции является появление на экране графического объекта в виде окна. Последним действием кода главной функции является со­здание цикла обработки сообщений.
После его создания приложение становится пассивным и начинает взаимодействовать с внешним миром посредством специ­альным образом оформленных данных — сообщений.
Обработка поступающих приложению сообщений осуществляется специальной функцией, называемой оконной.
Оконная функция уникальна тем, что может быть вызвана только из операционной системы, а не из приложения, которое ее содержит. Таким образом, Windows-приложение, как минимум, должно состоять из трех перечис­ленных элементов.


Каркасное Windows-приложение на ассемблере содержит один сегмент данных .data и один сегмент кода . code. Сегмент стека в исходных текстах Windows-приложений непосредственно описывать не нужно. Windows выделяет для стега объем памяти, размер которого задан программистом в файле с расширением . def. Текст листинга 2 достаточно большой. Поэтому для обсуждения разобьем erо комментариями на характерные фрагменты, каждый из которых затем поясним необходимой степенью детализации.


2. Каркасное
Windows-приложение на ассемблере


<1> ;Пример каркасного приложения для Win32


<2> .386


<3> locals ;разрешает применение локальных меток в программе


<4> .model flat, STDCALL ;модельпамяти flat Я


<5> ;STDCALL - передача параметров в стиле С (справа налево),


<6> ; вызываемая процедура чистит за собой стек Ш


<7>
includewindowA.inc ;включаемый файл с описаниями базовых структур


;и констант Win32 т


<8> ;Объявление внешними используемых в данной программе функций Win32 (ASCII):


<9> extrn GetModuleHandleA:PROC


<10> extrn GetVersionExA:PROC В


<11> extrn GetCommandLineA:PROC


<12> extrn GetEnvironmentStringsA:PROC


<13> extrn GetEnvironmentStringsA:PROC


<14> extrn GetStartupInfoA:PROC


<15> extrn LoadIconA:PROC


<16> extrn LoadCursorA:PROC


<17> extrn GetStockObject:PROC


<18> extrn RegisterClassExA:PROC


<19> extrn CreateWindowExA:PROC


<20> extrn ShowWindow:PROC


<21> extrn UpdateWindow:PROC


<22> extrn GetMessageA:PROC


<23> extrn TranslateMessage:PROC


<24> extrn DispatchMessageA:PROC


<25> extrn ExitProcess:PROC


<26> extrn PostQuitMessage:PROC


<27> extrn DefWindowProcA:PROC


<28> extrn PlaySoundA:PROC


<29> extrn ReleaseDC:PROC


<30> extrn TextOutA:PROC


<31> extrn GetDC:PROC


<32> extrn BeginPaint:PROC


<33> extrnEndPaint:PROC


<34> ;объявление оконной функции объектом, видимым за пределами данного кода


<35> public WindowProc


<36> .data


<37> hwnd dd 0


<38> hInst dd 0


<39> hdc dd 0


<40> ;lpVersionInformation OSVERSIONINFO <?>


<41> wcl WNDCLASSEX <?>


<42> message MSG <?>


<43> ps PAINTSTRUCT <?>


<44> szClassName db 'Приложение Win32 ',0


<45> szTitleNamedb 'Каркасное приложение Win32 на ассемблере'.0


<46> MesWindowdb 'Это процесс разработки приложения


наассемблере?'


<47> MesWindowLen= $-MesWindow


<48> playFileCreate db 'create.wav',0


<49> playFilePaint db 'paint.wav',0


<50> playFileDestroy db 'destroy.wav',0


<51> . code


<52> start proc near


<53> ;точка входа в программу:


<54> ;начало стартового кода


<55> ;вызовы расположенных ниже функций можно при необходимости раскомментировать,


<56> :но они не являются обязательными в данной программе


<57> ;вызов BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInformation)


<58> ; push offset lpVersionInformation


<59> ; call GetVersionExA


<60> ;далее можно вставить код для анализа информации о версии Windows


<61> ;вызов LPTSTRGetCommandLine(VOID) - получить указатель на командную строку


<62> ; call GetCommandLineA :врегистрееахадрес


<63> ;вызов LPVOID GetEnvironmentStrings (VOID) - получитьуказатель


;на блок с переменными окружения


<64> ; call GetEnvironmentStringsA ;врегистрееахадрес


<65> ;вызов VOIDGetStartupInfo(LPSTARTUPINFO lpStartupInfo) ;указатель


;наструктуру STARTUPINFO


<66> ; push offset lpStartupInfo


<67> ; call GetStartupInfoA


<68> ;вызов HMODULE GetModuleHandleA (LPCTSTR lpModuleName)


<69> push NULL ;0->GetModuleHandle


<70> call GetModuleHandleA ;получитьзначениебазовогоадреса,


<71> movhInst, eax ;no которому загружен модуль.


<72> ;далее hInst будет использоваться в качестве дескриптора данного приложения


<73> ;конец стартового кода


<74> WinMain:


<75>;определитьклассокна ATOM RegisterClassEx(CONST WNDCLASSEX *lpWndClassEx),


<76> ; где *lpWndClassEx - адресструктуры WndClassEx


<77> ;для начала инициализируем поля структуры WndClassEx


<78> movwcl.cbSize,typeWNDCLASSEX -.размер структуры


:в wcl.cbCIZE


<79> mov wcl.style,CS_HREDRAW+CS_VREDRAW


<80> mov wcl.pfnWndProg,offsetWindowProg ;адресоконнойпроцедуры


<81> mov wcl.cbCisExtra,0


<82> mov wcl.cbWndExtra,0


<83> moveax,hInst


<84> mov ;дискриптор приложения в поле hInstance структуры wcl


<85> mov wcl.hInstance, eax


<86> ;готовимвызов HICON LoadIcon (HINSTANCE hInstance, LPCTSTR lpIconName)


<87> push IDI_APPLICATION ,-стандартныйзначок


<88> push 0 ;NULL


<89> саП LoadIconA


<90> mov wcl.hIcon, eax ,-дескрипторзначкавполе hIcon I


;структуры wcl


<91> ;готовимвызов HCURSOR LoadCursorA (HINSTANCE hInstance, LPCTSTR M
;lpCursorName)


<92> pushIDC_ARROW ,-стандартный курсор - стрелка


<93> push 0


<94> саllLoadCursorA


<95> movwcl.hCursor,eax ;дескриптор курсора в поле hCursor


;структуры wc1


<96> ;определим цвет фона окна - белый


<97> ;готовимвызов HGDIOBJ GetStockObject(int fnObject)


<98> push WHITE_BRUSH


<99> саП GetStockObject


<100> mov wcl.hbrBackground, eax


<101> mov dword ptrwcl.lpszMenuName, 0 ;безглавногоменю


<102> mov dwordptrwcl.lpszClassName,offsetszC1assName; имя


;классаокна


<103> mov wcl.hIconSm, 0


<104> ;регистрируемклассокна - готовимвызов RegisterClassExA (&wndclass)


<105> push offset wcl


<106> саП RegisterClassExA


<107> testax, ах;проверить на успех регистрации класса окна


<108> jz end_cyc1_msg ;неудача


<109> ;создаемокно:


<110> ;готовим вызовHWND CreateWindowExA(DWORDdwExStyle,


LPCTSTR1pClassName,


<111> ; LPCTSTR 1pW1ndowName, DWORD dwStyle, int x, int у, int nWidth,


|;int nHeight,


<112> ; HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID


;lpParam)


<113> push 0 ;lpParam


<114> push hInst ;hInstance


<115> push NULL ;menu


<116> push NULL ;parent hwnd


<117> push CW_USEDEFAULT ;высотаокна


<118> push CW_USEDEFAULT ;ширинаокна


<119> pushCW_USEDEFAULT ;координата у левого верхнего угла


;окна


<120> pushCW_USEDEFAULT ;координата х левого верхнего угла


<121> push WS_OVERLAPPEDWINDOW ;стильокна


<122> push offset szTitleName ;строказаголовкаокна


<123> push offset szClassName ;имяклассаокна


<124> push NULL


<125> саll CreateWindowExA


<126> mov hwnd,eax ;-дескрипторокна


<127> ;показатьокно:


<128> ;готовимвызов BOOL ShowWindow( HWND hWnd, int nCmdShow )


<129> push SW_SHOWNORMAL


<130> push hwnd


<131> callShowWindow


<132> ;перерисовываем содержимое окна


<133> ;готовим вызов BOOLUpdateWindow( HWNDhWnd )


<134> push hwnd


<135> call UpdateWindow


<136> ;запускаем цикл сообщений:


<137> ;готовим вызов BOOLGetMessageA( LPMSGlpMsg, HWNDhWnd,


<138> ; UINTwMsgFilterMin,UINTwMsgFilterMax)


<139> cycl_msg:


<140> push 0


<141> push 0


<142> push NULL


<143> push offset message


<144> cal 1 GetMessageA


<145> cmp ах, 0


<146> je end_cycl_msg


<147> ;трансляция ввода с клавиатуры


<148> ;готовимвызов BOOL Trans1ateMessage( CONST MSG *lpMsg )


<149> push offset message


<150> call TranslateMessage


<151> ;отправим сообщение оконной процедуре


<152> ;готовимвызов LONG D1spatchMessage( CONST MSG *lpmsg )


<153> push offset message


<154> call DispatchMessageA


<155> jmp cycl_msg


<156> end_cycl_msg:


<157>


<158> ;выход из приложения


<159> ;готовим вызов VOIDExitProcess( UINTuExitCode )


<160> push NULL


<161> call ExitProcess


<162> start endp


<163> ; - - - - - - - - - - - - --WindowProc-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


<164> WindowProc proc


<165> argP0nwnd:DWORD, PPmes:DWORD, @@wparam:DWORD, @@lparam:DWORD


<166> usesebx, edi, es1 ;эти регистры обязательно должны сохраняться


<167> local @@hdc:DWORD


<168> cmp @@mes, WM_DESTROY


<169> je wmdestroy


<170> cmp @@mes, WM_CREATE


<171> je wmcreate


<172> cmp @@mes, WM_PAINT


<173> je wmpaint


<174> jmp default


<175> wmcreate:


<176> ;обозначим создание окна звуковым эффектом


<177> ;готовим вызов функции BOOLPlaySound(LPCSTRpszSound, HMODULEhmod, DWORD


;fdwSound )


<178> push SND_SYNC+SND_FILENAME


<179> push NULL


<180> push offset playFileCreate


<181> callPlaySoundA


<182> moveax, О;возвращаемое значение - 0


<183> jmp exit_wndproc


<184> wmpaint:


<185> push SND_SYNC+SND_FILENAME


<186> push NULL


<187> push offset playFIilePaint


<188> call

P1aySoundA


<189>;получимконтекстустройства HDC BeginPaint(HWND nwnd,LPPAINTSTRUCT;LPpAINT)


<190> push offset ps


<191> push @@hwnd


<192> call BeginPaint


<193> mov @@hdc,eax


<194> ;выведемстрокутекставокно BOOL TextOut( HDC hdc. int nXStart, int


:nYStart.


<195> ; LPCTSTR lpString, int cbString )


<196> push MesWindowLen


<197> push offset MesWindow


<198> push 100


<199> push 10


<200> push @@hdc


<201> call TextOutA


<202> :ocвoбoдитькoнтeкcтBOOLEndPaint( HWNDhWnd, CONSTPAINTSTRUCT*lpPai <203> push offset ps


<204> push @@hdc


<205> call EndPaint


<206> mov еах,0;возвращаемое значение-0


<207> jmp exit_wndproc


<208> wmdestroy:


<209> push SND_SYNC+SND_FILENAME


<210> push NULL


<211> push offset playFileDestroy


<212> callPlaySoundA


<213> ;послать сообщение WМ_QUIТ


<214> ;готовимвызов VOID PostQuitMessage( int nExitCode )


<215> push 0


<216> call PostQuitMessage


<217> mov eax, О;возвращаемоезначение - 0


<218> jmp exit_wndproc


<219> default:


<220> ; обработка по умолчанию


<221>;готовим вызов LRESULTDefWindowProc( HWNDhWnd, UINTMsg,


<222> ; WPARAMwParam,LPARAMlParam)


<223> push @@lparam


<224> push @@wparam


<225> push @@mes


<226> push @@nwnd


<227> call DefWindowProcA


<228> jmp exit_wndproc


<229> ;... ... ...


<230> exit_wndproc:


<231> ret


<232> WindowProc endp


<233> end start


3.Иерархия
окон


Изучив по дисциплине «Системное программное обеспечение» написание окон Windows на языке Assembler и рассматривая графическую оконную систему нельзя обойтись без подробного рассмотрения того, какие окна можно отображать на экране.


Тип окна задается 32-битовым без знаковым целым числом, которое указывается третьим параметром вызова функции CreateWindow.


Существует всего лишь три основных типа окон Window.


1 тип. Перекрывающиеся окна. Флаг WS_OVERLAPPED.


2 тип. Вспомогательные окна. Флаг WS_POPUP.


3 тип. Дочерние окна. . Флаг WS_CHILD.


Для написания курсового проекта, который имеет тему «Программа демонстрирующая иерархию окон 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;транслятор автоматически преобразует команду условной передачи управления


;в комбинацию условной и безусловной команды, если условная в силу ограниченности ;области своего действия не обеспечивает передачу управления по нужному адресу


modelflat,STDCALL;выбирает модель памяти для 32-разрядного программирования и ;правила передачи параметров функции STDCALL, далее действующие по умолчанию


UNICODE = 0


includewin32.inc;файл, содержащий описание структур данных и констант


; some 32-bit constants and structures


Lequ <LARGE>; последовательности символов LARGE, являющейся именем операции, объявляющей следующий за ней операнд 32-разрядным, присваивается имя L


Define the external functions we will be linking to


;


extrnBeginPaint: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


extrnFindFirstFileA: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 ;дикриптормодуля


pushLIDI_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 ; Class name;имякласса


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 ; Class name


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. Использование TurboAssembler при разработке программ / Составитель А.А. Чекатков. Киев: Диалектика, 1995.


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


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


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

Сохранить в соц. сетях:
Обсуждение:
comments powered by Disqus

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

Слов:3754
Символов:35710
Размер:69.75 Кб.