Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Ассемблер? Это просто! Учимся программировать


Информационный Канал Subscribe.Ru


Ассемблер под Windows №6

Меню в среде Windows


Доброго времени суток, уважаемые подписчики. Сегодня мы обсудим две достаточно важные, для программирования под Windows, темы. В принципе мы рассмотрим одну тему, меню, просто меню это часть так называемых ресурсов программы. Они то и будут нашей второй темой.


Внимание! Все материалы этой рассылки, написанные до 25 августа 2002 года были написаны не мной, а Калашниковым Олегом (admin@RusFAQ.ru). Я начал писать с первого выпуска "Программирование под Windows". Просьба все письма связанные с выпусками рассылки до 25-ого числа посылать ему.


В начале, по традиции, немного теории. Windows во многом упрощает нам работу программ, он берёт на себя практически все заботы об обслуживанию нашего окна, предлагает нам диалоги типа MessageBox... Ещё одна очень полезная вещь, это так называемые ресурсы. Нам достаточно записать лишь параметры нужных нам объектов в файл ресурсов, а Windows берёт на себя задачу создания соответствующих объектов и их обработки. Один из объектов ресурсов, он же наиболее часто используемый, меню. Все ресурсы наиболее удобно писать в редакторе ресурсов, например в Borland Workshop, ( Распаковывется при помощи WinRar3 + лекарство ) однако структура меню настолько легка, что её легче сделать вручную! Для этого надо создать файл расширения .rc , давайте создадим menu.rc, и записать в него следующие:

#defineIDM_TEST 0
#defineIDM_OPEN 1
#defineIDM_SAVE 2
#defineIDM_EXIT 3
IDM_MENUMENU {
POPUP"&Файл" {
MENUITEM "&Сохранить",IDM_SAVE
MENUITEM "&Загрузить",IDM_OPEN
MENUITEM SEPARATOR
MENUITEM "Вы&ход",IDM_EXIT
}
MENUITEM "&Тест",IDM_TEST
}

Прежде чем идти дальше давайте разберёмся, что же мы записали. Заранее хочу предупредить, что файлы ресурсов пишутса не на ассемблере, именно поэтому я и советую работать с редактором ресурсов. Итак, первые четыре строчки равны следующим строкам на ассемблере: IDM_TEST equ 1 IDM_OPEN equ 2 IDM_SAVE equ 3 IDM_EXIT equ 4 , то есть мы создаём условные значения, которые при компиляции заменяются их реальными значениями. Следующйё строкой мы объявляем меню с именем IDM_MENU, объявляем одну подменю, в которой находится три пункта и разделительная полоса. и ещё одну кнопку в меню.

А теперь давайте добавим информацию о меню в window.asm:

