1. diel - Dialógové okno Windows v assembleri
V dnešnom ASM tutoriálu pri tvorbe užívateľského rozhrania použijeme funkcie Windows na vytváranie dialógových okien.
Využívanie natívnych dialógových okien
Táto praktika má samozrejme svoje výhody a nevýhody.
Výhody
- Používame priamo súčasť operačného systému. Nemusíme inštalovať žiadne knižnice.
- Funguje to vo všetkých verziách Windows.
- Vo Visual Studiu je editor, v ktorom si môžeme dialógové okná jednoducho naklikať.
Nevýhody
- Vyzerá to trochu zastaralo. V dnešnej dobe sú ľudia zvyknutí, že všetko musí byť materiálne a ploché.
- Rozloženie je statické. Ak by sme chceli dynamicky pridávať do formulára ďalšie položky, museli by sme si sami počítať ich súradnice.
- Nie je možné robiť animácie ani iné špeciálne efekty.
Vytvorenie resources
Formulár si definujeme najprv ako tzv. Resource. V moderných aplikáciách sa resources používajú prevažne pre obrázky a ikony. Ak vytvárame používateľské rozhranie pomocou Win32 API, potom do resoures ukladáme tiež menu, panely nástrojov, klávesové skratky a dialógy. Čokoľvek si dáme do resources, bude vložené do EXE súboru.
Vo Visual Studiu klikneme v Solution Exploreri alebo v menu Project na Add New Item. Potom v ľavom paneli klikneme na Resource a vpravo vyberieme Resource File (.rc).

Keď v Solution Exploreri dvakrát klikneme na novo pridaný .rc
súbor, zobrazí sa Resource View. V Resource View klikneme
pravým tlačidlom na .rc súbor a zvolíme Add Resource.

Ďalej zvolíme Dialóg a klikneme na tlačidlo New.

Objaví sa editor dialógu a vľavo je toolbox so všetkými možnými ovládacími prvkami.
Zdrojový kód
Keď sa chceme pozrieť na zdrojový kód .rc súboru, v
Solution Exploreri naň klikneme pravým tlačidlom a zvolíme View
Code. V tejto lekcii použijeme nasledujúci súbor
Resource.rc. Môžete si ho odtiaľto celý skopírovať a alebo si
ho môžete skúsiť sami naklikať vo Visual Studiu. Pretože súbor
vygenerovaný Visual Studiom je pomerne dlhý, tu uvedieme len tie riadky,
ktoré sú nevyhnutné na spustenie programu (zvyšok súboru je prípadne k
stiahnutiu v archíve pod lekcií):
#include "resource.h" #include "winres.h" LANGUAGE LANG_CZECH, SUBLANG_DEFAULT #pragma code_page(1250) IDD_LOGIN DIALOGEX 0, 0, 155, 103 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Vítejte" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN LTEXT "Zadejte Vaše jméno:",374,6,9,142,8 EDITTEXT IDC_NAME, 7, 26, 142, 14, ES_AUTOHSCROLL CONTROL "Pamatovat si mě",IDC_REMEMBER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,55,142,10 DEFPUSHBUTTON "OK",IDOK,19,78,50,14 PUSHBUTTON "Zrušit",IDCANCEL,86,78,50,14 END
Kód korešponduje s nasledujúcim dialógovým oknom:

