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é 10x (5.28 kB)
Aplikácia je vrátane zdrojových kódov v jazyku ASM