CZĘŚĆ 2. - INSTRUKCJE WARUNKOWE
Ok, a więc mamy okienko z komunikatem. Ale jak teraz odczytać, który przycisk został wybrany przez użytkownika? Służą do tego tzw. instrukcje warunkowe, czyli IF. Napiszmy następujący program:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
msgTytul db "MASM Tutorial",0
msgTekst db "Wciśnij tak lub nie.",0
.code
start:
invoke MessageBox, 0, addr msgTekst, addr msgTytul, MB_YESNO or MB_ICONQUESTION
invoke ExitProcess, 0
end start
Jak się zapewne domyślacie, służy on do wyświetlenia okienka z odpowiednim komunikatem i przyciskami tak/nie. W pomocy (winapi.hlp) do funkcji MessageBox czytamy:
"The return value is zero if there is not enough memory to create the message box. If the function succeeds, the return value is one of the following menu-item values returned by the dialog box:
| Value |
Meaning |
| IDABORT |
Abort button was selected. |
| IDCANCEL |
Cancel button was selected. |
| IDIGNORE |
Ignore button was selected. |
| IDNO |
No button was selected. |
| IDOK |
OK button was selected. |
| IDRETRY |
Retry button was selected. |
| IDYES | Yes button was selected." |
Należy więc sprawdzić, czy zwrócona wartość jest równa IDYES czy IDNO. Warto wiedzieć, że funkce API zawsze zwracają wartości w rejestrze EAX. Sprawdzania wartości dokonujemy za pomocą bloku instrukcji .IF-.ENDIF. Składnia wygląda tak:
.IF warunek
polecenia
.ELSEIF warunek
polecenia
.ELSE
polecenia
.ENDIF
Warto wiedzieć, że IF nie jest standardową instrukcją assemblera, tzn. nie występuje w assemblerze jakim posługuje się procesor. Kompilator po prostu "tłumaczy" każdy blok IF na odpowiadające mu polecenia assemblera. Omówię je, jak zajdzie taka potrzeba. Na razie możemy z powodzeniem używać instrukcji IF.
Wszyscy, którzy programowali już w jakimś języku wyższego poziomu, więdzą zapewne, że po MessageBoxie można dopisać na przykład taki oto zestaw poleceń:
.IF eax==IDYES
invoke MessageBox, 0, addr msgYesTekst, addr msgTytul, MB_OK or MB_ICONEXCLAMATION
.ELSE
invoke MessageBox, 0, addr msgNoTekst, addr msgTytul, MB_OK or MB_ICONEXCLAMATION
.ENDIF
Wstawiamy go bezpośrednio po poleceniu "invoke MessageBox". A dlaczego piszemy ".else" zamiast ".elseif eax==IDNO"? Żeby zaoszczędzić trochę pamięci i czasu procesora (przyda wam się to później, gdy będziecie chcieli napisać jakiegoś vira ;-)). Oczywiście w tym fragmencie jest pewne niedopatrzenie - nie ma jeszcze zmiennych msgYesTekst oraz msgNoTekst. Definiujemy je oczywiście w sekcji .data. Możemy napisać np.
msgYesTekst db "Wcisnąłeś ",34,"Tak",34,"!",0
msgNoTekst db "Wcisnąłeś ",34,"Nie",34,"!",0
Dociekliwi pewnie zaraz zapytają: A co to jest 34? Jest to kod ASCII cudzysłowu. A skąd my to wiemy? Z tablicy znaków (ta windowsowa posiada znaki jedynie od 32, poza tym nie podaje kodu znaku. Warto więc zaopatrzyć się w jakąś lepszą - na mojej stronie jest jeszcze (chyba) mój stary programik tego typu o nazwie ArAscii [jeszcze z czasów, kiedy programowalem ;) w VB]. Nie jest to może najlepszy program tego typu ale na początek wystarczy - ci co chcą więcej muszą poszperać w czeluściach internetu).
Oczywiście analogicznie można reagować na inne przyciski (IDABORT, IDCANCEL, IDIGNORE, IDOK, IDRETRY).
Cały program wygląda więc tak:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
msgTytul db "MASM Tutorial",0
msgTekst db "Wciśnij tak lub nie.",0
msgYesTekst db "Wcisnąłeś ",34,"Tak",34,"!",0
msgNoTekst db "Wcisnąłeś ",34,"Nie",34,"!",0
.code
start:
invoke MessageBox, 0, addr msgTekst, addr msgTytul, MB_YESNO or MB_ICONQUESTION
.IF eax==IDYES
invoke MessageBox, 0, addr msgYesTekst, addr msgTytul, MB_OK or MB_ICONEXCLAMATION
.ELSE
invoke MessageBox, 0, addr msgNoTekst, addr msgTytul, MB_OK or MB_ICONEXCLAMATION
.ENDIF
invoke ExitProcess, 0
end start
Chyba nie muszę wyjaśniać, co on robi... Cały programik można pobrać stąd.
Arkadiusz "Czajnick" Robiński
arekrob@kki.net.pl
http://www.antywin.ko.pl