Your snipt has been migrated to #newsnipt successfully.
Chex][0V
asm
posted: Jun, 5th 2010 | jump to bottom
; windlg.asm ; Графическое win32-приложение, демонстрирующее работу с диалогом ; ; Компиляция TASM ; tasm /m /ml /D_TASM_ windlg.asm ; brcc32 windlg.rc ; tlink32 /Tpe /aa /c /x windlg.obj,,,,,windlg.res ; ; идентификаторы контролов (элементов диалога) IDC_EDIT equ 0 IDC_BUTTON equ 1 IDC_EXIT equ 2 ; идентификаторы элементов меню IDM_GETTEXT equ 10 IDM_CLEAR equ 11 IDM_EXIT equ 12 include def32.inc include kernel32.inc include user32.inc .386 .model flat .data dialog_name db "ZZZ_Dialog",0 ; имя диалога в ресурсах count dw 0 length dd 0 .data? buffer db 512 dup(?) ; буфер для введённого текста .code _start: xor ebx,ebx ; в EBX будет 0 для команд push 0 (короче в 2 раза) ; определим идентификатор нашей программы ; Вызов GetModuleHandle(NULL) push ebx call GetModuleHandle ; запустим диалог ; Вызов DialogBoxParam(hModule,DlgName,hwnd,DlgProc,NULL) push ebx ; значение, которое перейдёт как параметр WM_INITDIALOG push offset dialog_proc ; адрес процедуры типа DialogProc push ebx ; идентификатор окна-предка (0 - ничей диалог) push offset dialog_name ; адрес имени диалога в ресурсах push eax ; идентификатор программы, в ресурсах которой ; находится диалог (наш идентификатор в EAX) call DialogBoxParam ; выход из программы ; Вызов ExitProcess(NULL) push ebx call ExitProcess ; ; процедура dialog_proc ; обработчик событий ; вызывается диалогом каждый раз, когда в нём что-нибудь происходит ; именно здесь будут происходить вся работа программы ; ; процедура не должна изменять регистры EBP,EDI,ESI и EBX ! ; dialog_proc proc near ; так как мы получаем параметры в стеке, построим стековый кадр push ebp mov ebp,esp ; процедура типа DialogProc вызывается со следующими параметрами dp_hWnd equ dword ptr [ebp+08h] ; идентификатор диалога dp_uMsg equ dword ptr [ebp+0Ch] ; номер сообщения dp_wParam equ dword ptr [ebp+10h] ; первый параметр dp_lParam equ dword ptr [ebp+14h] ; второй параметр mov ecx,dp_hWnd ; ECX будет хранить идентификатор диалога mov eax,dp_uMsg ; а EAX - номер сообщения cmp eax,WM_INITDIALOG ; если мы получили WM_INITDIALOG jne not_initdialog ;Вызов GetDlgItem(hwnd,id) push IDC_EDIT push dp_hWnd call GetDlgItem ; определим идентификатор ;Вызов SetFocus(hwnd) push eax ; окошка редактирования текста call SetFocus ; и передадим ему фокус not_initdialog: cmp eax,WM_CLOSE ; если мы получили WM_CLOSE jne not_close ;Вызов EndDialog(hwnd,0) push 0 push ecx call EndDialog ; закрыть диалог not_close: cmp eax,WM_COMMAND ; если мы получили WM_COMMAND jne not_command mov eax,dp_wParam ; EAX = wParam (номер сообщения) cmp dp_lParam,0 ; если lparam ноль - сообщение от меню jne lParam_not_0 cmp ax,IDM_GETTEXT ; если это пункт меню Get Text jne not_gettext ;Вызов GetDlgItemText(hwnd,id,buffer,size_of_buffer) push 512 ; размер буфера push offset buffer ; адрес буфера push IDC_EDIT ; номер конрола редактирования push ecx call GetDlgItemText ; считаем текст в buffer push eax push ebx xor eax, eax xor ebx, ebx ;Вызов GetDlgItem(hwnd,id) push IDC_EDIT push dp_hWnd call GetDlgItem ; определим идентификатор ;Вызов GetWindowTextLength(hwnd) push eax ; окошка редактирования текста call GetWindowTextLength ; и передадим ему длину строки mov ecx, eax ; в eax длина строки mov length, ecx ;перемещаем в переменную lenght xor eax, eax ; eax=0 mov count, 0 ;кол-во слов в строке = 0 mov edi, offset buffer ;загрузка буфера в edi mov al, ' ' ; mov bl, [edi] ; CYCLE: repne scasb ; jne END_CYCLE ; cmp ecx, length ; je NEXT ; mov bl, [edi-2] ; NEXT: cmp bl, al ; jne INCREMENT ; jmp CYCLE ; INCREMENT: inc count ;увеличиваем кол-во слов на 1 jmp CYCLE ;проходим цикл снова END_CYCLE: inc count ; pop ebx pop eax ;Вызов MessageBox(hwnd,Text,Title,mode) push MB_OK push offset dialog_name ;push offset buffer add count, '0' push offset count push dp_hWnd call MessageBox ; и покажем его в MessageBox not_gettext: cmp eax,IDM_CLEAR ; если это пункт меню Clear jne not_clear ;Вызов SetDlgItemText(hwnd,id,text) push 0 ; NULL push IDC_EDIT ; номер контрола push ecx call SetDlgItemText ; установим новый текст not_clear: cmp eax,IDM_EXIT ; если это пункт меню Exit jne not_exit ;Вызов EndDialog(hwnd,0) push 0 ; код возврата push ecx ; идентификатор диалога call EndDialog ; закрыть диалог lParam_not_0: ; lParam не ноль - сообщение от контрола cmp eax,IDC_EXIT ; если сообщение от кнопки Exit jne not_exit shr eax,16 cmp eax,BN_CLICKED ; если её нажали jne not_exit ;Вызов EndDialog(hwnd,0) push 0 ; код возврата push ecx ; идентификатор диалога call EndDialog ; закрыть диалог not_exit: xor eax,eax ; после обработки команды inc eax ; DialogProc должен возвращать TRUE (eax=1) leave ret 16 ; конец процедуры not_command: ; сюда передаётся управление если мы получили ; какое-то незнакомое сообщение xor eax,eax ; код возврата FALSE (eax=0) leave ret 16 ; конец процедуры dialog_proc endp end _start
66 views




