Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Оконные (каркасные) приложения WindowsСодержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте
Главным элементом программы в среде Windows является окно. Окно может содержать элементы управления: кнопки, списки, окна редактирования и др. Эти элементы также являются окнами, но обладающими особым свойством: события, происходящие с этими элементами (и самим окном), приводят к приходу сообщений в процедуру окна. Для каждого окна определяется своя процедура обработки сообщений. Система Windows является многозадачной: каждая задача имеет свое адресное пространство и свою очередь сообщений. Любая процедура в среде Windows может быть запущена как самостоятельная задача. В структуре каркасного приложения Windows можно выделить следующие разделы, образующие «скелет» программы: · получение дескриптора приложения; · регистрация класса окна; · создание главного окна; · цикл обработки очереди сообщений; · процедура главного окна. Получение дескриптора приложения осуществляется функцией HMODULE WINAPI GetModuleHandle(__in_opt LPCTSTR lpModuleName); lpModuleName – имя загруженного модуля (.dll или.exe файла), включая путь; если принимает значение 0, то функция возвращает дескриптор исполняемого.exe – файла. Регистрация класса окна осуществляется с помощью функции ATOM RegisterClass(CONST WNDCLASS *lpwcx); единственным параметром которой является указатель на структуру WNDCLASS, содержащую информацию об окне. Под регистрацией класса окна понимается совокупность присущих ему характеристик, таких как стиль его границ, форм курсора, пиктограмм, цвета фона, наличия меню, адреса оконной процедуры, обрабатывающей сообщения этого окна. WNDCLASS struc style DD? ;стиль границ окна и его поведение ; при перерисовке ;CS_VREDRAW = 0001h ;CS_HREDRAW = 0002h ;CS_KEYCVTWINDOW = 0004H ;CS_DBLCLKS = 0008h ;CS_OWNDC = 0020h ;CS_CLASSDC = 0040h ;CS_PARENTDC = 0080h ;CS_NOKEYCVT = 0100h ;CS_SAVEBITS = 0800h ;CS_NOCLOSE = 0200h ;CS_BYTEALIGNCLIENT = 1000h ;CS_BYTEALIGNWINDOW = 2000h ;CS_GLOBALCLASS = 4000h lpfnWndProc WNDPROC?;адрес оконной процедуры ;Все окна, созданные на основе этого класса, ;будут обрабатывать посланные им сообщения cbClsExtra DD?;количество дополнительно cbWndExtra DD?;резервируемых байт, обычно 0 hInstance DD?;дескриптор приложения, полученный ;GetModulHandleA hIcon DD?;дескриптор значка LoadIcon ;IDI_APPLICATION = 32512 ;IDI_HAND = 32513 ;IDI_QUESTION = 32514 ;IDI_EXCLAMATION = 32515 ;IDI_ASTERISK = 32516 hCursor DD?;дескриптор курсора LoadCursor ;IDC_ARROW = 32512 ;IDC_IBEAM = 32513 ;IDC_WAIT = 32514 ;IDC_CROSS = 32515 ;IDC_UPARROW = 32516 ;IDC_SIZE = 32640 ;IDC_ICON = 32641 ;IDC_SIZENWSE = 32642 ;IDC_SIZENESW = 32643 ;IDC_SIZEWE = 32644 ;IDC_SIZENS = 32645 hbrBackground DD?;дескриптор кисти ;WHITE_BRUSH =0 ;LTGRAY_BRUSH =1 ;GRAY_BRUSH =2 ;DKGRAY_BRUSH =3 ;BLACK_BRUSH =4 ;NULL_BRUSH =5 ;HOLLOW_BRUSH =5 Цвет фона окна можно также задать функцией CreateSolidBrush, аргумент которой – это константа, получаемая как комбинация трех цветов (RGB): красного, зеленого и синего. Цвет определяется одним 32-битным числом. В этом числе первый байт - интенсивность красного, второй байт - интенсивность зеленого, третий байт - интенсивность синего цвета. Последний байт равен нулю. lpszMenuName DD 0;указатель на ASCIIZ строку ;с именем меню lpszClassName DD?;присвоение данному классу ;уникального имени ends Создание окна осуществляется с помощью функции, позволяющей создать экземпляр окна. HWND CreateWindowEx( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); dwExStyle – определяет дополнительные стили создаваемого окна: WS_EX_ACCEPTFILES = 10h – поддержка перетаскивания файлов WS_EX_APPWINDOW = 00040000h – добавление окна на панель задач WS_EX_CLIENTEDGE = 00000200h – стиль границ окна WS_EX_COMPOSITED – перерисовка снизу вверх (Windows XP) WS_EX_CONTEXTHELP =00000400h – значок «?» в строке заголовка окна WS_EX_CONTROLPARENT=00010000h – окно содержит дочернее окно, использующееся в диалогах WS_EX_DLGMODALFRAME = 1h – окно с двойной границей WS_EX_LAYERED=00080000h – «послойное» окно (Windows XP) WS_EX_LAYOUTRTL=00400000h – начало отсчета по горизонтали – справа WS_EX_LEFT=00000000h –выравнивание свойств по левому краю (по умолчанию) WS_EX_LEFTSCROLLBAR = 00004000h – полоса прокрутки слева WS_EX_LTRREADING= 00000000h – отображение текста слева направо (по умолчанию) WS_EX_MDICHILD – создание дочернего окна в многооконном интерфейсе (MDI) WS_EX_NOACTIVATE= 08000000h – созданное окно не активируется WS_EX_NOINHERITLAYOUT= 00100000h – окно не передает свое положение дочерним окнам WS_EX_NOPARENTNOTIFY = 4h – дочернее окно не передает сообщение WM_PARENTNOTIFY родительскому окну при своем создании/закрытии. WS_EX_OVERLAPPEDWINDOW=WS_EX_CLIENTEDGE+WS_EX_WINDOW. WS_EX_PALETTEWINDOW=WS_EX_WINDOWEDGE+WS_EX_TOOLWINDOW+WS_EX_TOPMOST. WS_EX_RIGHT = 00001000h – выравнивание свойств по правому краю WS_EX_RIGHTSCROLLBAR = 00000000h – вертикальная полоса прокрутки в правой части окна (по умолчанию) WS_EX_RTLREADING =00002000h – размещение текста справа налево WS_EX_STATICEDGE =00020000h – окно с тркхмерным стилем границ WS_EX_TOOLWINDOW = 00000080h – окно для плавающей панели инструментов WS_EX_TOPMOST = 8h – расположение окна перед всеми окнами. WS_EX_TRANSPARENT = 20h – окно без перерисовки WS_EX_WINDOWEDGE = 00000100h – «приподнятый» стиль границ окна lpClassName — указатель на ASCIIZ-строку с именем класса окна. Можно использовать предопределенные классы для создания элементов окна: BUTTON – кнопка; COMBOBOX – набор переключателей; EDIT – поле редактирования; LISTBOX – список; MDICLIENT – MDI-клиент; RICHEDIT_CLASS – объект Rich Edit 2.0; SCROLLBAR – полоса прокрутки; STATIC – надпись. lpWindowName — указатель на ASCIIZ-строку с именем окна. dwStyle определяет стиль окна приложения: WS_OVERLAPPED =000000000h WS_ICONICPOPUP =0C0000000h WS_POPUP =080000000h WS_CHILD =040000000h WS_MINIMIZE =020000000h WS_VISIBLE =010000000h WS_DISABLED =008000000h WS_CLIPSIBLINGS =004000000h WS_CLIPCHILDREN =002000000h WS_MAXIMIZE =001000000h WS_CAPTION =000C00000h;WS_BORDER | WS_DLGFRAME WS_BORDER =000800000h WS_DLGFRAME =000400000h WS_VSCROLL =000200000h WS_HSCROLL =000100000h WS_SYSMENU =000080000h WS_THICKFRAME =000040000h WS_HREDRAW =000020000h WS_VREDRAW =000010000h WS_GROUP =000020000h WS_TABSTOP =000010000h WS_MINIMIZEBOX =000020000h WS_MAXIMIZEBOX =000010000h x — координата левого верхнего угла окна y — координата левого верхнего угла окна nWidth — ширина окна (по умолчанию CW_USEDEFAULT (80000000h)) nHeight — высота окна (по умолчанию CW_USEDEFAULT (80000000h)) hWndParent — дескриптор родительского окна. Между двумя окнами Windows-приложения можно устанавливать родовидовые отношения. Дочернее окно всегда должно появляться в области родительского окна. hMenu — дескриптор главного меню окна hInstance — дескриптор приложения, создающего окно. lpParam – используется при создании окна для передачи данных или указателя на них в оконную функцию. Все параметры, передаваемые функции CreateWindowEx, сохраняются в создаваемой Windows внутренней структуре CREATESTRUCT. Поля этой структуры идентичны параметрам функции CreateWindowEx. Указатель на структуру CREATESTRUCT передается оконной функции при обработке сообщения WMCREATE. Сам указатель находится в поле lpParam сообщения. Значение параметра lpParam функции CreateWindowEx находится в поле lpCreateParams структуры CREATESTRUCT. Функция CreateWindowEx возвращает дескриптор окна.
Для отображения окна используется функция BOOL ShowWindow(HWND hWnd, int nCmdShow); hWnd – дескриптор окна. nCmdShow – константа, задающая начальный вид окна. SW_HIDE =0 SW_SHOWNORMAL =1 SW_NORMAL =1 SW_SHOWMINIMIZED =2 SW_SHOWMAXIMIZED =3 SW_MAXIMIZE =3 SW_SHOWNOACTIVATE =4 SW_SHOW =5 SW_MINIMIZE =6 SW_SHOWMINNOACTIVE =7 SW_SHOWNA =8 SW_RESTORE =9
Цикл обработки сообщений. После создания данного цикла приложение становится пассивным и начинает взаимодействовать с внешним миром посредством специальным образом оформленных данных — сообщений. Для получения сообщений используется функция GetMessage, выполняющая следующие действия: · постоянно просматривать очередь сообщений; · выбирать сообщения, удовлетворяющие заданным в функции параметрам; · заносит информацию о событии в экземпляр структуры MSG; · передает управление в цикл обработки сообщений. BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax); lpMsg – указатель на экземпляр структуры MSG. Во время работы GetMessageA извлекает сообщение из очереди сообщений приложения и на основе информации в нем инициализирует поля экземпляра структуры MSG. Таким образом, приложение получает полный доступ ко всей информации в сообщении, сформированном Windows. MSG struc hwnd DD?;дескриптор окна, которому адресовано сообщение ;возвращается функцией CreateWindowEx mes DD?;идентификатор типа сообщения ;все константы начинаются с WM_ wParam DD?;дополнительная информация о сообщении lParam DD? time DD?;время помещения сообщения в очередь сообщений pt POINT <>;координаты курсора мыши в момент помещения MSG ends ;сообщения в очередь
POINT struc x DD 0 y DD 0 POINT ends hWnd — в поле передается дескриптор окна, сообщения для которого должны будут выбираться данной функцией. Параметр, позволяет создать своеобразный фильтр, заставляющий функцию GetMessage выбирать из очереди и передавать в цикл обработки сообщений сообщения лишь для определенного окна данного приложения. Если hWnd=0, то GetMessage будет выбирать из очереди сообщения для всех окон; wMsgFilterMin и wMsgFi1terMax — значения данных параметров также позволяют создавать фильтр для выбираемых функцией GetMessageA сообщений. Они задают диапазон номеров сообщений (поле mes структуры MSG), которые будут выбираться из очереди функцией GetMessage и передаваться в цикл обработки сообщений. Цикл обработки сообщений состоит из двух функций: BOOL TranslateMessage(const MSG *lpMsg); LRESULT DispatchMessage(const MSG *lpmsg); Эти функции имеют единственный параметр — указатель на экземпляр структуры MSG, предварительно заполненный информацией о сообщении функцией GetMessage. Функция TranslateMessage предназначена для обнаружения сообщений от клавиатуры для данного приложения. Если приложение не будет самостоятельно обрабатывать ввод с клавиатуры, то эти сообщения передаются для обработки обратно Windows. Функция DispatchMessage предназначена для передачи сообщения оконной функции. Такая передача производится не напрямую, так как сама DispatchMessage ничего не знает о месторасположении оконной функции, а косвенно — посредством системы Windows. При этом: - функция DispatchMessage возвращает сообщение операционной системе; - Windows, используя описание класса окна, передает сообщение нужной оконной функции приложения; - после обработки сообщения оконной функцией управление возвращается операционной системе; - Windows передает управление функции DispatchMessage; - DispatchMessage завершает свое выполнение. Так как вызов функции DispatchMessage является последним в цикле, то управление опять передается функции GetMessage. GetMessage выбирает следующее сообщение из очереди сообщений и, если оно удовлетворяет параметрам, заданным при вызове этой функции, то выполняется тело цикла. Цикл обработки сообщений выполняется до тех пор, пока не приходит сообщение, равное 0. Получение этого сообщения — единственное условие, при котором программа может выйти из цикла обработки сообщений. Таким образом, главная функция будет иметь следующий вид: .586 .MODEL FLAT, stdcall include win.inc ; файл с константами и структурами
; сегмент данных .data HWND DD 0; дескриптор главного окна Message MSG <?> WC WNDCLASS <?> HINST DD 0; дескриптор приложения TITLENAME DB 'Программа',0 CLASSNAME DB 'CLASS32',0 ...
; сегмент кода .code START proc ; получить дескриптор приложения INVOKE GetModuleHandle, 0 MOV HINST, EAX REG_CLASS: ; заполнить структуру окна стиль MOV WC.style, CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS ; процедура обработки сообщений MOV WC.lpfnWndProc, OFFSET WNDPROC MOV WC.cbClsExtra, 0 MOV WC.cbWndExtra, 0 MOV EAX, HINST MOV WC.hInstance, EAX ;--------- иконка окна INVOKE LoadIcon, 0, IDI_APPLICATION MOV WC.hIcon, EAX ;---------- курсор окна INVOKE LoadCursor, 0, IDC_ARROW MOV WC.hCursor, EAX ;--------- MOV WC.hbrBackground, GRAY_BRUSH; цвет окна MOV DWORD PTR WC.lpszMenuName, 0 MOV DWORD PTR WC.lpszClassName, OFFSET CLASSNAME INVOKE RegisterClass, OFFSET WC ; создать окно зарегистрированного класса INVOKE CreateWindowEx, 0, OFFSET CLASSNAME, OFFSET TITLENAME, WS_CAPTION + WS_SYSMENU + WS_THICKFRAME + WS_GROUP +\ WS_TABSTOP, 100,; X — координата левого верхнего угла 100,; Y — координата левого верхнего угла 400,; DX - ширина окна 450,; DY — высота окна 0, 0, HINST,0 ; проверка на ошибку CMP EAX, 0 JZ END_LOOP MOV HWND, EAX; дескриптор окна ; -------------------------------------------------- INVOKE ShowWindow, HWND, SW_SHOWNORMAL; показать созданное окно INVOKE UpdateWindow, HWND;перерисовать видимую часть окна
; цикл обработки сообщений MSG_LOOP: INVOKE GetMessage, OFFSET Message, 0,0,0 CMP EAX, 0 JE END_LOOP INVOKE TranslateMessage, OFFSET Message INVOKE DispatchMessageA, OFFSET Message JMP MSG_LOOP END_LOOP: ; выход из программы (закрыть процесс) INVOKE ExitProcess, Message.wParam START endp ... Для организации адекватной реакции со стороны Windows-приложения на действия пользователя и поддержания в актуальном состоянии того окна приложения, сообщения которого обрабатываются, используется оконная функция. Приложение может иметь несколько оконных функций. Их количество определяется количеством классов окон, зарегистрированных в системе функцией RegisterClass. Когда для окна Windows-приложения появляется сообщение, операционная система Windows производит вызов соответствующей оконной функции. Сообщения, в зависимости от источника их появления в оконной функции, могут быть двух типов: синхронные и асинхронные. К синхронным сообщениям относятся те сообщения, которые помещаются в очередь сообщений приложения и терпеливо ждут момента, когда они будут выбраны функцией GetMessage. После этого поступившие сообщения попадают в оконную функцию, где и производится их обработка. Асинхронные сообщения попадают в оконную функцию в экстренном порядке, минуя при этом все очереди. Асинхронные сообщения, в частности, инициируются некоторыми функциями Win32 API, такими как CreateWindowEx или UpdateWIndow. Координацию синхронных и асинхронных сообщений осуществляет Windows. Если рассматривать синхронное сообщение, то его извлечение производится функцией GetMessage с последующей передачей его обратно в Windows функцией DispatchMessage. Асинхронное сообщение, независимо от источника, который инициирует его появление, сначала попадает в Windows и затем — в нужную оконную функцию. В схеме, реализованной в Windows, обработка сообщений приложением проводится в два этапа: на первом этапе приложение выбирает сообщение из очереди и отправляет его обратно во внутренние структуры Windows; на втором этапе Windows вызывает нужную оконную функцию приложения, передавая ей параметры сообщения. Преимущество этой схемы в том, что Windows самостоятельно решает все вопросы организации эффективной работы приложений. Таким образом, при поступлении сообщения Windows вызывает оконную функцию и передает ей ряд параметров. Все они берутся из соответствующих полей сообщения. Оконная функция имеет следующие параметры: 1. hWnd — дескриптор окна, которому предназначено сообщение; 2. message — идентификатор сообщения, характеризующий тип сообщения; 3. wParam и lРaram —дополнительные параметры, являющиеся копиями соответствующих полей структуры поступившего сообщения. Оставшиеся два поля структуры MSG: time и POINT используются достаточно редко, и при необходимости их значения можно извлечь непосредственно из экземпляра структуры сообщения. Параметры оконной функции Windows помещает в стек. Основные типы обрабатываемых идентификаторов сообщений WM_CREATE equ 1h; создание окна WM_DESTROY equ 2h; закрытие окна WM_PAINT equ 0Fh ; перерисовка окна WM_COMMAND equ 111h ; обработка команды Windows
WM_LBUTTONDOWN equ 201h; нажатие левой кнопки мыши WM_LBUTTONUP equ 202h; отжатие левой кнопки мыши WM_LBUTTONDBLCLK equ 203h; двойное нажатие левой кнопки мыши WM_RBUTTONDOWN equ 204h; нажатие правой кнопки мыши WM_RBUTTONUP equ 205h; отжатие правой кнопки мыши WM_RBUTTONDBLCLK equ 206h; двойное нажатие правой кнопки мыши WM_MBUTTONDOWN equ 207h; нажатие средней кнопки мыши WM_MBUTTONUP equ 208h; отжатие средней кнопки мыши WM_MBUTTONDBLCLK equ 209h; двойное нажатие средней кнопки мыши Структура процедуры окна строится по принципу switch-case, выбирая из списка тип события, которое необходимо обработать. При перерисовке окна системой посылается сообщение WM_PAINT, именно при получении этого сообщения следует перерисовывать содержимое окна. Это сообщение генерируется системой при разворачивании окна, изменении его размеров, наложении на данное окно других окон с последующим их закрытием. Для того, чтобы осуществить вывод информации в окно, необходимо сначала получить контекст окна (контекст устройства). Это — некоторое число, посредством которого осуществляется связь между приложением и окном. Обычно контекст устройства определяется посредством функции HDC GetDC(HWND hWnd); передается дескриптор окна При получении сообщения WM_PAINT контекст устройства получается посредством функции HDC BeginPaint( HWND hwnd, // дескриптор окна LPPAINTSTRUCT lpPaint); // указатель на структуру PAINTSTRUCT PAINTSTRUCT STRUCT hdc DWORD 0; дескриптор контекста окна fErase DWORD 0; 1 – стирать фон, 0 – оставить фон окна left DWORD 0; левый top DWORD 0; верхний right DWORD 0; правый bottom DWORD 0; нижний угол прямоугольника для перерисовки fRes DWORD 0; резервный, используется системой fIncUp DWORD 0; резервный, используется системой Reserv DB 32 dup(0); резервный, используется системой PAINTSTRUCT ENDS Для вывода текста в окно используется функция BOOL TextOut( HDC hdc, // дескриптор контекста окна int nXStart, // координата Х начальной позиции int nYStart, // координата Н начальной позиции LPCTSTR lpString, // указатель на строку символов int cbString); // количество байт для вывода Предварительно задать цвет фона и букв можно посредством функций COLORREF SetBkColor( HDC hdc, // дескриптор контекста окна COLORREF crColor); // цвет фона RGB COLORREF SetTextColor( HDC hdc, // дескриптор контекста окна COLORREF crColor); // цвет букв RGB Центр системы координат для окна находится в левом верхнем углу, ось Y направлена вниз, ось Х - вправо. Это общепринятый вариант для графических экранов. Для окончания перерисовки окна используется функция BOOL EndPaint( HWND hWnd, // дескриптор окна CONST PAINTSTRUCT *lpPaint // указатель на структуру PAINTSTRUCT ); // полученную функцией BeginPaint Для завершения приложения используется сообщение WM_DESTROY, которое обрабатывается вызовом функции void PostQuitMessage(int nExitCode); Аргументом функции является код завершения приложения. Для обработки нажатия на кнопку как элемент управления окна используется сообщение WM_COMMAND. При его получении программа сравнивает параметр lparam функции окна последовательно с дескрипторами кнопок и анализирует, с какой кнопкой произведено действие. Если обработчик для данного типа сообщения не требуется, вызывается обработчик сообщения по умолчанию в виде функции LRESULT DefWindowProc( HWND hWnd, // дескриптор окна UINT Msg, // тип сообщения WPARAM wParam, // параметр сообщения LPARAM lParam); // параметр сообщения
Пример оконной функции, выводящей в окно строку «Привет Всем». .data ... hBut DD?; дескриптор кнопки hdc DD?; дескриптор контекста окна ps PAINTSTRUCT <?> mess db 'Привет всем!',0; надпись в окне mess_len equ $-mess-1 .code ... ; -------------------------------------------------- ; процедура окна WNDPROC PROC hW:DWORD, Mes:DWORD, wParam:DWORD, lParam:DWORD CMP Mes, WM_DESTROY JE WMDESTROY CMP Mes, WM_CREATE JE WMCREATE CMP Mes, WM_PAINT JE WMPAINT JMP DEFWNDPROC ; создание окна WMCREATE: MOV EAX, 0 JMP FINISH ; перерисовка окна WMPAINT: INVOKE BeginPaint, hW, offset ps mov hdc,eax INVOKE SetBkColor, hdc, RGBW
mov eax, mess_len INVOKE TextOutA, hdc, 10, 20,;x, y offset mess, eax
INVOKE EndPaint, hdc, offset ps MOV EAX, 0 JMP FINISH ; обработка сообщения по умолчанию DEFWNDPROC: INVOKE DefWindowProc, hW, Mes, wParam, lParam JMP FINISH WMDESTROY: INVOKE PostQuitMessage, 0 MOV EAX, 0 FINISH: ret WNDPROC ENDP END START Пример программы, вычисляющей сумму двух чисел. ; файл win.inc ; директивы компилятору для подключения прототипов функций include c:\masm32\include\kernel32.inc include c:\masm32\include\user32.inc include c:\masm32\include\gdi32.inc include c:\masm32\include\shlwapi.inc
; стандартные дескрипторы окна IDI_APPLICATION = 32512 IDI_HAND = 32513 IDI_QUESTION = 32514 IDI_EXCLAMATION = 32515 IDI_ASTERISK = 32516
;стандартные дескрипторы курсора IDC_ARROW = 32512 IDC_IBEAM = 32513 IDC_WAIT = 32514 IDC_CROSS = 32515 IDC_UPARROW = 32516 IDC_SIZE = 32640 IDC_ICON = 32641 IDC_SIZENWSE = 32642 IDC_SIZENESW = 32643 IDC_SIZEWE = 32644 IDC_SIZENS = 32645
; свойства окна CS_VREDRAW = 0001h CS_HREDRAW = 0002h CS_KEYCVTWINDOW = 0004H CS_DBLCLKS = 0008h CS_OWNDC = 0020h CS_CLASSDC = 0040h CS_PARENTDC = 0080h CS_NOKEYCVT = 0100h CS_SAVEBITS = 0800h CS_NOCLOSE = 0200h CS_BYTEALIGNCLIENT = 1000h CS_BYTEALIGNWINDOW = 2000h CS_GLOBALCLASS = 4000h
; цвет кисти WHITE_BRUSH =0;прозрачное окно LTGRAY_BRUSH =1 GRAY_BRUSH =2 DKGRAY_BRUSH =3 BLACK_BRUSH =4 NULL_BRUSH =5; привычный цвет окна HOLLOW_BRUSH =5
; структура WNDCLASS STRUCT style DD? lpfnWndProc DD? cbClsExtra DD 0 cbWndExtra DD 0 hInstance DD? hIcon DD? hCursor DD? hbrBackground DD? lpszMenuName DD 0 lpszClassName DD? WNDCLASS ENDS
; тип окна WS_OVERLAPPED =000000000h WS_ICONICPOPUP =0C0000000h WS_POPUP =080000000h WS_CHILD =040000000h WS_MINIMIZE =020000000h WS_VISIBLE =010000000h WS_DISABLED =008000000h WS_CLIPSIBLINGS =004000000h WS_CLIPCHILDREN =002000000h WS_MAXIMIZE =001000000h WS_CAPTION =000C00000h;WS_BORDER | WS_DLGFRAME WS_BORDER =000800000h WS_DLGFRAME =000400000h WS_VSCROLL =000200000h WS_HSCROLL =000100000h WS_SYSMENU =000080000h WS_THICKFRAME =000040000h WS_HREDRAW =000020000h WS_VREDRAW =000010000h WS_GROUP =000020000h WS_TABSTOP =000010000h WS_MINIMIZEBOX =000020000h WS_MAXIMIZEBOX =000010000h
; отображение окна SW_HIDE =0 SW_SHOWNORMAL =1 SW_NORMAL =1 SW_SHOWMINIMIZED =2 SW_SHOWMAXIMIZED =3 SW_MAXIMIZE =3 SW_SHOWNOACTIVATE =4 SW_SHOW =5 SW_MINIMIZE =6 SW_SHOWMINNOACTIVE =7 SW_SHOWNA =8 SW_RESTORE =9
; Типы сообщений WM_NULL equ 0h WM_CREATE equ 1h WM_DESTROY equ 2h WM_MOVE equ 3h WM_SIZE equ 5h WM_ACTIVATE equ 6h WM_SETFOCUS equ 7h WM_KILLFOCUS equ 08h WM_ENABLE equ 0Ah WM_SETREDRAW equ 0Bh WM_SETTEXT equ 0Ch WM_GETTEXT equ 0Dh WM_GETTEXTLENGTH equ 0Eh WM_PAINT equ 0Fh WM_CLOSE equ 10h WM_QUIT equ 12h WM_KEYFIRST equ 100h WM_KEYDOWN equ 100h WM_KEYUP equ 101h WM_CHAR equ 102h WM_INITDIALOG equ 110h WM_COMMAND equ 111h WM_SYSCOMMAND equ 112h WM_TIMER equ 113h WM_HSCROLL equ 114h WM_VSCROLL equ 115h WM_MOUSEMOVE equ 200h WM_LBUTTONDOWN equ 201h WM_LBUTTONUP equ 202h WM_LBUTTONDBLCLK equ 203h WM_RBUTTONDOWN equ 204h WM_RBUTTONUP equ 205h WM_RBUTTONDBLCLK equ 206h WM_MBUTTONDOWN equ 207h WM_MBUTTONUP equ 208h WM_MBUTTONDBLCLK equ 209h WM_WINDOWPOSCHANGING equ 46h WM_WINDOWPOSCHANGED equ 47h WM_SIZING equ 214h
; структура сообщения POINT STRUCT x DD? y DD? POINT ENDS
MSG STRUCT hwnd DD? message DD? wParam DD? lParam DD? time DD? pt POINT <> MSG ENDS
PAINTSTRUCT STRUCT hdc DWORD 0; дескриптор контекста окна fErase DWORD 0; 1 – стирать фон, 0 – оставить фон окна left DWORD 0; левый top DWORD 0; верхний right DWORD 0; правый bottom DWORD 0; нижний угол прямоугольника для перерисовки fRes DWORD 0; резервный, используется системой fIncUp DWORD 0; резервный, используется системой Reserv DB 32 dup(0); резервный, используется системой PAINTSTRUCT ENDS
RECT STRUCT left dd 0 top dd 0 right dd 0 bottom dd 0 RECT ENDS
SRCCOPY equ 0CC0020h SRCPAINT equ 0EE0086h SRCAND equ 8800C6h SRCINVERT equ 660046h SRCERASE equ 440328h
PATCOPY equ 0F00021h PATPAINT equ 0FB0A09h PATINVERT equ 5A0049h DSTINVERT equ 550009h BLACKNESS equ 42h WHITENESS equ 0FF0062h
PS_SOLID equ 0 PS_DASH equ 1 PS_DOT equ 2 PS_DASHDOT equ 3 PS_DASHDOTDOT equ 4 PS_NULL equ 5 PS_INSIDEFRAME equ 6 PS_USERSTYLE equ 7 PS_ALTERNATE equ 8 PS_STYLE_MASK equ 0Fh PS_ENDCAP_ROUND equ 0h PS_ENDCAP_SQUARE equ 100h PS_ENDCAP_FLAT equ 200h PS_ENDCAP_MASK equ 0F00h PS_JOIN_ROUND equ 0h PS_JOIN_BEVEL equ 1000h PS_JOIN_MITER equ 2000h PS_JOIN_MASK equ 0F000h PS_COSMETIC equ 0h PS_GEOMETRIC equ 10000h PS_TYPE_MASK equ 0F0000h
SM_CXSCREEN equ 0 SM_CYSCREEN equ 1 SM_CXVSCROLL equ 2 SM_CYHSCROLL equ 3 SM_CYCAPTION equ 4 SM_CXBORDER equ 5 SM_CYBORDER equ 6 SM_CXDLGFRAME equ 7 SM_CYDLGFRAME equ 8 SM_CYVTHUMB equ 9 SM_CXHTHUMB equ 10 SM_CXICON equ 11 SM_CYICON equ 12 SM_CXCURSOR equ 13 SM_CYCURSOR equ 14 SM_CYMENU equ 15 SM_CXFULLSCREEN equ 16 SM_CYFULLSCREEN equ 17 SM_CYKANJIWINDOW equ 18 SM_MOUSEPRESENT equ 19 SM_CYVSCROLL equ 20 SM_CXHSCROLL equ 21 SM_DEBUG equ 22 SM_SWAPBUTTON equ 23 SM_RESERVED1 equ 24 SM_RESERVED2 equ 25 SM_RESERVED3 equ 26 SM_RESERVED4 equ 27 SM_CXMIN equ 28 SM_CYMIN equ 29 SM_CXSIZE equ 30 SM_CYSIZE equ 31 SM_CXFRAME equ 32 SM_CYFRAME equ 33 SM_CXMINTRACK equ 34 SM_CYMINTRACK equ 35 SM_CXDOUBLECLK equ 36 SM_CYDOUBLECLK equ 37 SM_CXICONSPACING equ 38 SM_CYICONSPACING equ 39 SM_MENUDROPALIGNMENT equ 40 SM_PENWINDOWS equ 41 SM_DBCSENABLED equ 42 SM_CMOUSEBUTTONS equ 43 SM_CXFIXEDFRAME equ SM_CXDLGFRAME SM_CYFIXEDFRAME equ SM_CYDLGFRAME SM_CXSIZEFRAME equ SM_CXFRAME SM_CYSIZEFRAME equ SM_CYFRAME SM_SECURE equ 44 SM_CXEDGE equ 45 SM_CYEDGE equ 46 SM_CXMINSPACING equ 47 SM_CYMINSPACING equ 48 SM_CXSMICON equ 49 SM_CYSMICON equ 50 SM_CYSMCAPTION equ 51 SM_CXSMSIZE equ 52 SM_CYSMSIZE equ 53 SM_CXMENUSIZE equ 54 SM_CYMENUSIZE equ 55 SM_ARRANGE equ 56 SM_CXMINIMIZED equ 57 SM_CYMINIMIZED equ 58 SM_CXMAXTRACK equ 59 SM_CYMAXTRACK equ 60 SM_CXMAXIMIZED equ 61 SM_CYMAXIMIZED equ 62 SM_NETWORK equ 63 SM_CLEANBOOT equ 67 SM_CXDRAG equ 68 SM_CYDRAG equ 69 SM_SHOWSOUNDS equ 70 SM_CXMENUCHECK equ 71 SM_CYMENUCHECK equ 72 SM_SLOWMACHINE equ 73 SM_MIDEASTENABLED equ 74 SM_MOUSEWHEELPRESENT equ 75 SM_CMETRICS equ 75 SM_XVIRTUALSCREEN equ 76 SM_YVIRTUALSCREEN equ 77 SM_CXVIRTUALSCREEN equ 78 SM_CYVIRTUALSCREEN equ 79 SM_CMONITORS equ 80
; файл с текстом программы .586 .MODEL FLAT, stdcall RGBW equ 00CCCCCCh; цвет фона окна include win.inc include console.inc[1]
.data HWND DD 0; дескриптор главного окна HINST DD 0; дескриптор приложения TITL DB "Программа",0 CLASSNAME DB 'CLASS32',0 Message MSG <?> WC WNDCLASS <?>
CPBUT db 'Рассчитать',0 CLSBTN db 'BUTTON',0 CLSEDT db 'EDIT',0 CAP db 'Сообщение',0 TEXTA db 20 dup(0); текст в полях редактирования TEXTB db 20 dup(0) summa dd 0
hBut DD?; дескриптор кнопки hedt1 DD?; дескриптор поля 1 hedt2 DD?; дескриптор поля 2 hdc DD?; дескриптор контекста окна ps PAINTSTRUCT <?> mess1 db 'Посчитать сумму двух чисел: ',0; надпись в окне mess1_len equ $-mess1-1 mess2 db '=',10 dup(' '),0; результат суммы строковый sum_len equ $-mess2-1
.code START proc ; получить дескриптор приложения INVOKE GetModuleHandle, 0 MOV HINST, EAX ; заполнить структуру окна стиль MOV WC.style, CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS ; процедура обработки сообщений MOV WC.lpfnWndProc, OFFSET WNDPROC MOV EAX, HINST MOV WC.hInstance, EAX INVOKE LoadIcon, 0, IDI_APPLICATION MOV WC.hIcon, EAX INVOKE LoadCursor, 0, IDC_ARROW MOV WC.hCursor, EAX INVOKE CreateSolidBrush, RGBW MOV WC.hbrBackground, EAX MOV DWORD PTR WC.lpszMenuName, 0 MOV DWORD PTR WC.lpszClassName, OFFSET CLASSNAME INVOKE RegisterClass, OFFSET WC ; создать окно зарегистрированного класса INVOKE CreateWindowEx, 0, OFFSET CLASSNAME, OFFSET TITL, WS_CAPTION + WS_SYSMENU + WS_THICKFRAME + WS_GROUP + WS_TABSTOP, 100,; X — координата левого верхнего угла 100,; Y — координата левого верхнего угла 400,; DX - ширина окна 450,; DY — высота окна 0, 0, HINST,0 CMP EAX, 0 ; проверка на ошибку JZ END_LOOP MOV HWND, EAX; дескриптор окна
INVOKE ShowWindow, HWND, SW_SHOWNORMAL; показать созданное окно INVOKE UpdateWindow, HWND;перерисовать видимую часть окна ;------------------------------------------------------------------- ; цикл обработки сообщений MSG_LOOP: INVOKE GetMessage, OFFSET Message, 0,0,0 CMP EAX, 0 JE END_LOOP INVOKE TranslateMessage, OFFSET Message INVOKE DispatchMessageA, OFFSET Message JMP MSG_LOOP END_LOOP: INVOKE ExitProcess, Message.wParam; выход из программы START endp ; -------------------------------------------------- ; процедура окна WNDPROC PROC hW:DWORD, Mes:DWORD, wParam:DWORD, lParam:DWORD CMP Mes, WM_DESTROY JE WMDESTROY CMP Mes, WM_CREATE JE WMCREATE CMP Mes, WM_COMMAND JE WMCOMMAND CMP Mes, WM_PAINT JE WMPAINT JMP DEFWNDPROC ;------------------------------------------------------------------ WMCREATE: ; создание окна INVOKE CreateWindowExA, 0,; поле редактирования 1 offset CLSEDT, ;имя класса окна offset TEXTA, ;надпись в поле WS_CHILD+WS_VISIBLE,;стиль окна 10, 50, ;x, y 60, 20, ;длина, ширина hW, ;дескриптор окна 0, ;дескриптор меню HINST, ;дескриптор приложения 0 ;lpParam mov hedt1,eax; сохранение дескриптора mov eax,0 INVOKE ShowWindow, hedt1, SW_SHOWNORMAL INVOKE CreateWindowExA, 0,; поле редактирования 2 offset CLSEDT, ;имя класса окна offset TEXTB, ;надпись в поле WS_CHILD+WS_VISIBLE, ;стиль окна 90, 50, ;x, y 60, 20, ;длина, ширина hW, ;дескриптор окна 0, ;дескриптор меню HINST, ;дескриптор приложения 0 ;lpParam mov hedt2,eax ; сохранение дескриптора mov eax,0 INVOKE ShowWindow, hedt2, SW_SHOWNORMAL INVOKE CreateWindowExA, 0,; кнопка offset CLSBTN, ;имя класса окна offset CPBUT, ;надпись на кнопке WS_CHILD+WS_VISIBLE,;стиль окна кнопки 10, 90, ;x, y 100, 20, ;длина, ширина hW, ;дескриптор окна 0, ;дескриптор меню HINST, ;дескриптор приложения 0 ;lpParam mov hBut,eax ; сохранение дескриптора mov eax,0 INVOKE ShowWindow, hBut, SW_SHOWNORMAL MOV EAX, 0 JMP FINISH ;------------------------------------------------------------------ WMCOMMAND: ; обработка нажатия кнопки mov eax, hBut cmp lParam,eax jne COM_END ; команда не соответствует нажатию кнопки
INVOKE SendMessage, hedt1, WM_GETTEXT, 20, offset TEXTA INVOKE SendMessage, hedt2, WM_GETTEXT, 20, offset TEXTB
INVOKE StrToInt, offset TEXTA mov summa, eax INVOKE StrToInt, offset TEXTB add summa, eax
mov eax, sum_len INVOKE TextOutA,; стирание строки результата в окне hdc, 180, 50, offset mess2, eax INVOKE IntToStr, summa, offset mess2+1 INVOKE LENSTR, offset mess2; определение длины результата push eax INVOKE TextOutA,; вывод результата hdc, 180, 50, offset mess2, eax pop ecx ; очистка строки inc ecx mov al,' ' mov edi, offset mess2+1 CLR: mov [edi],al inc edi loop CLR COM_END: MOV EAX, 0 JMP FINISH ;------------------------------------------------------------------ WMPAINT: ; перерисовка окна INVOKE BeginPaint, hW, offset ps mov hdc,eax INVOKE SetBkColor, hdc, RGBW
mov eax, mess1_len INVOKE TextOutA, hdc, 10, 20, offset mess1, eax INVOKE EndPaint, hdc, offset ps MOV EAX, 0 JMP FINISH ;------------------------------------------------------------------ DEFWNDPROC: ; обработка сообщения по умолчанию INVOKE DefWindowProc, hW, Mes, wParam, lParam JMP FINISH ;------------------------------------------------------------------ WMDESTROY: ; выход из цикла обработки сообщений INVOKE PostQuitMessage, 0 MOV EAX, 0 FINISH: ret WNDPROC ENDP END START В результате работы программы получим окно: Графика в оконных приложениях Windows Система координат для вывода графических образов такая же, как и для ввода текстовой информации. Координаты измеряются в логических единицах, которые по умолчанию совпадают с пикселями. Начало отсчета – верхний левый угол окна. Для создания графических образов используются 3 основных объекта: точка (пиксел), перо, кисть. Цвет точки задается с помощью функции COLORREF SetPixel( HDC hdc, // дескриптор контекста окна int X, // x-координата точки int Y, // y-координата точки COLORREF crColor); // цвет точки Перо используется для рисования линий и контуров замкнутых фигур. Цвет пера задается при помощи функции HPEN CreatePen( int fnPenStyle, // стиль пера // PS_SOLID =0 // PS_DASH =1 // PS_DOT =2 // PS_DASHDOT =3 // PS_DASHDOTDOT =4 // PS_NULL =5 невидимое перо int nWidth, // ширина пера COLORREF crColor); // цвет пера Кисть используется для закрашивания замкнутых объектов. Цвет кисти задается с помощью функции HBRUSH CreateSolidBrush(COLORREF crColor); // цвет кисти Можно заранее создать несколько кистей и перьев, а затем выбирать нужные с помощью функции HGDIOBJ SelectObject( HDC hdc, // дескриптор контекста окна HGDIOBJ hgdiobj); // дескриптор объекта Обновление информации в окне программы происходит по получению сообщения WM_PAINT. В реальных программах вывод информации в окно может происходить по различным событиям и из различных процедур. Кроме того, если информации в окне много, то непосредственный вывод при помощи функции TextOut достаточно медленный. Чтобы воспроизводить содержимое окна, необходимо где-то запомнить это содержимое. Возникает проблема сохранения информации (и не только текстовой), находящейся в окне. В операционной системе Windows образуется виртуальное окно, и весь вывод информации производится туда. Затем по приходе сообщения WM_PAINT содержимое виртуального окна копируется на реальное окно. В целом общая схема такова: 1. При создании окна - создается совместимый контекст устройства функцией HDC CreateCompatibleDC(HDC hdc); // дескриптор контекста окна Полученный контекст следует запомнить. - создается карта бит, совместимая с данн<
|
||||
Последнее изменение этой страницы: 2020-12-09; просмотров: 414; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.149.29.192 (0.011 с.) |