
Функция TranslateAccelerator
Обрабатывает клавиши - ускорители для команд меню. Функция транслирует сообщение WM_KEYDOWN или WM_SYSKEYDOWN в сообщение WM_COMMAND или WM_SYSCOMMAND (если имеется элемент для клавиши в заданной таблице клавиш-ускорителей), а затем передает сообщение WM_COMMAND или WM_SYSCOMMAND непосредственно соответствующей оконной процедуре. TranslateAccelerator не возвращает значения до тех пор, пока оконная процедура не обработает сообщение.
Синтаксис
int TranslateAccelerator
(
HWND hWnd, // дескриптор окна назначения
HACCEL hAccTable, // дескриптор таблицы клавиш-ускорителей
LPMSG lpMsg // адрес структуры с сообщением
);
Параметры hWnd Идентифицирует окно, сообщения которого должны быть оттранслированы. hAccTable Идентифицирует таблицу клавиш-ускорителей. Таблица должна быть загружена при помощи вызова функции LoadAccelerators или создана вызовом функции CreateAcceleratorTable. lpMsg Указывает на структуру MSG, которая содержит информацию сообщения, извлеченного из очереди сообщений вызывающего потока при помощи использования функции GetMessage или PeekMessage.
Возвращаемые значения Если функция завершается успешно, величина возвращаемого значения - ИСТИНА (TRUE). Если функция не выполняет задачу, величина возвращаемого значения - ЛОЖЬ(FALSE). Чтобы получить дополнительные данные об ошибках, вызовите GetLastError.
Функция GetMessage
Эта функция извлекает сообщение из очереди. 29
BOOL GetMessage
(
LPMSG lpMsg, // указатель на структуру
HWND hWnd, // указатель окна чьи сообщения нужно обрабатывать
UINT wMsgFilterMin, // номер мимимального сообщения для выборки
UINT wMsgFilterMax // номер максимального сообщения для выборки
);
С помощью переменной hWnd есть возможность указать конкретное окно, от которого будет принято сообщение. Если установить это значение в NULL, то будут приниматься все сообщения. Возврат этой функции будет отличен от нуля пока не будет получено сообщение WM_QUIT
Функция DispatchMessage
Распределяет сообщение оконной процедуре. Обычно она используется, чтобы доставить сообщение, извлеченное функцией GetMessage.
Синтаксис
LRESULT DispatchMessage( const MSG* lpmsg );
Параметры
lpmsg
Указатель на структуру MSG, которая содержит сообщение.
Возвращаемое значение
Величина возвращаемого значения определяется значением, которое возвращает оконная процедура. Несмотря на то, что это значение зависит от отправляемого сообщения, возвращаемое значение, как правило, игнорируется.
Функция PostQuitMessage
Указывает системе, что поток сделал запрос на то, чтобы завершить свою работу (выйти). Это обычно используется в ответ на сообщение WM_DESTROY.
Синтаксис
void PostQuitMessage(
int nExitCode
);
Параметры 30
nExitCode
Определяет код завершения прикладной программы. Это значение используется как параметр wParam сообщения WM_QUIT.
Возвращаемые значения
Возвращаемых значений нет.
Функция CreateDialogParam
Создает немодальное диалоговое окно из шаблона ресурса блока диалога. Перед показом диалогового окна на экране, функция отправляет в процедуру блока диалога определяемое программой значение сообщения WM_INITDIALOG, как параметр lParam. Прикладная программа может использовать это значение, чтобы инициализировать элементы управления диалогового окна.
Синтаксис
HWND CreateDialogParam
(
HINSTANCE hInstance, // дескриптор экземпляра программы
LPCTSTR lpTemplateName, // идентификация шаблона блока диалога
HWND hWndParent, // дескриптор окна владельца
DLGPROC lpDialogFunc, // указатель на процедуру диалогового окна
LPARAM dwInitParam // инициализационное значение
);
Параметры hInstance Идентифицирует экземпляр модуля, исполняемый файл которого содержит шаблон диалогового окна. lpTemplateName Идентифицирует шаблон диалогового окна. Этот параметр - или указатель на строку символов с нуль-терминатором в конце, которая определяет имя шаблона диалогового окна, или целочисленное значение, которое определяет идентификатор ресурса шаблона блока диалога. Если параметр определяет идентификатор ресурса, его старшее слово должно быть нулевым, а младшее слово должно содержать идентификатор. Вы можете использовать макрокоманду MAKEINTRESOURCE, чтобы создать это значение. hWndParent Идентифицирует окно, которое владеет блоком диалога. lpDialogFunc 31
Указывает на процедуру диалогового окна. За большей информацией о процедуре диалогового окна обратитесь к статье DialogProc dwInitParam Устанавливает значение, передаваемое процедуре диалогового окна в параметре lParam сообщения WM_INITDIALOG.
Возвращаемые значения Если функция завершилась успешно, возвращается значение дескриптор окна блока диалога. Если функция потерпела неудачу, возвращается значение ПУСТО (NULL).
Функция DestroyWindow
function DestroyWindow(Wnd: HWnd): Bool; Уничтожает окно или блок безpежимного диалога и все связанные с ним дочеpние окна.
Параметры:
Wnd: Идентификатор окна.
Возвращаемое значение:
В случае успешного завершения - не нуль; 0 - в противном случае.
Функция TranslateMessage
Эта функция переводит сообщения формата виртуальных клавиш в сообщения символы.
BOOL TranslateMessage
(
CONST MSG *lpMsg // структура с информацией о сообщении
);
lpMsg - это структура полученная в результате вызова функций GetMessage() или PeekMessage().
Функция вернет значение отличное от нуля в случае, если перевод произведен. Если сообщение типа WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, или WM_SYSKEYUP, то возвращаемое значение всегда отличное от нуля. 32
Функция LoadCursor
загружает заданный ресурс курсора из (.EXE) файла выполняемой программы, связанной с экземпляром прикладной программы.
Синтаксис
HCURSOR LoadCursor
(
HINSTANCE hInstance, // дескриптор экземпляра приложения
LPCTSTR lpCursorName // идентификатор названия строки или ресурса курсора
);
Параметры hInstance Идентифицирует экземпляр модуля, исполняемый файл которого содержит курсор, который будет загружен. lpCursorName Указывает на строку с символом нуля в конце, содержащую имя ресурса курсора, который будет загружен. Или же, этот параметр может состоять из идентификатора ресурса, в младшем слове и нуля в старшем слове. Может также использоваться макрокоманда MAKEINTRESOURCE, чтобы создать это значение. Чтобы использовать предопределенный курсор Win32, прикладная программа должна установить параметр hInstance в значение ПУСТО (NULL), а параметр lpCursorName в одно из следующих значений:
IDC_APPSTARTING - Стандартная стрелка и маленькие песочные часы
IDC_ARROW - Стандартная стрелка
IDC_CROSS - Перекрестие
IDC_IBEAM - I-прямая вертикальная линия для текста
IDC_ICON - Только для Windows NT: Пустая иконка
IDC_NO - Перечеркнутый круг
IDC_SIZE - Только для Windows NT: Четырех направленная стрелка
IDC_SIZEALL - Подобно IDC_SIZE
IDC_SIZENESW - Двунаправленная стрелка, указывающая северо-восток и юго-запад
IDC_SIZENS - Двунаправленная стрелка, указывающая север и юг
IDC_SIZENWSE - Двунаправленная стрелка, указывающая северо-запад и юго-восток
IDC_SIZEWE - Двунаправленная стрелка, указывающая запад и восток
IDC_UPARROW - Вертикальная стрелка
IDC_WAIT - Песочные часы
33
Возвращаемые значения Если функция завершается успешно, возвращаемое значение - дескриптор недавно загруженного курсора. Если функция не выполняет задачу, возвращаемое значение ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError
Демонстрационная программа
Листинг:
Файл menu1.inc:
; файл menu1.inc
; константы
; сообщение приходит при закрытии окна
WM_CLOSE equ 10h
WM_INITDIALOG equ 110h
WM_SETICON equ 80h
WM_COMMAND equ 111h
WM_SETCURSOR equ 20h
; прототипы внешних процедур
EXTERN ShowWindow@8:NEAR
EXTERN MessageBoxA@16:NEAR
EXTERN ExitProcess@4:NEAR
EXTERN GetModuleHandleA@4:NEAR
EXTERN LoadIconA@8:NEAR
EXTERN LoadMenuA@8:NEAR
EXTERN SendMessageA@16:NEAR
EXTERN SetMenu@8:NEAR
EXTERN LoadAcceleratorsA@8:NEAR
EXTERN TranslateAcceleratorA@12:NEAR
EXTERN GetMessageA@16:NEAR
EXTERN DispatchMessageA@4:NEAR
EXTERN PostQuitMessage@4:NEAR
EXTERN CreateDialogParamA@20:NEAR
EXTERN DestroyWindow@4:NEAR
EXTERN TranslateMessage@4:NEAR
EXTERN LoadCursorA@8:NEAR
; структуры
; структура сообщения
MSGSTRUCT STRUC
MSHWND DD ?
MSMESSAGE DD ?
MSWPARAM DD ?
MSLPARAM DD ?
MSTIME DD ?
MSPT DD ?
MSGSTRUCT ENDS
Файл rs.rc:
// файл menu1.rc
// определение констант
#define WS_SYSMENU 0x00080000L
#define WS_MINIMIZEBOX 0x00020000L
#define WS_MAXIMIZEBOX 0x00010000L
#define WS_POPUP 0x80000000L
#define VK_F1 0x70
#define VK_F2 0x71
#define VK_F3 0x72
#define VK_F4 0x73
#define VK_F5 0x74
#define VK_F6 0x75
#define VK_F7 0x76
#define VK_F8 0x77
#define st WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
MENUP MENU
{
POPUP "&Первая группа ресурсов"
{
MENUITEM "&1) Иконки", 1
MENUITEM SEPARATOR
MENUITEM "&2) Курсоры", 2
MENUITEM SEPARATOR
MENUITEM "&3) Битовые картинки",3
MENUITEM SEPARATOR
MENUITEM "&4) Строки",4
MENUITEM SEPARATOR
MENUITEM "&5) Диалоговые окна",5
MENUITEM SEPARATOR
}
POPUP "&Вторая группа ресурсов"
{
MENUITEM "&1) Меню",6
MENUITEM SEPARATOR
MENUITEM "&2) Акселераторы",7
MENUITEM SEPARATOR
POPUP "Еще подмен&ю"
{
MENUITEM "Десятый пунк&т",8
}
}
MENUITEM "Вы&ход",10
}
// идентификаторы
#define IDI_ICON1 1
#define IDI_CUR1 2
// определили иконку
IDI_ICON1 ICON "ico1.ico"
IDI_CUR1 CURSOR "arrow_il.cur"
// определение диалогового окна
DIAL1 DIALOG 100, 100, 340, 220
STYLE WS_POPUP | st
CAPTION "Пример Курсовой работы по Операционным системам"
FONT 14, "TimeNewRoman"
{
}
MENUP ACCELERATORS
{
VK_F1, 1, VIRTKEY, ALT
VK_F2, 2, VIRTKEY, ALT
VK_F3, 3, VIRTKEY, ALT
VK_F4, 4, VIRTKEY, ALT
VK_F5, 5, VIRTKEY, ALT
VK_F6, 6, VIRTKEY, ALT
VK_F7, 7, VIRTKEY, ALT
}
Файл menu1.asm:
;файл menu1.asm
.386P
; плоская модель
.MODEL FLAT, stdcall
include menu1.inc
; директивы компоновщику для подключения библиотек
includelib user32.lib
includelib kernel32.lib
IDC_CROSS equ 32515
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
NEWHWND DD 0
MSG MSGSTRUCT <?>
HINST DD 0 ; дескриптор приложения
PA DB "DIAL1",0
PMENU DB "MENUP",0
STR1 DB "Выход из программы",0
STR2 DB "Сообщение",0
STR11 DB "Иконка (от англ. icon) — элемент графического интерфейса, небольшая картинка, представляющая приложение, файл, каталог, окно, компонент операционной системы, устройство", 0
STR12 DB "Курсор (указатель мыши) (англ. cursor — указатель, стрелка прибора) — экранная пометка, показывающая место на экране, где появится следующий символ ", 0
STR13 DB "BMP (от англ. Bitmap Picture) — формат хранения растровых изображений, разработанный компанией Microsoft. Кроме этого, структуры из этого формата используются некоторыми WinAPI-функциями подсистемы GDI. ", 0
STR14 DB " Строковый тип (англ. string «нить, вереница») — тип данных, значениями которого является произвольная последовательность (строка) символов алфавита. ", 0
STR15 DB "Диалоговое окно (англ. dialog box) — в графическом пользовательском интерфейсе специальный элемент интерфейса, окно, предназначенное для вывода информации и (или) получения ответа от пользователя. ", 0
STR21 DB "Меню системы. Оно является центральной отправной точкой для запуска программ, а также открытия недавних документов и доступа к свойствам системы", 0
STR22 DB "Клавиатурный акселератор - это функциональная клавиша или последовательность клавиш, которые оператор может нажимать для исполнения команды элемента меню. ", 0
ACC DWORD ?
_DATA ENDS
; сегмент кода
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
START:
; получить дескриптор приложения
PUSH 0
CALL GetModuleHandleA@4
MOV [HINST], EAX
; загрузить акселераторы
PUSH OFFSET PMENU
PUSH [HINST]
CALL LoadAcceleratorsA@8
MOV ACC, EAX ; запомнить дескриптор таблицы
; создать немодальный диалог
PUSH 0
PUSH OFFSET WNDPROC
PUSH 0
PUSH OFFSET PA
PUSH [HINST]
CALL CreateDialogParamA@20
; визуализировать немодальный диалог
MOV NEWHWND, EAX
PUSH 1 ; SW_SHOWNORMAL
PUSH [NEWHWND]
CALL ShowWindow@8 ; показать созданное окно
; кольцо обработки сообщений
MSG_LOOP:
PUSH 0
PUSH 0
PUSH 0
PUSH OFFSET MSG
CALL GetMessageA@16
CMP EAX, 0
JE END_LOOP
; транслировать сообщение акселератора
PUSH OFFSET MSG
PUSH [ACC]
PUSH [NEWHWND]
CALL TranslateAcceleratorA@12
CMP EAX,0
JNE MSG_LOOP
PUSH OFFSET MSG
CALL TranslateMessage@4
PUSH OFFSET MSG
CALL DispatchMessageA@4
JMP MSG_LOOP
END_LOOP:
PUSH 0
CALL ExitProcess@4
; процедура окна
; расположение параметров в стеке
; [EBP+014Н] LPARAM
; [EBP+10H] WAPARAM
; [EBP+0CH] MES
; [EBP+8] HWND
WNDPROC PROC
PUSH EBP
MOV EBP,ESP
PUSH EBX
PUSH ESI
PUSH EDI
;-------------------------
CMP DWORD PTR [EBP+0CH],WM_CLOSE
JNE L1
; закрыть диалоговое окно
JMP L5
L1:
CMP DWORD PTR [EBP+0CH],WM_INITDIALOG
JNE L3
; загрузить иконку
PUSH 1 ; идентификатор иконки
PUSH [HINST] ; идентификатор процесса
CALL LoadIconA@8
; установить иконку
PUSH EAX
PUSH 1 ; тип иконки (маленькая)
PUSH WM_SETICON
PUSH DWORD PTR [EBP+08H]
CALL SendMessageA@16
; загрузить меню
PUSH OFFSET PMENU
PUSH [HINST]
CALL LoadMenuA@8
; установить меню
PUSH EAX
PUSH DWORD PTR [EBP+08H]
CALL SetMenu@8
;-----------------------------
MOV EAX, 1 ; возвратить не нулевое значение
JMP FIN
; проверяем, не случилось ли чего с управляющими
; элементами на диалоговом окне
L3:
CMP DWORD PTR [EBP+0CH],WM_COMMAND
JE L6
JMP FINISH
; здесь определяем идентификатор, в данном случае
; это идентификатор пункта меню сообщение
L6:
CMP WORD PTR [EBP+10H], 1
JNE L7
PUSH 0 ; MB_OK
PUSH OFFSET STR2
PUSH OFFSET STR11
PUSH 0
CALL MessageBoxA@16
JMP FINISH
L7:
CMP WORD PTR [EBP+10H], 2
JNE L8
PUSH 0 ; MB_OK
PUSH OFFSET STR2
PUSH OFFSET STR12
PUSH 0
CALL MessageBoxA@16
JMP FINISH
L8:
CMP WORD PTR [EBP+10H], 3
JNE L9
PUSH 0 ; MB_OK
PUSH OFFSET STR2
PUSH OFFSET STR13
PUSH 0
CALL MessageBoxA@16
JMP FINISH
L9:
CMP WORD PTR [EBP+10H], 4
JNE L10
PUSH 0 ; MB_OK
PUSH OFFSET STR2
PUSH OFFSET STR14
PUSH 0
CALL MessageBoxA@16
JMP FINISH
L10:
CMP WORD PTR [EBP+10H], 5
JNE L21
PUSH 0 ; MB_OK
PUSH OFFSET STR2
PUSH OFFSET STR15
PUSH 0
CALL MessageBoxA@16
JMP FINISH
L21:
CMP WORD PTR [EBP+10H], 6
JNE L22
PUSH 0 ; MB_OK
PUSH OFFSET STR2
PUSH OFFSET STR21
PUSH 0
CALL MessageBoxA@16
JMP FINISH
L22:
CMP WORD PTR [EBP+10H], 7
JNE L4
PUSH 0 ; MB_OK
PUSH OFFSET STR2
PUSH OFFSET STR22
PUSH 0
CALL MessageBoxA@16
JMP FINISH
L4:
CMP WORD PTR [EBP+10H], 10
JNE FINISH
; сообщение
PUSH 0 ; MB_OK
PUSH OFFSET STR2
PUSH OFFSET STR1
PUSH 0
CALL MessageBoxA@16
; закрыть диалоговое немодальное окно
L5:
PUSH DWORD PTR [EBP+08H]
CALL DestroyWindow@4
; послать сообщение для выхода из кольца
; обработки сообщений
PUSH 0
CALL PostQuitMessage@4 ; сообщение WM_QUIT
FINISH:
MOV EAX, 0
FIN:
POP EDI
POP ESI
POP EBX
POP EBP
RET 16
WNDPROC ENDP
_TEXT ENDS
END START
Файл menu1.bat:
ml /c /Cp /Gz /coff /nologo %menu1.asm
rc %rs.rc
link /subsystem:windows %menu1.obj rs.RES
pause
Демонстрация
работы:
Вывод
В ходе выполнения курсовой работы самостоятельно были изучены основы программирования на 32-битном ассемблере. Составлена программа на языке ассемблера для 32 разрядных микропроцессоров семейства Intel, демонстрирующая применение макросредств в ассемблере.
Литература:
1. Пирогов Владислав Юрьевич. Ассемблер для Windows. — М.: Издатель Молгачева С.В., 2002. —552 с., ил.
2. http://netcode.ru/cpp
3. Методические указания для выполнения курсовой работы «Изучение операционной системы Windows» по курсу «Операционные системы»
для студентов специальности 23.01.00 «Вычислительные машины, комплексы, системы и сети»
Программное обеспечение:
1. Microsoft (R) Macro Assembler 32 SDK.