📄 窗口子类化演示.txt
字号:
窗口子类化演示 作者:msfm 于2008-1-17上传
--------------------------------------------------------------------------------
编辑前言:msfm给我们提供了一个窗口子类化的例子,程序实现了检测输入
是否在给定范围的功能。程序很简单,但是对于学习者来说有很大的参考意义。
另外我们还可以根据这个程序的框架扩展出自己需要的程序。通过积累框架的代码
在日后会很方便我们编写简单的程序。
;MASMPlus 代码模板 - 普通的 Windows 程序代码
;********************************************************************
; 窗口子类化演示
; 起源于一个DELPHI项目,需要控制一些字符输入,要求速度优先,于是想到用嵌入汇编
; 解决循环查找字符,带来的时间浪费问题。
; 于是简单的 使用了窗口自类化方法,其中需要注意的是,使用模态与非模态对话框,VK_RETURN
; 消息将不被拦截,希望高手赐教原因。
; 程序还有相当大的优化改进,空间,同时存在很大的不足,目前只是提供了一个框架,希望大
; 家修改,并提出宝贵的意见。谢谢
;********************************************************************
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.data?
hInstance dd ?
hWinMain dd ?
dwOption dd ?
lpOldProcEdit dd ?
hedt dd ?
buf db 256 dup(?)
.const
szClassName db 'MyClass',0
Cedt db "Edit",0 ;标准控件
Cstc db "static",0 ;标准控件
szCaptionMain db '字符检测',0 ;Cation
szCaption db '范围定义 *、0..9、:、A..Z、a..z',0 ;合法字符
lpText db '提示',0
lpCaption db '包含非法字符',0
tbTable db '*','*','0','9',':',':',
'A','Z',
'a','z' ;定义合法字符Table
tbTableLen db $-tbTable ;length(Table)
.code
_isLetter proc
pushad
;下面的程序是一个双层循环,看起来不是很精巧,但是
;算法足够简单,容易理解
invoke lstrlen,addr buf
mov ecx,eax
lea esi,buf
iloop: ;外层循环
mov bl,[esi] ;从输入中取出一个字符
xor edx,edx ;我们使用edx作为标记
push ecx
lea edi,tbTable
movzx ecx,tbTableLen
jloop: ;内层循环
mov ax,[edi]
.if (al>bl)
inc edx
jmp nexti
.elseif (ah>=bl)
jmp nexti
.else
add edi,2
.endif
loop jloop
nexti:
pop ecx
.if (edx!=0) ;如果没有标记,说明不符合范围
mov eax,1
popad
ret
.endif
inc esi
loop iloop
popad
xor eax,eax
ret
_isLetter endp
_ProcEdit proc hWnd,uMsg,wParam,lParam
pushad
mov eax,uMsg
.if eax==WM_KEYDOWN
.if wParam == VK_RETURN
invoke GetWindowText,hedt,addr buf,sizeof buf
invoke _isLetter
.if eax !=0
invoke MessageBox,hWnd,addr lpCaption,addr lpText ,MB_ICONWARNING
invoke SetFocus,hedt
ret
.endif
ret
.endif
.else
invoke CallWindowProc,lpOldProcEdit,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
popad
ret
_ProcEdit endp
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
mov eax,uMsg
.if eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
100,100,400,200,\
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset Cstc,offset szCaption,\
WS_VISIBLE or WS_CHILD,\
25,10,350,20,\
hWinMain,NULL,hInstance,NULL
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset Cedt,NULL,\
WS_VISIBLE or WS_CHILD,\
25,50,350,40,\
hWinMain,NULL,hInstance,NULL
mov hedt,eax
invoke SetFocus,hedt
invoke SetWindowLong,hedt,GWL_WNDPROC,addr _ProcEdit
mov lpOldProcEdit,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
--------------------------------------------------------------------------------
欢迎访问AoGo汇编小站:http://www.aogosoft.com/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -