The Easiest Way to Save and Share Code Snippets on the web

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