Použitie resources v ASM
Visual Studio automaticky pre všetky položky generuje číselné
identifikátory a vkladá ich do hlavičkového súboru
resource.h:
#define IDD_LOGIN 102 #define IDC_REMEMBER 1001 #define IDC_NAME 1002
V assembleri nemôžeme použiť priamo súbor resource.h, ale
manuálne z neho musíme vytvoriť resource.inc, ktorý bude
vyzerať takto:
IDD_LOGIN equ 102 IDC_REMEMBER equ 1001 IDC_NAME equ 1002
Nie je vhodné používať názvy DIALOG1,
CHECK1, EDIT1 atď., Ale je lepšie pomenovať si
ovládacie prvky podľa toho, čo ktorý ovládací prvok robí.
Program v assembleri
Pripravíme si súbor s ASM kódom:
option win64:2 include windows.inc include resource.inc .data remember dd FALSE name db "nějaké jméno", 100 dup(0) .code
Naša dialógové okno obsahuje jeden prepínač a jedno textové pole. V
sekcii .data sú pre nich vytvorené globálne premenné. Všimnite
si, že za textom sú vyhradené nulové bajty operátorom dup. To
je kvôli tomu, že do premennej potom zapíšeme text, ktorý zadal
používateľ. Ak používateľ zadá príliš dlhý text, tak sa oreže.
Kód
Pridajme ďalšie riadky reprezentujúci časť s kódom ASM programu.
dlgproc
Najprv pridáme funkciu pre obsluhu nášho okna:
dlgproc proc hWnd:HWND, msg:UINT, wParam:WPARAM, lParam:LPARAM
mov hWnd,rcx
.if edx == WM_INITDIALOG
invoke CheckDlgButton, hWnd, IDC_REMEMBER, remember
invoke SetDlgItemText, hWnd, IDC_NAME, addr name
mov eax,TRUE
.elseif edx == WM_COMMAND
.if r8w == IDOK
invoke IsDlgButtonChecked, hWnd, IDC_REMEMBER
mov remember,eax
invoke GetDlgItemText, hWnd, IDC_NAME, addr name, sizeof name
invoke EndDialog, hWnd, IDOK
.elseif r8w == IDCANCEL
invoke EndDialog, hWnd, IDCANCEL
.else
mov eax,FALSE
.endif
.else
mov eax,FALSE
.endif
ret
dlgproc endp
Názov funkcie si môžeme zvoliť aký chceme. V aplikácii často býva
viac okien, takže je rozumné si ich správne pomenovávať, aby sme sa v nich
vyznali. V prvom parametra hWnd dostaneme handle nášho okna. Vo
Windows je všetka komunikácia medzi oknami a systémom riešená pomocou
správ. V parametri msg je typ správy, ktorú máme obslúžiť.
Parametre wParam a lParam závisia od toho, o ktorú
správu sa jedná. V 64-bitové aplikácii sa parametre odovzdávajú v
registroch. Hneď na začiatku si register ECX uložíme do
premennej hWnd, pretože ho neskôr budeme potrebovať. Ďalej sme
použili príkazy .if, .elseif, .else a
.endif, ktoré fungujú podobne ako vo vyšších programovacích
jazykoch a zvyšujú čitateľnosť programu.
Vo WM_INITDIALOG vyplníme počiatočnej hodnoty položiek
podľa hodnôt z premenných. Funkcia CheckDlgButton zaškrtne
prepínač, zatiaľ čo funkcia SetDlgItemText vyplní text. V
registri EAX vraciame TRUE, čo znamená, že systém
automaticky aktivuje čiže nastaví focus na prvú položku dialógu.
Vo WM_COMMAND sa obsluhujú tlačidlá alebo iné ovládacie
prvky. Keď užívateľ stlačí tlačidlo "OK", uložíme si zadané
hodnoty do premenných a potom zavrieme okno funkcií EndDialog.
Pokiaľ užívateľ stlačí tlačidlo "Zrušiť" alebo zatvorí okno,
potom tiež ukončíme dialóg.
Ak správu nespracujeme, musíme v registri EAX vrátiť
FALSE a systém správu spracuje za nás a vykoná nejakú
predvolenú akciu.
main
A konečne dodáme aj hlavnú funkciu main:
main proc
invoke GetModuleHandle, NULL
invoke DialogBoxParam, rax, IDD_LOGIN, 0, addr dlgproc, 0
invoke ExitProcess, 0
main endp
end main
Vo funkcii zistíme handle našej aplikácie a zobrazíme dialógové okno.
Ak by bol dialóg skompilovaný do DLL, potom by bol vo funkcii
GetModuleHandle miesto NULL názov DLL súboru.
Funkcia DialogBoxParam vracia v registri RAX hodnotu,
ktorú sme predtým zadali v EndDialog. Môžeme si teda z dialógu
vracať nejakú hodnotu. Pokiaľ naopak potrebujeme odovzdať nejakú hodnotu
smerom do dialógu, zadáme ju ako posledný parameter funkcie
DialogBoxParam a potom ju budeme mať vo WM_INITDIALOG
v parametri lParam.
Common controls - Manifest
Keď program spustíme, bude okno vyzerať ako v dávnych dobách vo Windows 95:

Aby vyzeralo trochu modernejšie, musíme nový vzhľad povoliť v
manifeste. Vo vlastnostiach projektu Linker -> Manifest File
-> Additional Manifest Dependencies zadáme
"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'".
Ak použijeme pokročilejšie ovládacie prvky, musíme ich inicializovať.
Za riadok include windows.h pridáme tieto dva riadky:
include commctrl.inc includelib comctl32.lib
Na začiatok funkcie main pridáme riadky:
local ic:INITCOMMONCONTROLSEX
mov ic.dwSize, sizeof INITCOMMONCONTROLSEX
mov ic.dwICC, ICC_LISTVIEW_CLASSES or ICC_TREEVIEW_CLASSES or ICC_BAR_CLASSES
invoke InitCommonControlsEx, addr ic
Inicializuje len to, čo budeme skutočne potrebovať. Celkový zoznam, čo všetko ide iniciovať, je nižšie:
ICC_LISTVIEW_CLASSES- zoznam položiek s viacerými stĺpciICC_TREEVIEW_CLASSES- stromové zobrazenieICC_BAR_CLASSES- panel s nástrojmiICC_TAB_CLASSES- záložkyICC_UPDOWN_CLASS- šípky hore a dole u zadávanie číselICC_PROGRESS_CLASS- ukazovateľ priebehuICC_HOTKEY_CLASS- klávesová skratkaICC_ANIMATE_CLASS- animácie, AVI klipICC_DATE_CLASSES- dátum a časICC_USEREX_CLASSES- výber z viac položiek s obrázkamiICC_COOL_CLASSES- moderné panel s nástrojmi ako v MS Office
dlgproc bez .if
Na záver si ukážeme, ako by vyzerala dialógová procedúra bez použitia
.if, čo je samozrejme len nadstavba prekladača nad
inštrukciami:
dlgproc proc hWnd:HWND, msg:UINT, wParam:WPARAM, lParam:LPARAM
mov hWnd,rcx
cmp edx,WM_INITDIALOG
jne @@1
invoke CheckDlgButton, hWnd, IDC_REMEMBER, remember
invoke SetDlgItemText, hWnd, IDC_NAME, addr name
mov eax,TRUE
jmp @@ret
@@1: cmp edx,WM_COMMAND
jne @@0
cmp r8w,IDCANCEL
je @@e
cmp r8w,IDOK
jne @@0
invoke IsDlgButtonChecked, hWnd, IDC_REMEMBER
mov remember,eax
invoke GetDlgItemText, hWnd, IDC_NAME, addr name, sizeof name
mov r8w,IDOK
@@e: invoke EndDialog, hWnd, r8w
@@0: mov eax,FALSE
@@ret: ret
dlgproc endp
V prílohe máte aplikácii k stiahnutiu so zdrojovým kódom pre prípad, že by vám čokoľvek nešlo.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 11x (5.28 kB)
Aplikácia je vrátane zdrojových kódov v jazyku ASM
