📄 编写 windows 标准控件㈠ .txt
字号:
invoke GetWindowText,hButt,addr buffer,sizeof buffer
mov ecx,wParam
lea esi,buffer
@@:
mov al,[esi]
inc esi
test al,al
jz @@Ret
cmp al,'&'
jnz @B
cmp BYTE ptr [esi],cl
jnz @B
jmp @@ButtonClick
invoke DefWindowProc,hButt,uMsg,wParam,lParam
过滤系统按键,这里没有用接管这个词,是因为,在处理后,还使用DefWindowProc调用了默认的窗口过程,所以叫过滤,这里的处理,就是判断当前按下的Alt+键是否是控件文本中带下划线的字母。
WM_SETFONT/WM_GETFONT 设置字体/获得字体
mov eax,[ebx].hFont
mov ecx,wParam
mov [ebx].hFont,ecx
设置字体,并返回前一次的字体。
mov eax,[ebx].hFont
直接返回当前使用的字体。
这里的两个消息,我们都自己处理了,是完全性的接管。返回值的定义与标准消息一致。
WM_SETTEXT 设置控件文本
invoke SendParentNotifyMessage,hButt,FBNM_CHANGED
invoke DefWindowProc,hButt,uMsg,wParam,lParam
invoke InvalidateRect,hButt,0,TRUE
首先发送通知消息给父窗口,让父窗口知道,然后使用默认过程,再刷新,这个消息是系统默认的消息,所以要在系统默认窗口过程处理完之后再刷新。每一个控件,都是有一个默认的保存标题的属性的,我们没有自己保存,而是使用默认的文本,因为控件只有一个文本属性,本身也不需要进行处理。如果需要根据返回值取消设置,改成以下设置:
invoke SendParentNotifyMessage,hButt,FBNM_CHANGED
.if eax!=0
invoke DefWindowProc,hButt,uMsg,wParam,lParam
invoke InvalidateRect,hButt,0,TRUE
.endif
这样当父窗口没有处理时,默认返回值是0。就会取消这个操作。
FBM_SETDATA /FBM_GETDATA 设置/获得用户自定义
mov eax,[ebx].dwData
mov ecx,lParam
mov [ebx].dwData,ecx
通过消息保存一个DWORD的数据到控件中。这是标准控件行为。基本上只要是控件都会有。
mov eax,[ebx].dwData
获得用户自定义数据
WM_NCDESTROY 非客户窗口销毁
直接释放所占用的资源,控件只使用了一个内存结构,直接invoke LocalFree,ebx即可。
为什么不是在WM_DESTROY中处理呢?因为写控件时,有可能处理的消息中访问了内存,而这个消息如果在WM_DESTROY消息发生之后,则会发生内存访问错误,比WM_DESTROY消息之后的很多,NC几乎全部都是。
使用这个控件
就这样,这个简单而功能完善的标准平坦按钮控件就编写完成,功能不强,但是很标准,当用户使用时,可以子类化,超类化,接管重绘,完全重绘,而所有的处理方式与Windows中的Button一模一样,UseControl.asm就是测试与使用的程序,其中,通过不同的风格,显示不同外观的按包,鼠标触发,等等。大家可以仔细地用一用,只要按照标准的Button使用方法即可。
当然,还是有很多的地方没有完善的,比如通知消息,现在只有三个,按下/弹出/单击,而标准按钮则有很多个,还有更多功能的消息处理,这些是很容易处理并加上的。没有全部列出是因为这些并不是重点,重点是如何在正确的地方接管正确的消息。 这样用户使用起来不需要费力再学习。
使用的例子程序在这里就不解说了,相信你会很快学会使用本章的 FlatButton 控件。是不是已经感觉到标准控件的魅力了呢?呵呵
控件的发布
本章列出的工程,其实是可以做为写控件的模板的,通过在固定的地方,修改与定义,使用这个模板来快速建立新的控件模块。
控件完成之后,一定要进行多方位的测试,争取把每一个细节都测试到,确认已经可封装,就可以发布了,发布的方式,按需求,可以选择是LIB,还是DLL,区别其实不大,一个是静态链接,一个是动态链接,如果只是一个程序使用,那静态链接是比较好的方式,如果是多个程序公用的,DLL方式更好。
下面就就告诉大家,在MASMPlus中,如何通过简单地改动达到发布为DLL或LIB的方法
发布为LIB
在Control.asm文件选择栏上,单击右键->参数设置:
这是已有的设置,分别是独立编译,然后把OJB与工程一起链接:
改成以下设置:
然后,在工程首文件UseControl.asm引用库文件:
因为在control.inc中,我们已经定义了函数RegisterFlatButton的原型:
所以不需要再在UseControl.asm中使用RegisterFlatButton PROTO :DWORD来声明LIB中的函数原型。
请记住,好的习惯是,所有与控件相关的定义,原型,常数,都放入一个文件中,以提供给目标程序使用。
按Ctrl+1编译:
正在处理工程文件...
ml.exe /c /coff /Fo"Control.obj" "D:\MASMPlus\Project\FlatButton\Control.asm"
link.exe /LIB /OUT:"Control.LIB" "Control.obj"
正在处理工程 ...
ml.exe /c /coff /nologo /Fo"UseControl.obj" "D:\MASMPlus\Project\FlatButton\UseControl.ASM"
rc.exe /Fo"UseControl.res" "D:\MASMPlus\Project\FlatButton\UseControl.rc"
转换 UseControl.RC 到 UseControl.ID ...
link.exe /SUBSYSTEM:WINDOWS /nologo /OUT:"UseControl.exe" "UseControl.obj" "UseControl.RES"
准备就绪:D:\MASMPlus\Project\FlatButton\UseControl.exe
就如上面所示,Control编译后,被链接成了LIB。
发布为DLL
首先按LIB发布方式改好,然后,再把参数设置成如下所示:
参数设置意思是,单独编译,并单独地链接为DLL。
这里需要用使到Control.Def,工程默认已经包含这个文件,在Control.asm所在目录,如果没有,则手动建立与之同名的DEF文件,输入以下内容:
LIBRARY control
DESCRIPTION This Control of Flat button
EXPORTS RegisterFlatButton
第一行是DLL的名字,一定要与编译出来的DLL文件名同名
第二行是库的说明,随便填
第三行是导出函数,这里我们把注册控件的函数导出
然后,把Control.asm中注释掉的DLL过程,LibMain取消掉注释。
再把最后面的END改为END LibMain即可:
按ctrl+1编译:
正在处理工程文件...
ml.exe /c /coff /Fo"Control.obj" "D:\MASMPlus\Project\FlatButton\Control.asm"
link.exe /SUBSYSTEM:WINDOWS /DLL /DEF:"Control.Def" /OUT:"Control.DLL" "Control.obj"
正在处理工程 ...
ml.exe /c /coff /nologo /Fo"UseControl.obj" "D:\MASMPlus\Project\FlatButton\UseControl.ASM"
rc.exe /Fo"UseControl.res" "D:\MASMPlus\Project\FlatButton\UseControl.rc"
转换 UseControl.RC 到 UseControl.ID ...
link.exe /SUBSYSTEM:WINDOWS /nologo /OUT:"UseControl.exe" "UseControl.obj" "UseControl.RES"
准备就绪:D:\MASMPlus\Project\FlatButton\UseControl.exe
小结
目前就到这里,因为编写标准控件涉及到很多的基础知识,实在是不好讲。我的表达能力一直欠佳,这种抽象的知识,难以用语言描述,就看大家的理解能力了。能举一反三的朋友,只要第一篇基本上就不需要再看别的了。
下一章,我会把本章的FLATBUTTON控件改写成更复杂的控件,之后介绍如何使用图像列表,工具栏提示控件,等等。另外,本章列出的工程,其实是可以做为写控件的模板的,通过在固定的地方,修改与定义,使用这个模板来快速建立新的控件模块。同时可以快速地发布为DLL或LIB方式
习题:
通过本章的教程,将控件改成以下样式:
按图中所示,鼠标操作时实现按下/触发。
活用本章所学习到的知识,尝试实现以上分组功能,同时,左侧部分按下时,使用原本的功能发送命令,下拉按钮时,不要去发送命令WM_COMMAND,而是使用通知消息,通知父窗口进行处理,具体是弹出菜单还是其它操作,控件不要管,只管发送消息即可。
有问题,或不懂的地方,可以到我们的论坛提出,我会一一解答,不过请不要提抽象的问题,比如问控件重绘怎么显示不同外观,这种问题真的是答不出来。请提具体一点。
我们的论坛:http://www.aogosoft.com/bbs
AoGo 2007-11-6
Mail: webmaster@aogosoft.com
sixnabs@163.com
--------------------------------------------------------------------------------
<<<上一篇 欢迎访问AoGo汇编小站:http://www.aogosoft.com 下一篇>>>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -