Каталог :: Программирование и комп-ры

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

Министерство образования РФ
ИНСТИТУТ ПЕРЕПОДГОТОВКИ КАДРОВ
          Уральского государственного технического университета          
     

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

Оценка проекта Члены комиссии Программа демонстрирующая иерархию окон Windows

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

руководитель: Кулюкин В.П. слушатель гр.СП-923: 2001г. Содержание:

Введение

1. Окон­ные приложения Windows. 2. Каркасное Windows-приложение на ассемблере 3. Иерархия окон 4. «Программа демонстрирующая иерархию окон Windows» 5.Библиографический список Введение В подавляющем большинстве книг о программировании для Windows изложение, как правило, ведется на базе языка C/C++, реже — на базе Pascal. А что же ас­семблер — в стороне? Конечно, нет! Мы не раз обращали ваше внимание на пра­вильное понимание места ассемблера в архитектуре компьютера. Любая програм­ма на языке самого высокого уровня в своем внутреннем виде представляет собой последовательность машинных кодов. А раз так, то всегда остается теоретическая возможность написать ту же программу, но уже на языке ассемблера: Непонима­ние или недооценка такой возможности приводит к тому, что достаточно часто приходится слышать фразу, подобную следующей: «Ах, опять этот ассемблер, но ведь это что-то несерьезное!» Также трудно согласиться с тезисом, который чаще всего следует вслед за этой фразой. Суть его сводится к утверждению того, что мощность современных компьютеров позволяет не рассматривать проблему эф­фективности функционирования программы в качестве первоочередной. Гораздо легче решить ее за счет увеличения объема памяти, быстродействия центрально­го процессора и качества компьютерной периферии. Чем обосновать необходимость разработки Windows-приложений на языке ассем­блера? Приведем следующие аргументы: Ø языке ассемблера позволяет программисту полностью контролировать создава­емый им программный код и оптимизировать его по своему усмотрению; Ø компиляторы языков высокого уровня помещают в загрузочный модуль про­граммы избыточную информацию. Эквивалентные исполняемые модули, ис­ходный текст которых написан на языке ассемблера, имеют в несколько раз меньший размер; Ø при программировании на ассемблере сохраняется полный доступ к аппарат­ным ресурсам компьютера; Ø приложение, написанное на языке ассемблера, как правило, быстрее загружа­ется в оперативную память компьютера; Ø приложение, написанное на языке ассемблера, обладает, как правило, более высокой скоростью работы и реактивностью ответа на действия пользователя. Разумеется, эти аргументы не следует воспринимать, как некоторую рекламную кампанию в поддержку языка ассемблера. Но нельзя забывать и о том, что суще­ствует бесконечное множество прикладных задач, ждущих своей очереди на ком­пьютерную реализацию. Далеко не все из этих задач требуют применения тяже­ловесных средств разработки, результатом работы которых являются столь же тяжеловесные исполняемые файлы. Многие прикладные задачи могут быть изящ­но исполнены на языке ассемблера, не теряя привлекательности. 1. Окон­ные приложения Windows. Windows поддерживает два типа приложений: Ø оконное приложение — строится на базе специального набора функций (API), составляющих графический интерфейс пользователя (GUI, Graphic User Inter­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> include windowA.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> extrn EndPaint: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> szTitleName db 'Каркасное приложение Win32 на ассемблере'.0 <46> MesWindow db 'Это процесс разработки приложения на ассемблере?' <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> ;вызов LPTSTR GetCommandLine(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> mov hInst, eax ;no которому загружен модуль. <72> ;далее hInst будет использоваться в качестве дескриптора данного приложения <73> ;конец стартового кода <74> WinMain: <75>;определить класс окна ATOM RegisterClassEx(CONST WNDCLASSEX *lpWndClassEx), <76> ; где *lpWndClassEx - адрес структуры WndClassEx <77> ;для начала инициализируем поля структуры WndClassEx <78> mov wcl.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> mov eax,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> push IDC_ARROW ,-стандартный курсор - стрелка <93> push 0 <94> саll LoadCursorA <95> mov wcl.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> test ax, ах;проверить на успех регистрации класса окна <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> push CW_USEDEFAULT ;координата у левого верхнего угла ;окна <120> push CW_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> call ShowWindow <132> ;перерисовываем содержимое окна <133> ;готовим вызов BOOL UpdateWindow( HWND hWnd ) <134> push hwnd <135> call UpdateWindow <136> ;запускаем цикл сообщений: <137> ;готовим вызов BOOL GetMessageA( LPMSG lpMsg, HWND hWnd, <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> ;готовим вызов VOID ExitProcess( UINT uExitCode ) <160> push NULL <161> call ExitProcess <162> start endp <163> ; - - - - - - - - - - - - --WindowProc-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <164> WindowProc proc <165> argP0nwnd:DWORD, PPmes:DWORD, @@wparam:DWORD, @@lparam:DWORD <166> uses ebx, 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> ;готовим вызов функции BOOL PlaySound(LPCSTR pszSound, HMODULE hmod, DWORD ;fdwSound ) <178> push SND_SYNC+SND_FILENAME <179> push NULL <180> push offset playFileCreate <181> call PlaySoundA <182> mov eax, О;возвращаемое значение - 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> call PlaySoundA <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( HWND hWnd, 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-битовым без знаковым целым числом, которое указывается третьим параметром вызова функции Create Window. Существует всего лишь три основных типа окон 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;транслятор автоматически преобразует команду условной передачи управления ;в комбинацию условной и безусловной команды, если условная в силу ограниченности ;области своего действия не обеспечивает передачу управления по нужному адресу 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 ; 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. Использование Turbo Assembler при разработке программ / Составитель А.А. Чекатков. Киев: Диалектика, 1995. 2. Рихтер Д. Windows для профессионалов ( программирование в Win32 API для Windows NT 3.5 и Windows 95) пер. С англ. М.: Издательский отдел «Русский Редакция» ТОО «Channel Trading Ltd», 1995. 3. Зубков С.В. Assembler. Для DOS, Windows и Unix. М. : ДМК. 1999.