第十八课 通用控件
本课中我们将学习什么是通用控件和如何使用它们。
理论:
win95相对于win3x有几个加强的用户界面控件。其实在win95正式发行前这些控件就在使用,譬如:状态条、工具条等。以前程序员要自己去编程使用它们,现在微软已经把它们包含到了win9x和winnt中了。- toolbar ---工具条
- tooltip ---提示文本
- status bar ---状态条
- property sheet ---属性页单
- property page ---属性页
- tree view ---树型视图
- list view ---列表视图
- animation ---动画
- drag list ---能够处理drag-drop的列表框
- header ---
- hot-key ---热键
- image list ---图象链表
- progress bar ---进程状态条
- right edit ---
- tab ---跳格表
- trackbar ---跟踪条
- up-down ---滚动条
要加载comctl32.dll可以在您的应用程序中调用函数initcommoncontrols。initcommoncontrols函数是动态链接库comctl32.dll中的一个函数,只要在您的程序中的任意地方引用了该函数就、会使得windows的程序加载器pe loader加载该库。函数initcommoncontrols其实只有一条指令“ret”,它的唯一目的是为了使得在调用了个该函数的应用程序的可执行文件的pe头中的“引入”段中包含有comctl32.dll,这样无论什么时候该应用程序都会为您加载该库。所以真正初始化的工作是在该库的入口点处做的,在这里会注册所有的通用控件类,然后所有的通用控件就可以在这些类上进行创建,这就象创建其它的子窗口控件一样。
rtf文本编辑控件则不同。如果您要使用它,就必须调用loadlibrary函数来动态加载,并调用freelibrary来动态地卸载。
现在我们学习如何创建这些通用控件。您可以用资源编辑器把它们放到一个对话框中,或者您也可以自己调用相关的函数来手动创建它们。几乎所有的通用控件都是调用函数createwindowex或createwindow来创建的,您只要在其中传递通用控件的类名即可。有一些通用控件有一些特别的创建函数,但是其实这些函数在内部都调用了createwindowex,只是包装后的函数更方便使用而已。经过包装的函数有:
- createtoolbarex
- createstatuswindow
- createpropertysheetpage
- propertysheet
- imagelist_create
|
|
|
| toolbarwindow32 | toolbar |
| tooltips_class32 | tooltip |
| msctls_statusbar32 | status bar |
| systreeview32 | tree view |
| syslistview32 | list view |
| sysanimate32 | animation |
| sysheader32 | header |
| msctls_hotkey32 | hot-key |
| msctls_progress32 | progress bar |
| richedit | rich edit |
| msctls_updown32 | up-down |
| systabcontrol32 | tab |
property sheets、property pages和image list控件有它们自己的创建函数。drag list其实是可以伸缩的listbox控件,所以它没有自己的类名。上面的类名是vc++的资源编辑器提供的,它们和borland公司的win32 api指南中提出的不一样,和petzold的书《programming windows 95》也不一样。可以肯定的是我们上面列出的类名绝对准确。 这些通用控件可以有通用的窗口类的一些风格,譬如ws_child等。它们当然还有其他的特殊风格,譬如树型视图控件就有tvs_xxxxx风格,列表控件就有lvs_xxxx风格。具体的最好查找有关的win32 api函数指南。 既然我们已经知道了如何创建一个通用控件,我们就可以讨论这些通用控件之间以及和它们的父窗口之间是如何通讯的了。不象子窗口控件,通用控件在某些状态发生变化时不是通过发送wm_command而是发送wm_notify消息和父窗口通讯的。父窗口可以通过发送消息来控制子窗口的行为。对于那些新的通用控件,还有一些新的消息类型。您可以参考您的win32 api手册。
在下面的例子中我们将要实验一下进度条和状态条。
例子代码:
.386.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
winmain proto :dword,:dword,:dword,:dword
.const
idc_progress equ 1 ; control ids
idc_status equ 2
idc_timer equ 3
.data
classname db "commoncontrolwinclass",0
appname db "common control demo",0
progressclass db "msctls_progress32",0 ; the class name of the progress bar
message db "finished!",0
timerid dd 0
.data?
hinstance hinstance ?
hwndprogress dd ?
hwndstatus dd ?
currentstep dd ?
.code
start:
invoke getmodulehandle, null
mov hinstance,eax
invoke winmain, hinstance,null,null, sw_showdefault
invoke exitprocess,eax
invoke initcommoncontrols
winmain proc hinst:hinstance,hprevinst:hinstance,cmdline:lpstr,cmdshow:dword
local wc:wndclassex
local msg:msg
local hwnd:hwnd
mov wc.cbsize,sizeof wndclassex
mov wc.style, cs_hredraw or cs_vredraw
mov wc.lpfnwndproc, offset wndproc