Анимация
JavaScript
|
Главная Библионтека 340 ==бР 9 f..™.?.;*? Глава 5. Программирование на ассемблере nog Windows 34 предопределенных Windows классов окон (как правило, элементов управления), оно i может иметь меню. Тогда iiMenu используется как его ID. Windows может определит действительно ли hMenu - это описатель меню или же ID, проверив парамет IpClassName. Если это имя предопределенного класса, hMenu - это идентификатс контрола. Если нет, это описатель меню окна. lilnstance - описатель программного модуля, создающего окно. IpParam - опциональный указатель на структуру данных, передаваемых окну. Испол зуется окнами MDI, чтобы передать структуру CLIENTCREATESTRUCT. Обычно эт параметр устанавливается в NULL, означая, что никаких данных через CreateWindov не передается. Процедура окна может получить значение этого параметра посредств( вызова функции GetWindowsLong. После создания окна вызовом CreateWindowEx возвращенный его описатель coxpaj ется для дальнейшего манипулирования окном. Следующий вызов CreateDialogParam заполняет наше вновь созданное окно элем( тами взаимодействия с пользователем, превращая его в диалоговое. Эта функция по; чает 5 параметров: описатель модуля, создающего окно, шаблон диалогового окна (oi сание элементов содержится в файле ресурсов mdS.rc), описатель окна, которо принадлежат элементы диалога, адрес функции, обрабатывающей события от элемен-управления диалога, и - 32-битная константа, которая передается функции обрабо-сообщений диалога вместе с сообщением WMINITDIALOG в параметре IParam. Итак, как видно из текста профаммы mdS.asm, функция ChildDlgProc должна по чать и обрабатывать все сообщения элементов диалогового окна. В случае успешного завершения создания окна диалога его описатель сохраняе для возможности дальнейшей работы с его сообщениями и вызовом ShowWindow окно впервые отображается на экране компьютера. Сейчас следует немного отойти в сторону от исследования кода приложения mdj и рассмотреть его файл ресурсов md5.rc, чтобы получить ответ на вопрос, каким образом вызов CreateDialogParam наполнил наше окно элементами диалога. ; md5.ГС
flSCAPIT MENU BEGIN POPUP "SFile" BEGIN MENUITEM "ESxit", POPUP "SHelp" BEGIN MENUITEM "SAbout...", IDM FILE EXIT IDM HELP ABOUT IDD CHILD DLG DIALOG DISCARDABLE 0, 0, 309, 95 STYLE DS 3DL00K I WS VISIBLE I WS CHILD FONT 8,"MS Sans Serif" BEGIN EDITTEXT IDC INPUT EDIT, 48,7,222,14, ES AUTOHSCROLL WS TABGRP EDITTEXT IDC OUTPUT EDIT, 4 8,24,222,14, ES AUTOHSCROLL WS TABGRP I WS DISABLED PUSHBUTTON PUSHBUTTON WS TABGRP LTEXT LTEXT 7,10,40,8 "Run", IDC GO BUTTON, 167,41,50,14, WS TABGRP "Exit", IDC EXIT BUTTON, 2 2 0,41,50,14, "MD5 hash:", "Input string:". IDC STATIC, 7,27,40, IDC STATIC, Ресурсы для приложений Windows создаются отдельно от файлов текста профаммы и добавляются в результирующий исполняемый модуль на этапе линковки. Подавляющее большинство описаний различных ресурсов содержится в специальных файлах ресурсов, имеющих расширение .RC. Имя файла ресурсов обычно совпадает с именем исполняемого файла профаммы. В нашем случае это mdS.rc. Некоторые типы ресурсов, такие, как меню, диалоги, описываются на специальном языке. Другие ресурсы, например иконки, курсоры, изображения, тоже описываются в текстовом виде, но часть их описания является последовательностью шестнадцатирич-Hbix цифр. Обычно для создания ресурсов пользуются специальными средствами -редакторами ресурсов. Они позволяют создавать ресурсы, визуально контролировать правильность их создания, после чего сохранять их в формате файла ресурсов. Часто используется "смешанный" способ редактирования ресурсов. Например, при визуальном редактировании диалоговых окон достаточно фудно точно установить эле- менты диалогового окна. После приблизительной расстановки визуальными средствам, и сохранения в соответствующем файле осуществляется редактирование параметре элементов в RC-файле в обычном текстовом редакторе. Среда разработки RadASM рас, полагает средствами визуального редактирования ресурсов приложений, доступными меню Project/Add New и имеет соответствующий режим создания диалоговых окон, меню, идентификаторов ресурсов. При создании RC-файлов программист сталкивается с тем, что некоторые ресурсы такие, как иконки, курсоры, диалоговые окна, изображения (bitmapbi), могут быть сохранены в отдельных файлах с расщирениями .ico, .cur, .dig, .bmp, соответственно. В этом случае в RC-файлах делаются ссылки на упомянутые файлы посредством директивы include. Анализ файла md5.rc показьшает, что интерфейс программы, кроме непосредственно окна Windows, состоит из системного меню и диалога с несколькими элементами управления: полями редактирования, статического текста и кнопок. Описание синтаксиса RC-файла можно найти в библиотеке разработчика MSDN. Каждому элементу управления сопоставлены численные идентификаторы для ссылки на них в вызовах обработки сообщений. Файл ресурсов для размещения последних в исполняемом модуле должен быть откомпилирован специальным компилятором ресурсов (среда RadASM делает это автоматически при наличии файла ресурсов в проекте). Для этого в нашем случае вызывается утилита RC.EXE из пакета MASM32. После компиляции файла ресурсов компилятором ресурсов создается новый файл, имеющий расщирение .RES. Именно этот RES-файл используется линковщиком для добавления ресурсов в результирующий исполняемый модуль. Следует отметить, что при необходимости RES-файлы могут создаваться и редакторами ресурсов. Выбор пути получения готовых ресурсов зависит от предпочтений разработчика. Вернемся снова к обсуждению исходного текста программы md5. После отображения основного окна программы необходимо запустить так называемый цикл обработки сообщений для возможности отбора, трансляции и передачи оконной процедуре событий, происходящих с соответствующими элементами управления. msg loop: invoke PeekMessage,offset message,0,0,0,PM REMOVE or jz ax, ax no message invoke IsDialogMessage,[child dlg handle],offset message or eax,eax jnz no message cmp message.message,WM QUIT je end loop invoke TranslateMessage,offset message invoke DispatchMessage,offset message rc message: jmp msg loop Bo время работы приложения Windows не отправляет поток вводимых данных непосредственно ему. Вместо этого, она помещает все события мыши и клавиатуры, элементов управления в общую очередь сообщений. Приложение должно самостоятельно считывать данные из этой очереди; извлекать сообщения и распределять их так, чтобы оконная процедура могла их обработать. функция PeekMessage проверяет, есть ли в очереди сообщений "что-либо подходящее", и, если есть, извлекает сообщение из очереди в заданную структуру (в нашем случае - message). CreateWindowEx proto IpMsg:DWORD,\ hWnd:DWORD,\ wMsgFilterMin:DWORD, \ wMsgFilterMax:DWORD,\ wRemoveMsg:DWORD,\ IpMsg - указатель на структуру MSG, которая принимает информацию из очереди сообщений потока. hWnd - описатель окна, чьи сообщения должны быть извлечены. Окно должно принадлежать вызывающему потоку. Значение ПУСТО (NULL) имеет специальное предназначение: wMsgFilterMin - определяет целочисленную величину идентификатора самого маленького значения сообщения, которое будет извлечено. Используйте сообщение WMKEYFIRST, чтобы задать первое сообщение клавиатуры, или WM MOUSEFIRST, чтобы задать первое сообщение мыши. wMsgFilterMax - определяет целочисленную величину самого большого значения сообщения, которое будет извлечено. Используйте сообщение WMKEYLAST, чтобы задать первое сообщение клавиатуры, или WM MOUSELAST, чтобы задать последнее сообщение мыши. Если wMsgFilterMin и wMsgFilterMax являются оба нулевыми, функция PeekMessage возвращает все доступные сообщения, т. е. никакой фильтрации в диапазоне значений не выполняется. wRemoveMsg - в зависимости от значений (PMNOREMOVE или PMREMOVE) определяет, следует ли копию извлеченного сообщения отставить в системной очереди или нет. Если функция PeekMessage успешно извлекает какое-либо сообщение, не WMQUIT, величина возвращаемого значения не нуль. Если функция извлекает сообщение QUIT, величина возвращаемого значения - нуль. Вызов IsDialogMessage определяет, предназначено ли данное сообщец( для диалогового окна и если да, то соответствующая оконная функшм обрабатывает ег; В ходе выполнения функции IsDialogMessage Windows проверяет, есть ли в окц с указанным описателем элементы управления вообще, и если они есть, то выполняет последовательная посылка ряда сообщени!! им для смены текущего элемента yпpaвлeн при нажатии комбинаций клавищ смены фокуса. В случае если оконная функция возвратила О, а следовательно, и IsDialogMessa вернет это значение, т. е. сообщение было успешно обработано, дальнейшее процессир вание его должно быть прекращено. В случае ненулевого возврата происходит дальне, шая обработка вызовами TranslateMessage и DispatchMessage. Функция TranslateMessage переводит сообщения виртуальных клавиш в символьн! сообщения, которые помещаются в системную очередь сообщений вызывающего пото для прочтения на следующей итерации цикла обработки сообщений. Функция DispatchMessage отправляет каждое оттранслированное сообщение соотве ствующей оконной процедуре. Принимающей оконной процедурой в нашем случае яв; ется WindowProc. Итак, все сообщения диалогового интерфейса (поля ввода, шот обрабатываются функцией ChildDlgProc, а команды манипулирования главным окн программы и системного меню - WindowProc. Рассмотрим, как происходит обработка манипуляций оконной функцией WindowPr Каждая оконная процедура получает сообщения системы посредством выз( DispatchMessage в цикле обработки сообщений. Это могут быть сообщения управлй окном или сообщения о вводе данных. Необязательно обрабатывать каждое сообще! в своей оконной процедуре, его можно переправлять системе для обработки по умолчан! при помощи вызова функции DefWindowProc. Сообщения, требующие обязательной об ботки, имеют идентификаторы WMPAINT, WM COMMAND и WMDESTROY. Что такое сообщение оконной функции? Сообщение оконной функции - это CTpyf pa типа MSG, возвращаемая из системной очереди сообщений одним из вызовов выб ки сообщений, возможно, оттранслированная и отправленная в качестве второго п; метра для оконной функции. MSG STRUCT Hwnd DWORD ? message DWORD ? wParam DWORD ? IParam DWORD ? time DWORD ? pt POINT <> MSG ENDS hwnd - описатель окна, оконная процедура которого принимает сообщение, message - определяет иденнтифткатор сообщения. Приложения могут использов- только младшее слово; старшее слово зарезервировано системой. гдазз 5. Программирование на ассемблере nog Windows wParam - определяет дополнительную информацию о сообщении. Точное значение зависит от значения члена структуры message. IParam - определяет дополнительную информацию о сообщении. Точное значение зависит от значения члена структуры message. time - определяет время, когда сообщение было помещено в очередь. pt - хранит позицию курсора в экранных координатах в момент, когда сообщение бьтпо помещено в очередь. Оконная функция нашей профаммы выглядит следующим образом.
about: «bon MessageBox, [main win handle], of f set about string, of f set title,MB OK 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 [ 55 ] 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |