Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Полученный дескриптор hMenu можно указать в качестве девятого параметра функции CreateWindow:
invoke CreateWindow, ... , hMenu, ...
mov hWnd, EAX
Здесь необходимо отметить очень важный момент. При указании меню в вызове функции CreateWindow любое другое меню, заданное в классе окна, становится недоступным.
Можно также указать вместо меню NULL при регистрации класса окна и при вызове функции CreateWindow, а затем присоединить меню к окну при помощи вызова функции WIN API setMenu. Функция setMenu имеет следующий синтаксис:
BOOL SetMenu(HWND hWnd, //дескриптор окна
HMENU hMenu //дескриптор меню
) ;
Следующий фрагмент программного кода назначает окну hwnd меню с дескриптором hMenu:
push hMenu
push hWnd
call SetMenu

Такая форма позволяет использовать несколько меню в одном приложении окна. Следует отметить, что любое меню, назначенное окну, удаляется при удалении окна. Не связанное с окном меню перед завершением работы программы нужно удалять при помощи вызова функции DestroyMenu. Поясню это на маленьком примере.
Пусть мы назначили окну с дескриптором hWnd меню, дескриптор которого находится в переменной hMenui:
push hMenui
push hWnd
call SetMenu

Предположим, в программе нужно переопределить для окна приложения другое меню, например с дескриптором hMenu2. Это можно сделать, используя предыдущий фрагмент кода:
push hMenu2
push hWnd
call SetMenu

Эти команды отсоединяют от окна ранее назначенное меню hMenui, но не уничтожают его. При закрытии окна приложения будет уничтожено только меню hMenu2, а меню с дескриптором hMenui останется в памяти. Для удаления hMenui необходимо вызвать функцию DestroyMenu, Принимающую В качестве параметра дескриптор меню:
DestroyMenu(hMenui)

Теперь перейдем к рассмотрению основных примеров программ. В нашем первом примере будет присутствовать главное меню из двух пунктов и выпадающее меню, состоящее из трех пунктов. Это отображено в файле описания ресурсов, который назовем rsrc.rc:
#define IDM_WHITE 1
#define IDM_BLACK 2
#define IDM_BLUE 3
#define IDM_TITLE 4
MenuDemo MENU
{
POPUP "&BACKGROUND"
{
MENUITEM "&WHITE BRUSH", IDM_WHITE
MENUITEM "&BLACK BRUSH", IDM_BLACK
MENUIТЕМ SEPARATOR
MENUITEM "B&LUE BRUSH", IDM_BLUE
}
MENUITEM "&TITLE", IDM_TITLE
}
Каждый пункт главного и выпадающего меню описывается инструкцией MENUITEM с названием текстовой строки и идентификатора пункта меню. При выборе пункта выпадающего меню цвет фона клиентской области окна будет меняться, а если выбран пункт главного меню TITLE, ТО будет изменен заголовок приложения. Исходный текст программы (назовем ее MENUEX) приведен в листинге 5.21.
Листинг 5.21. Программа, демонстрирующая работу с меню
.386
.model flat, stdcaii
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO .-DWORD, :DWORD, : DWORD, : DWORD
szDisplayName DB "ДЕМОНСТРАЦИЯ РАБОТЫ С МЕНЮ", О
CommandLine DD О
MENUEX.ASM
. data
hWnd DD 0
hlnstance 'DD 0
szClassName DB "Demo_Class", 0
AppName DB "MyApp", 0
MenuName DB "MenuDemo' 0
bkColor
wColor DB "ЦВЕТ ФОНА ПОМЕНЯЕТСЯ HA БЕЛЫЙ!", О
DB "ЦВЕТ ФОНА ПОМЕНЯЕТСЯ НА ЧЕРНЫЙ!", О
Программирование на ассемблере в Windows: от простого к сложному 365
blColor DB "ЦВЕТ ФОНА ПОМЕНЯЕТСЯ НА ГОЛУБОЙ!", О
sTitle DB "ЗАГОЛОВОК ОКНА ПОМЕНЯЕТСЯ!", О
toggle DD О
sEng DB "WINDOWS APPLICATION", 0
sRus DB "ПРИЛОЖЕНИЕ WINDOWS", 0
.const
IDM_WHITE EQU 1
IDM_BLACK EQU 2
IDM_BLUE EQU 3
IDM TITLE EQU 4
push SW_SHOWDEFAULT
push CommandLine
push NULL
push hlnstance
call WinMain
push EAX
call ExitProcess
WinMain proc hlnst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD

Локальные переменные процедуры
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG

Заполнение структуры WNDCLASSEX требуемыми параметрами
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hlnst
pop wc.hlnstance
mov wc.hbrBackground, COLOR_BTNFACE+1
mov wc.IpszMenuName, offset MenuName
mov wc.IpszClassName, offset szClassName
push IDI_APPLICATION
push NULL
call Loadlcon'
mov wc.hlcon, EAX
push IDC_ARROW
push NULL
call LoadCursor
mov wc.hCursor, EAX
mov wc.hlconSm, 0
lea EAX, wc
push EAX
call RegisterClassEx
push NULL ^
push hlnst
push NULL
push NULL
push CW_USEDEFAULT
push CWJJSEDEFAULT
push CWJJSEDE FAULT
push CWJJSEDEFAULT
push WS_OVERLAPPEDWINDOW
push offset szD'isplayName
push offset szClassName
push WS_EX_OVERLAPPEDWINDOW
call CreateWindowEx
mov hWnd, EAX
push SW_SHOWNORMAL
push hWnd
push hWnd
call UpdateWindow

Цикл обработки сообщений
StartLoop:
push 0
push 0
push NULL
lea EAX, msg
push EAX
call GetMessage
cmp EAX, 0
je ExitLoop
lea EAX, msg
push EAX
call TranslateMessage
lea EAX, msg
push EAX
call DispatchMessage
jmp StartLoop
ExitLoop:
mov EAX, msg.wParam
ret
WinMain endp

Оконная процедура
WndProc proc hWin :DWORD,
call ShowWindow
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
LOCAL hdc
LOCAL ps
LOCAL rect
LOCAL hBrush
:HDC
:PAINTSTRUCT
:RECT
:HBRUSH
cmp uMsg,WM_COMMAND
jne next_l
mov EAX, wParam
cmp AX, IDM_WHITE
jne check_black
invoke MessageBox, NULL, ADDR wColor, offset AppName, MB_OK
mov hBrush, COLOR_WINDOW+l
jmp fill_rect
check_black:
cmp AX,IDM_BLACK
jne check_blue v
invoke MessageBox, NULL, ADDR bkColor, offset AppName, MB_OK
mov hBrush, C0L0R_WIND0W+3
jmp fill_rect
check_blue:
cmp AX,IDM_BLUE
jne check_title
invoke MessageBox, NULL, ADDR blColor, offset AppName, MB_0K
mov hBrush, C0L0R_WIND0W-3
jmp fill_rect
check title:
cmp AX, IDM_TITLE
jne ex wmsys
invoke MessageBox, NULL, ADDR sTitle, offset AppName, MB_0K
cmp toggle, 0
je chEng
push offset sRus
push hWin
call SetWindowText
jmp rev_flag
chEng:
push offset sEng
push hWin
call SetWindowText
rev flag:
not toggle
ex wmsys:
ret
next_l:
cmp uMsg, WM_DESTROY
jne next_2
push NULL
call PostQuitMessage
xor EAX, EAX
ret
next 2:
push lParam
push wParam
push uMsg
push hWin
call DefWindowProc
ret
fill_rect;
push hWnd
call GetDC
mov hdc, EAX
lea ESI,rect
push ESI
push hWnd
call GetClientRect
push hBrush
lea ESI, rect
push ESI
370 Глава 5
push hdc
call FillRect
push
push
hdc
hWnd
call ReieaseDC
ret
WndProc endp


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru