Создать меню без файла описания ресурсов с помощью функций CreateMenu и CreatePopupMenu
Министерство образования Российской Федерации
Институт переподготовки кадров
Уральского государственного технического
университета
Кафедра микропроцессорной техники
Курсовая работа
ТЕМА: Создать меню без файла описания ресурсов с
помощью функций CreateMenu и CreatePopupMenu.
Руководитель В.П.Кулюкин
Слушатель гр. СП-923
Г.Г.
2001г.
Содержание
Введение 3
Постановка задачи 5
Создание меню без описания
ресурсов с помощью функций CreateMenu и CreatePopupMenu 6
Текст программы 7
Заключение 13
Библиографический список 14
Введение
Ассемблер- один из самых
старых из существующих сегодня языков программирования.Когда-то это был самый
основной язык, без которого нельзя было заставить компьютер сделать что-либо
полезное.
Постепенно ситуация менялась.
Появились более удобные средства общения с компьютером. Но в отличии от других
языков ассемблер не умирал, более того он немог этого сделать в принципе.
Если коротко, то ассемблер-
это символическое представление машинного языка. Все процессы в машине на самом
низком, аппаратном уровне приводятся в действие только командами машинногшо
языка.
Отсюда понятно, что несмотря
на общее название, язык Ассемблера для каждого типа компьютера свой. Это
касается и внешнего вида программ, написанных на Ассемблере, и идей, отражением
которых этот язык является.
Известно, что к
программированию на языке ассемблера обращаются тогда, когда от программы
требуется максимальная скорость исполнения, когда необходимо обеспечить
взаимодействие с нестандартными внешними устройствами, когда необходимо
полностью использовать возможности процессора и операционной системы. На
языке ассемблера можно запрограммировать все, на что способна соответствующая
вычислительная машина, то есть ассемблер является машинно-ориентированным
языком программирования. Программируя на ассемблере иногда в силу привычки,
иногда в силу необходимости, особенно при организации интерфейса пользователя,
приходится многократно программировать одни и те же элементарные задачи. В
языках высокого уровня эта проблема решена применением стандартных функций и
процедур. В ассемблере эта проблема могла бы быть решена за счет библиотек
стандартных функций как на уровне исходных текстов, так и объектных кодов, но
такие библиотеки не стандартизованы и не распространяются вместе с
компиляторами. С появлением Windows 95 ситуация несколько изменилась. Создание приложений
на языке ассемблера представляет собой весьма сложную задачу в связи с высоким
уровнем интеграции прикладной программы и операционной системы, но теперь нет
необходимости многократно решать проблемы пользовательского интерфейса и
управления исполнением команд на уровне машинных команд [I].
Они решаются теперь с помощью операционной системы за счет обращения к функциям
интерфейса прикладного программирования – Application Programming Interface (API).
Программирование
пользовательского интерфейса с применением функций Win32 API
основано на использовании так называемых ресурсов. Ресурсами являются
соответствующим образом оформленные данные, используемые операционной системой
для создания внешнего отображения органов управления приложением, и средства,
обеспечивающие ввод данных в процессе исполнения программы в режиме диалога.
Ресурсы описываются в текстовом файле с расширением
rc. Файл ресурсов после обработки компилятора ресурсов и
получения двоичного файла с расширением res с помощью
компоновщика объединяется с исполняемым файлом.
Постановка задачи
Наиболее очевидным
средством управления приложением является меню. Строка меню выводится на экран
непосредственно под строкой заголовка. Это меню называется главным. Выбор
элемента меню влечет за собой выдачу приложению сообщения WM_COMMAND,
содержащего идентификатор пункта меню. Идентификаторы анализируются в оконной
процедуре приложения, что обеспечивает соответствующую реакцию на полученное
сообщение. Каждый пункт меню определяется тремя характеристиками. Первая
определяет то, что будет отображаться в данном пункте меню – это либо строка
текста, либо картинка. Вторая характеристика определяет либо константу,
посылаемую оконной процедуре в сообщении WM_COMMAND,
либо всплывающее меню, которое выводится на экран, когда пользователь выбирает
данный пункт меню. Третья характеристика указывает, является ли данный пункт
меню разрешенным (enabled), запрешенным (disabled),
недоступным (grayed) или помеченным (checked). Эта
характеристика пункта меню не является обязательной.
Меню можно создать тремя
способами. Можно определить меню в файле описания ресурсов, создать меню без
файла описания ресурсов непосредственно в программе с помощью функций CreatMenu, AppendMenu и InsertMenu или с помощью функции LoadMenuIndirect,
создав предварительно структуру MENUITEMPLATE. Наиболее простым и понятным при программировании под
Windows95 на языке ассемблера является определение меню в
файле описания ресурсов с помощью любого текстового редактора.
Моя задача заключается в
создание меню без файла описания ресурсов с помощью функций CreateMenu и CreatePopupMenu. Одним из средств создания меню без использования
файла описания ресурсов является функции CreateMenu с
последующим добавлением необходимого числа пунктов с помощью функции AppendMenu.
Создание меню без описания ресурсов с помощью функций
CreateMenu и CreatePopupMenu
Windows-приложение на
ассемблере содержит один сегмент данных .data и один сегмент кода .code. В
программе использовано 20 функций API. Параметры этим функциям передаются через
стек, результат возвращается в регистре ЕАХ.
Директива mode1 задает
плоскую модель памяти (flat) и стиль передачи параметров при входе в процедуры
программы и выходе из них (stdcall). Модель памяти flat обозначает плоскую
модель памяти. В соответствии с плоской моделью памяти компилятор создает
программу, которая содержит 32-битовый сегмент для данных и кода программы.
Указание этой модели памяти заставляет компоновщик создать исполняемый файл с
расширением .exe.
Параметр stdcall определяет
порядок передачи параметров через стек справа налево.
Директива include включае в
программу файл win32.inc.
Функции Win32 API,
используемые в программе должны быть объявлены с помощью директивы extrn для
того, чтобы компилятор мог сгенерировать правильный код.
При создании окна приложения
с помощью CreateMenu получаем дескриптор меню и используем его в качестве
одного из параметров функций CreateWindowExA. Затем с помощью функции CreatePopupMenu
получаем дескриптор выпадающего меню и вызовом AppendMenu
определяем все пункты наших меню.
Результат работы программы
приведен на Рис.1.
Текст
программы
p386 ; эта директива разрешает транслятору обрабатывать
команды
;
процессора i386
jumps ; транслятор автоматически преобразует команду
;условной
;
передачи управления в комбинацию условной и безусловной
; команд
если условная команда в силу ограниченности
;
области своего действия ;не обеспечивает передачу
;
управления по нужному адресу
model flat, STDCALL ; выбирается модель памяти для 32- разрядного
; программирования и правила передачи
; параметров функциям STDCALL, далее
; действующие по умолчанию
include win32.inc ; файл описания структур и констант
L equ <LARGE> ; последовательности символов LARGE,
; являющейся именем операции, объявляющей
; следующий за ней операнд 32-разрядным,
; присваивается имя L
IDM_QUIT
equ 100
IDM_ABOUT
equ 101
MF_ENABLED
equ 0
MF_POPUP
equ 10h
MF_OWNERDRAW
equ 100h
;Функции Win32 API, используемые программой
extrn BeginPaint
:PROC
extrn
CreateWindowExA :PROC
extrn
DefWindowProcA :PROC
extrn
DispatchMessageA :PROC
extrn
EndPaint :PROC
extrn
ExitProcess :PROC
extrn
GetMessageA :PROC
extrn
GetModuleHandleA :PROC
extrn
LoadCursorA :PROC
extrn
RegisterClassA :PROC
extrn
PostQuitMessage :PROC
extrn
ShowWindow :PROC
extrn
TranslateMessage :PROC
extrn
UpdateWindow :PROC
extrn
CreateMenu :PROC
extrn
MessageBoxA :PROC
extrn
AppendMenuA :PROC
extrn
DrawMenuBar :PROC
extrn
CreatePopupMenu :PROC
.data ;
переопределенное имя, означающее начало сегмента
; данных
newhwnd
dd 0
lppaint PAINTSTRUCT <?>
msg
MSGSTRUCT <?>
wc
WNDCLASS <?>
hInst
dd 0
fl
dw 0
szTitleName
db 'Это наше окно',0
szClassName
db 'ASMCLASS32',0
szHello db 'Привет!',0
szAppName
db 'Сообщение',0
hMenu dd 0
hsubmenu
dd 0
item1
db 'Меню',0
item2
db 'Выход',0
item3 db 'Возврат',0
.code
; переопределенное имя, означающее
начало
; сегмента кода
start:
push L 0
call
GetModuleHandleA
mov [hInst], eax
;инициализация
структуры WndClass
mov [wc.clsStyle], CS_HREDRAW +
CS_VREDRAW +
CS_GLOBALCLASS
mov
[wc.clsLpfnWndProc], offset WndProc
mov
[wc.clsCbClsExtra], 0
mov
[wc.clsCbWndExtra], 0
mov
eax, [hInst]
mov
[wc.clsHInstance], eax
push
L IDI_APPLICATION
push
L 0
call
LoadIconA
mov
[wc.clsHIcon], eax
push
L IDC_ARROW
push
L 0
call
LoadCursorA
mov
[wc.clsHCursor], eax
mov
[wc.clsHbrBackground], COLOR_WINDOW + 1
mov
dword ptr [wc.clsLpszMenuName],0
mov
dword ptr [wc.clsLpszClassName], offset szClassName
push
offset wc
call
RegisterClassA
call
CreateMenu
mov [hMenu],eax
push
L 0 ; lpParam
push
[hInst] ; hInstance
push
[hMenu] ; menu
push
L 0 ; parent hwnd
push
L CW_USEDEFAULT ; height
push
L CW_USEDEFAULT ; width
push
L CW_USEDEFAULT ; y
push
L CW_USEDEFAULT ; x
push
L WS_OVERLAPPEDWINDOW ; Style
push
offset szTitleName ; Title string
push
offset szClassName ; Class name
push
L 0 ; extra style
call
CreateWindowExA
call
CreatePopupMenu
mov [hsubmenu],
eax
push offset item2
push L
IDM_QUIT
push 0
push eax
call AppendMenuA
push offset
item3
push L
IDM_ABOUT
push 0
push [hsubmenu]
;eax
call AppendMenuA
push offset
item1
push [hsubmenu]
push MF_POPUP
push
[hMenu]
call AppendMenuA
nop
push L
SW_SHOWNORMAL
push
[newhwnd]
call
ShowWindow
push
[newhwnd]
call
UpdateWindow
push [newhwnd]
call DrawMenuBar
msg_loop:
push L 0
push L 0
push L 0
push offset
msg
call
GetMessageA
cmp ax, 0
je
end_loop
push offset
msg
call
TranslateMessage
push offset
msg
call
DispatchMessageA
jmp
msg_loop
end_loop:
push
[msg.msWPARAM]
call
ExitProcess
;----Оконная процедура----
WndProc proc
uses ebx edi esi, hwnd:DWORD, wmsg:DWORD,\
wparam:DWORD,
lparam:DWORD
LOCAL
hDC:DWORD
cmp [wmsg],
WM_DESTROY
je
wmdestroy
cmp [wmsg],
WM_SIZE
je wmsize
cmp [wmsg],
WM_CREATE
je
wmcreate
cmp
[wmsg],WM_PAINT
je wmpaint
;**************************************
cmp [wmsg],WM_COMMAND
je wmcommand
;**************************************
jmp
defwndproc
wmcommand:
mov eax,lparam
cmp ax,0
jne m1
mov eax,wparam
cmp ax,IDM_ABOUT
jne m2
call MessageBoxA,0,offset
szHello,offset szAppName,MB_OK
jmp m1
m2: cmp ax,IDM_QUIT
jne m1
push 0
m1: mov eax,0
jmp finish
wmcreate:
mov eax, 0
jmp finish
defwndproc:
push
[lparam]
push
[wparam]
push [wmsg]
push [hwnd]
call
DefWindowProcA
jmp finish
wmdestroy:
push L 0
call PostQuitMessage
mov eax, 0
jmp finish
wmsize:
mov eax, 0
jmp finish
wmpaint:
push offset
lppaint
push [hwnd]
call
BeginPaint
mov
[hDC],eax
push offset
lppaint
push [hwnd]
call
EndPaint
mov eax,0
jmp finish
finish:
ret
WndProc
endp
;---------------------------------
public WndProc
end
start ; конец программы
рис1. Окно программы
Заключение
Моя задача состояла в
создании программы без файла описания ресурсов с помощью функций CreateMenu и CreatePopupMenu. Это приложение не выполняет никакой полезной работы
и служит для демонстрации некоторых возможностей системы в организации
интерфейса пользователя.
Библиографический список
Зубков С.В. Assembler. Для DOS Windows и Unix.
М.: ДМК, 1999
Пустоваров В.И. АССЕМБЛЕР.
Программирование и анализ корректности машинных программ.
Применение TURBO ASSEMBLER для программирования ПЭВМ. Часть1,2.: Методические
указания к лабораторному практикуму по дисциплине : «Системное программное
обеспечение» / Составитель В.П.Кулюкин. Екатеринбург: изд. ИПК УГТУ, 2000.