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

Программа, демонстрирующая иерархию окон 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-приложение на ассемблере

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

  .386

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

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

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

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

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

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

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

     extrn             GetModuleHandleA:PROC

    extrn            GetVersionExA:PROC В

    extrn             GetCommandLineA:PROC

    extrn             GetEnvironmentStringsA:PROC

    extrn             GetEnvironmentStringsA:PROC

    extrn             GetStartupInfoA:PROC

    extrn             LoadIconA:PROC

    extrn             LoadCursorA:PROC

    extrn             GetStockObject:PROC

    extrn             RegisterClassExA:PROC

    extrn             CreateWindowExA:PROC

   extrn             ShowWindow:PROC

    extrn             UpdateWindow:PROC

    extrn             GetMessageA:PROC

    extrn            TranslateMessage:PROC

    extrn             DispatchMessageA:PROC

    extrn             ExitProcess:PROC            

    extrn             PostQuitMessage:PROC

    extrn             DefWindowProcA:PROC

    extrn             PlaySoundA:PROC

    extrn             ReleaseDC:PROC

    extrn             TextOutA:PROC  

    extrn             GetDC:PROC

    extrn             BeginPaint:PROC

    extrn            EndPaint:PROC

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

  public WindowProc

   .data

    hwnd              dd           0

hInst                  dd           0

hdc                     dd           0

;lpVersionInformation OSVERSIONINFO  

wcl       WNDCLASSEX   

message   MSG   

ps       PAINTSTRUCT  

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

szTitleName db     'Каркасное приложение Win32 на ассемблере'.0

MesWindow  db   'Это  процесс разработки приложения

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

MesWindowLen=     $-MesWindow

playFileCreate       db   'create.wav',0

playFilePaint         db   'paint.wav',0

playFileDestroy    db  'destroy.wav',0

. code

start     proc   near

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

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

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

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

;вызов BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInformation)

;        push   offset lpVersionInformation

;        call   GetVersionExA

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

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

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

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

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

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

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

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

;       push   offset lpStartupInfo

;       call   GetStartupInfoA

;вызов HMODULE GetModuleHandleA (LPCTSTR lpModuleName)

push   NULL ;0->GetModuleHandle

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

mov    hInst, eax     ;no которому загружен модуль.

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

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

WinMain:

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

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

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

mov    wcl.cbSize,typeWNDCLASSEX   -.размер структуры

 :в wcl.cbCIZE

mov  wcl.style,CS_HREDRAW+CS_VREDRAW  

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

mov    wcl.cbCisExtra,0

mov    wcl.cbWndExtra,0

mov    eax,hInst

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

mov    wcl.hInstance, eax

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

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

push 0 ;NULL

саП LoadIconA

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

;структуры wcl

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

push IDC_ARROW ,-стандартный курсор - стрелка

push 0

саll LoadCursorA

mov wcl.hCursor,eax ;дескриптор курсора в поле hCursor

;структуры wc1

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

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

push WHITE_BRUSH

саП GetStockObject

mov wcl.hbrBackground, eax

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

mov dwordptrwcl.lpszClassName,offsetszC1assName; имя

;класса окна  

mov wcl.hIconSm, 0

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

push offset wcl

саП RegisterClassExA

test ax, ах;проверить на успех регистрации класса окна

jz end_cyc1_msg ;неудача

;создаем окно:

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

 LPCTSTR1pClassName,

; LPCTSTR 1pW1ndowName, DWORD dwStyle, int x, int у, int nWidth,

             |;int nHeight,

;  HWND hWndParent, HMENU hMenu, HANDLE hInstance, LPVOID      

             ;lpParam)

     push   0   ;lpParam                         

     push   hInst ;hInstance     

     push   NULL ;menu

      push   NULL ;parent hwnd

      push   CW_USEDEFAULT    ;высота окна

      push   CW_USEDEFAULT    ;ширина окна

       push   CW_USEDEFAULT    ;координата у левого верхнего угла

           ;окна

       push   CW_USEDEFAULT    ;координата х левого верхнего угла

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

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

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

       push   NULL

      саll   CreateWindowExA

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

       ;показать окно:

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

push   SW_SHOWNORMAL

push         hwnd

call         ShowWindow

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

;готовим вызов BOOL UpdateWindow( HWND hWnd )

push         hwnd

call          UpdateWindow

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

;готовим вызов BOOL GetMessageA( LPMSG lpMsg, HWND hWnd,

;                     UINTwMsgFilterMin,UINTwMsgFilterMax)

cycl_msg:

push         0

push         0

push         NULL

push         offset message

cal 1         GetMessageA

cmp           ах, 0

je            end_cycl_msg

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

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

push         offset message

call         TranslateMessage

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

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

push          offset message

call          DispatchMessageA

jmp           cycl_msg

end_cycl_msg:

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

;готовим вызов VOID ExitProcess( UINT uExitCode )

push         NULL

call          ExitProcess

start            endp

; - - - - -  - - - - - - - --WindowProc-- - - - -  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WindowProc    proc

argP0nwnd:DWORD, PPmes:DWORD, @@wparam:DWORD, @@lparam:DWORD

uses ebx, edi, es1        ;эти регистры обязательно должны сохраняться

local              @@hdc:DWORD

cmp           @@mes, WM_DESTROY

je            wmdestroy

cmp           @@mes, WM_CREATE

je            wmcreate

cmp           @@mes, WM_PAINT

je            wmpaint

jmp           default

wmcreate:

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

;готовим вызов функции BOOL PlaySound(LPCSTR pszSound, HMODULE hmod, DWORD

 ;fdwSound     )

push          SND_SYNC+SND_FILENAME

push         NULL

push         offset playFileCreate

        call   PlaySoundA

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

         jmp    exit_wndproc

wmpaint:

         push   SND_SYNC+SND_FILENAME

         push   NULL

         push   offset playFIilePaint

         call P1aySoundA

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

         push   offset ps

         push   @@hwnd

         call BeginPaint

         mov @@hdc,eax

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

:nYStart.

;       LPCTSTR lpString, int cbString )

         push   MesWindowLen

         push   offset MesWindow

         push   100

         push   10

         push   @@hdc

         call   TextOutA

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

         push   @@hdc

         call   EndPaint

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

          jmp    exit_wndproc

  wmdestroy:

         push   SND_SYNC+SND_FILENAME

         push   NULL

          push   offset playFileDestroy

         call   PlaySoundA

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

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

         push   0

         call   PostQuitMessage

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

         jmp    exit_wndproc

default:

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

;готовим вызов LRESULTDefWindowProc( HWND hWnd, UINTMsg,

;        WPARAMwParam,LPARAMlParam)

         push   @@lparam

          push   @@wparam

         push   @@mes

         push   @@nwnd

          call    DefWindowProcA

          jmp exit_wndproc

;...  ...  ...

exit_wndproc:

ret

WindowProc    endp

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, являющейся именем операции, объявляющей следующий за ней операнд 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.





2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.