Міністерство освіти Російської Федерації
Інститут перепідготовки кадрів
Уральського державного технічного
університету
Кафедра мікропроцесорної техніки
Курсова роботаТЕМА: Створення меню без файлу опису ресурсів на основі функції LoadMenuIndirect.
Керівник доц., К.т.н. В. П. Кулюкін
Слухач гр. СП-923 І.Г.
г.Нягань
2001р.
Введення.
Відомо, що до програмування мовою асемблера звертаються тоді, коли від програми потрібна максимальна швидкість виконання, коли необхідно забезпечити взаємодію з нестандартними зовнішніми пристроями, коли необхідно повністю використовувати
можливості процесора і операційної системи. На мові асемблера можна запрограмувати все, на що здатна відповідна обчислювальна машина, тобто асемблер є машинно-орієнтованою мовою програмування. Програмуючи на асемблері іноді в силу звички, іноді в силу необхідності, особливо при організації інтерфейсу користувача, доводиться багато разів програмувати одні й ті ж елементарні завдання. У мовах високого рівня ця проблема вирішена застосуванням стандартних функцій і процедур. В асемблері ця проблема могла б бути вирішена за рахунок бібліотек стандартних функцій як на рівні вихідних текстів, так і об'єктних кодів, але такі бібліотеки не стандартизовані і не поширюються разом з компіляторами. З появою Windows 95 ситуація дещо змінилася. Створення додатків на мові асемблера представляє собою досить складне завдання у зв'язку з високим рівнем інтеграції прикладної програми і операційної системи, але тепер немає необхідності багаторазово вирішувати проблеми користувальницького інтерфейсу і управління виконанням команд на рівні машинних команд [I]. Вони вирішуються тепер за допомогою операційної системи за рахунок звернення до функцій інтерфейсу програмування - Application Programming Interface (API).
Програмування для користувача інтерфейсу з застосуванням функцій Win32 API засноване на використанні так званих ресурсів. Ресурсами є відповідним чином оформлені дані, які використовуються операційною системою для створення зовнішнього відображення органів управління програмою, і кошти, що забезпечують введення даних в процесі виконання програми в режимі діалогу. Ресурси описуються в текстовому файлі з розширенням
rc. Файл ресурсів після обробки компілятора ресурсів і одержання двійкового файлу з розширенням res за допомогою компонувальника об'єднується з виконуваним файлом.
Загальна частина.
Найбільш очевидним засобом управління додатком є меню. Строкаа меню виводиться на екран безпосередньо під рядком заголовка. Це меню називається головним. Вибір елемента меню тягне за собою видачу додатка повідомлення WD_COMMAND, що містить ідентифікатор пункту меню. Ідентифікатори аналізуються у віконній процедурі програми, що забезпечує відповідну реакцію на отримане повідомлення. Кожен пунк меню визначається трьома характеристиками. Перша визначає те, що буде відображатися в даному пункті меню - це або рядок тексту, або картинка. Друга характеристика визначає або константу, що посилається віконної процедури повідомленні WM_COMMAND, або спливаюче меню, яке виводиться на екран, коли користувач вибирає даний пункт меню. Третя характеристика вказує, чи є даний пункт меню дозволеним (enabled), запрешенним (disabled), недоступним (grayed) або поміченим (checked). Ця характеристика пункту меню не є обов'язковою.
Для того, щоб включити меню в додаток, необхідно реалізувати наступну послідовність кроків:
розробити сценарій меню. Перед тим як приступити до процесу включення меню в конкретний додаток, розробимо логічну схему. Цей крок необхідний для того, щоб вже на стадії проектування забезпечити ергономічні властивості програми. Адже меню - це один з небагатьох елементів інтерфейсу, з яким користувач постійно буде мати справу. Тому схема меню повинна мати наочну ієрархічну структуру, з логічно зв'язаними між собою пунктами цієї ієрархії, що допоможе користувачеві ефективно використовувати всі можливості програми. Для того, щоб вести предметну розмову, поставимо собі завдання розробити для вікна нашого застосування головне меню. При цьому ми досліджуємо можливості виведення у вікно додатка тексту і графіки, а також покажемо способи вирішення загальних проблем, пов'язаних з розробкою програми. Наше меню досить просте і складається з трьох елементів: "Текст", "Графіка", "Про програму". Ієрархічна структура меню представлена.
| |||||||
| |||||||
| |||||||
| |||||||
|
|
| |||||||||||||
| |||||||||||||||
|
описати схему меню у файлі ресурсів. Для виконання цього опису використовуються спеціальні оператори.
скласти текст включається файлу, необхідного для компіляції ресурсного файлу
компілювати ресурсний файл.
підключити меню на стадії реєстрації того вікна додатка, для роботи з яким воно буде використовуватися.
Меню можна створити трьома способами. Можна визначити меню у файлі опису ресурсів, створити меню без файлу опису ресурсів безпосередньо у програмі за допомогою функцій CreatMenu, AppendMenu і InsertMenu або за допомогою функції LoadMenuIndirect, створивши попередньо структуру MENUITEMPLATE. Найбільш простим і зрозумілим при програмуванні під Windows95 на мові асемблера є визначення меню у файлі опису ресурсів за допомогою будь-якого текстового редактора.
Основна частина.
Моє завдання полягає в тому, щоб написати програму на тему: "Створити меню без файлу опису ресурсів на основі функцій LoadMenuIndirect".
Одним із засобів створення меню без використання файлу опису ресурсів є функція LoadMenuIndirect. Для застосування цієї функції необхідно створити шаблон меню, визначається структурами
MENUITEMTEMPLATEHEADER і MENUITEMTEMPLATE.
Повний шаблон меню складається із заголовка і хоча б одного опису пункту меню. Заголовок - структура MENUITEMTEMPLATEHEADER - складається з двох полів розміром в слово. У першому слові міститься номер версії функції. Для Windows NT і Win16 це 0, для Windows95-1. У другому слові міститься зсув до першої структури MENUITEMTEMPLATE. Якщо між заголовком і описом першого пункту меню немає додаткової інформації, це поле містить 0.
Описи пунктів меню, наступні за заголовком, повинні бути вирівняні на кордоні подвійного слова. Структура MENUITEMTEMPLATE має, як правило, п'ять полів. Шосте поле має сенс для пункту меню, що вказує на спливаюче меню.
Як приклад наводиться вікно з головними і спливаючими меню, створеними за допомогою функції LoadMenuIndirect.
Програма.
p386
jumps
model flat, STDCALL
include win32.inc; файл опису структур і констант
L equ
IDM_QUIT equ 100
IDM_ABOUT equ 101
MF_ENABLED equ 0
MF_POPUP equ 1h
; Функції 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 LoadIconA: PROC
extrn RegisterClassA: PROC
extrn PostQuitMessage: PROC
extrn ShowWindow: PROC
extrn TranslateMessage: PROC
extrn UpdateWindow: PROC
extrn LoadMenuIndirectA: PROC
extrn MessageBoxA: 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
align 4
MenuTemplate dw 1,0; Тема меню. 1 - ознака
; Структури для функції Windows95
align 4
dd 0; тип пункту
dd 0, MF_ENABLED, 0; IDM_ABOUT;
dw 81h
dw'&',' M ',' e ',' n ',' u ', '1', 0
align 4
dd 0,0,0, IDM_QUIT
dw 0
dw 'E','&',' x', 'i', 't', 0,0
align 4
dd 0,0, IDM_ABOUT
dw 0
dw'&',' Q ',' u ',' i ',' t ', '1', 0
align 4
dd 0,0,0; IDM_QUIT
dw 81h; Ознака вспл. меню
dw 'Q', 'u', 'i', 't', '2 ', 0,0,0
align 4
dd 0,0, IDM_ABOUT
dw 0
dw 'Q', 'u', 'i', 't', '3 ', 0,0
align 4
dd 0,0, IDM_QUIT
dw 80h
dw 'E','&',' x', 'i', 't', 0,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
push offset MenuTemplate
call LoadMenuIndirectA
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
mov [newhwnd], eax
push L SW_SHOWNORMAL
push [newhwnd]
call ShowWindow
push [newhwnd]
call UpdateWindow
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
; We never get to here
;---- Віконна процедура ----
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
call PostQuitMessage
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