IDM_TESTequ0
IDM_OPENequ1
IDM_SAVEequ2
IDM_EXITequ3
includedef32.inc
includeuser32.inc
include kernel32.inc
.386
.modelflat
.const
classdb"window class 1",0
name_db"Da window!",0
suredb"Предупреждение",0
askdb"Вы уверены, что хотите выйти?",0
menu_namedb'IDM_MENU',0
save_msgdb'Вы выбрали пункт Сохранить',0
open_msgdb'Вы выбрали пункт Открыть',0
test_msgdb'Вы выбрали пункт Тест',0
.data
wcwndclassex<4*12,cs_hredraw or cs_vredraw,offset win_proc,0,0,?,?,?, color_window+1,0,offset class,0>
.data?
msg_msg<?,?,?,?,?,?>
.code
_start:
xorebx,ebx
pushebx
callGetmodulehandle
movesi,eax
movdword ptr wc.hInstance,eax
pushIDI_Application
pushebx
callloadicon
movwc.hIcon,eax
pushidc_arrow
pushebx
callLoadCursor
movwc.hCursor,eax
pushoffset wc
callregisterclassEx
pushoffset menu_name
pushesi
callLoadMenu
movecx,CW_usedefault
pushebx
pushesi
pusheax;Это не новая строка!
pushebx
pushecx
pushecx
pushecx
pushecx
pushws_overlappedwindow
pushoffset name_
pushoffset class
pushebx
callcreatewindowex
pusheax
pushsw_shownormal
pusheax
callshowwindow
callupdatewindow
movedi,offset msg_
main_:
pushebx
pushebx
pushebx
pushedi
callGetmessage
testeax,eax
jzexit_
pushedi
calltranslatemessage
pushedi
calldispatchmessage
jmpmain_
exit_:
pushebx
callexitprocess
win_procproc
pushebp
movebp,esp
wp_hWndequdword ptr [ebp+08h]
wp_uMsgequdword ptr [ebp+0Ch]
wp_wParamequdword ptr [ebp+10h]
wp_lParamequdword ptr [ebp+14h]
cmpwp_uMsg,wm_close
jnenot_close
pushMB_YesNo
pushoffset sure
pushoffset ask
push0
callMessageBox
cmpeax,IDYES
jenot_close
xoreax,eax
jmpnot_
not_close:
cmpwp_uMsg,wm_destroy
jnenot_
push0
callpostquitmessage
jmpend_
not_:
cmpwp_uMsg,WM_COMMAND
jnenot_all
moveax,wp_wParam
jmpdword ptr menus[eax*4]
menusddoffset menu_test
ddoffset menu_open
ddoffset menu_save
ddoffset menu_exit
menu_test:
mov eax,offset test_msg
jmp message_
menu_open:
mov eax,offset open_msg
jmp message_
menu_save:
mov eax,offset save_msg
message_:
pushMB_OK
pushoffset menu_name
pusheax
pushwp_hWnd
callMessageBox
jmpend_
menu_exit:
pushwp_hWnd
callDestroyWindow
end_:
leave
ret16
not_all:
leave
jmpDefWindowProc
win_procendp
end_start

А теперь давайте разберёмся в новых строках. Итак, первые 4 новые строки, это создание виртуальных значений, это я думаю понятно. Дальше мы создаём 4 переменные, одну с именем меню, и три с сообщениями для messagebox. Следующие добавление, это загрузка меню из ресурсов, выполняемая процедурой LoadMenu, которая получает два параметра, имя меню и Handle процесса. Далее мы заменяем одну строку при создании окна. Прошу обратить внимание, что эта строка уже существовала в прошлых примерах, просто мы помещали в стек не handle меню, а 0! Единственное, что нам осталось сделать, это добавить в процедуру нашего окна обработку событий меню. При получении сообщения от меню, главное сообщение содержит команду wm_command, а уже первый параметр сообщения содержит номер выбранного меню. То есть нам надо добавить только обработку сообщения wm_command. И только если сообщение действительно wm_command, обрабатывать первый параметр.

При этом в файл user32.inc следует дописать следующие строки:

extrn __imp__LoadMenuA@8:dword
extrn __imp__DestroyWindow@4:dword
LoadMenu equ __imp__LoadMenuA@8
DestroyWindow equ __imp__DestroyWindow@4

А в файл def32.inc

MB_OK equ 0
WM_COMMAND equ 111h

Причём, если Вы получили файлы inc от меня, то проверьте, возможно это уже записано в них! Тогда нет надобности записовать всё дважды. Если что не работает, пишите.
Все файлы ткущего урока можно скачать здесь, формат WinRaR.
К тому же Вам надо будет скачать улиту компиляции ресурсов, например, отсюда, формат WinRaR.И дописать строку в doit.bat:

ml /c /coff window.asm
rc /r menu.rc
link32 window.obj menu.res /subsystem:windows


Вот вроде и всё! Если есть какие вопросы, пишите, обязательно отвечу. На счёт следующего урока, даже не знаю на счёт чего писать, у меня есть две, на мой взгляд, одинаково интересные темы, "Работа с файлами в Windows" и "Значение Диологов в Windows". Напишите мне, что Вам кажется более интересным. Пишите, Dark_Lord@RusFAQ.ru, Dark_Lord@land.ru.
Или свяжитесь со мной по ICQ, мой номер 126222874!



При поддержке RusFAQ.ru

be number one


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное