- WM_COMMAND产生的条件:点击菜单, 点击加速键,点击子窗口按钮,点击工具栏按钮,点击列表框。这些时候都有command消息产生
- wParam 高16位通知码,低16位命令ID, lParam 发送命令消息的子窗体句柄。
菜单的定义
菜单ID MENU [DISCARDABLE]
BEGIN
POPUP 菜单文字 [,选项列表]
BEGIN
MENUITEM 菜单项文字,菜单项ID [,选项列表]
MENUITEM SEPARATOR //定义菜单项之间的分割线
END
END
- 菜单项ID——用来分辨不同的菜单项。当菜单被选中的时候,windows会向窗口过程发送WM_COMMAND消息,消息的参数就是这个菜单项ID。用菜单项ID可以分辨用户究竟选中了哪个菜单项。
菜单项的选项——用来定义菜单项的各种属性
- CHECKED——表示打上选定标志(对钩)
- GRAYED——表示菜单项是灰化的
- INACTIVE——表示菜单项是禁用的
- MENUBREAK 或 MENUBARBREAK——表示将这个菜单项和以后的菜单项列到新的列中
加速键的定义
加速键ID ACCELERATORS
BEGIN
键名,命令ID [,类型] [,选项]
END
- 键名——表示加速键对应的案件,可以有三种方式定义
- “^字母”:表示Ctrl键加上字母键
- “子母”:表示字母,这时类型必须指明是VIRTKEY
- 数值:表示ASCLL码为该值的字母,这时类型必须指明为ASCLL
- 命令ID——按下加速键后,windows向程序发送的命令ID。如果想把加速键和菜单项关联起来,这里就是要关联菜单项的ID
- 类型——用来指定键的定义方式,可以是VIRTKEY和ASCLL,分别用来表示“键名”字段定义的是虚拟键还是ASCLL码。
- 选型——可以是Alt,Control或Shift中的单个或多个,如果指定多个,则中间用逗号隔开,表示加速键是按键加上这些控制键的组合键
图标和光标的资源定义
图标ID ICON [DISCARDABLE] 图标文件名
光标ID CURSOR [DISCARDABLE] 光标文件名
对话框资源定义
对话框ID DIALOG [DISCARDABLE] x坐标,y坐标,宽度,高度
[可选属性]
BEGIN
子窗口控件
END
创建模态对话框
invoke DialogBoxParam,hInstance,lpTemplateName,hWndParent,lpDialogFunc,dwInitParam
- lpTemplateName,函数从hInstance参数指定的模块中装入 lpTemplateName参数指定的对话框资源。
- hWndParent,对话框的父窗口,对话框关闭之前将无法切换到父窗口所属的其他窗口中。
- lpDialogFunc,指定了对话框过程的地址,
- dwInitParam,当做WM_INITDIALOG消息的lParam传给对话框过程,自定义用途。
创建非模态对话框
invoke CreateDialogParam,hInstance,lpTemplateName,hWndParent,lpDialogFunc,dwInitparam
mov hDlg,eax
CreateDialogParam和DialogBoxParam在使用中有几个不同点:
- CreateDialogParam 在创建对话框后,会根据对话框模板的风格是否定义了WS_VISIBLE来决定是否显示对话框窗口。如果定义了则显示,没有定义,则程序需要在以后自行调用ShowWindow来显示它;而DialogBoxParam函数不管是否定义都会显示对话框。
- CreateDialogParam在建立对话框窗口后直接返回,返回值是对话框窗口的句柄;而DialogBoxParam需要在对话框关闭后才返回,返回值是EndDialog中的dwResult参数。
- 由于在CreateDialogParam返回后,应用程序在自己的消息循环中获取对话框消息,所以如果要用非模态对话框来做程序的主窗口,消息循环的代码还是要写的;而DialogBoxParam是使用Windows为它内建的消息循环
- 关闭非模态对话框仍然使用DestroyWindow函数。
对话框过程和普通窗口过程的区别
- 窗口过程对应于不同的消息有各种不同含义的返回值,而对话框过程返回BOOL类型的值,返回TRUE表示已经出了某条消息,返回FALSE表示没有处理。“对话框管理器”代码会根据返回值决定是否继续处理某条消息(唯一的例外是WM_INITDIALOG消息)
- 对于不处理的消息,不需要调用DefWindowProc来处理,这事情由“对话框管理器”来做。
在对话框中使用子窗口控件
- 子窗口控件的定义
CONTROL 文本 ,ID,类,风格,x,y,宽度,高度 [,扩展风格]
控件名称 [文本,] ID,x,y,宽度,高度,[,风格] [,扩展风格]
控件名称 | 说明 | 基于的类 | 默认窗口风格 |
---|---|---|---|
PUSHBUTTON | 按钮 | Button | BS_PUSHBUTTON,WS_TABSTOP |
DEFPUSHBUTTON | 默认按钮 | Button | BS_DEFPUSHBUTTON,WS_TABSTOP |
CHECKBOX | 复选框 | Button | BS_CHECKBOX,WS_TABSTOP |
AUTOCHECKBOX | 自动复选框 | Button | BS_AUTOCHECKBOX,WS_TABSTOP |
STATE3 | 3态复选框 | Button | BS_3STATE,WS_TABSTOP |
AUTO3STATE | 自动3态复选框 | Button | BS_AUTO3STATE,WS_TABSTOP |
RADIOBUTTON | 单选钮 | Button | BS_RADIOBUTTON,WS_TABSTOP |
AUTORADIOBUTTON | 自动单选钮 | Button | BS_AUTORADIOBUTTON,WS_TABSTOP |
GROUPBOX | 分组框 | Button | BS_GROUPBOX |
SCROLLBAR | 滚动条 | ScrollBar | SBS_HORZ |
CTEXT | 居中文本 | Static | SS_CENTER,WS_GROUP |
LTEXT | 左对齐文本 | Static | SS_LEFT,WS_GROUP |
RETEXT | 右对齐文本 | Static | SS_RIGHT,WS_GROUP |
ICON | 图标框 | Static | SS_ICON |
EDITTEXT | 文本编辑 | Edit | ES_LEFT,WS_BORDER,WS_TABSTOP |
COMBOBOX | 组合框 | ComboBox | CBS_ SIMPLE,WS_TABSTIOP |
LISTBOX | 列表框 | ListBox | LBS_NOTIFY,WS_BORDER |
子窗口控件的通用使用方法
-
由于子窗口控件实际上就是窗口,大部分窗口函数对它们都是适用的,如可以用
EndbleWindow
在灰化和允许状态之间切换,可以用ShowWindow
在显示和隐藏之间切换,可以用GetWindowText
t和SetWindowText
来改变上面的文字,也可以用MoveWindow
来改变大小和移动位置。 -
在资源脚本文件中定义的是控件的ID,当这些子窗口控件被创建以后同样会有一个窗口句柄,用函数
GetDlgItem
来获取子窗口句柄,用GetDlgCtrlID
或GetWindowLong
函数来获取子窗口句柄 -
向控件发消息用
SendDlgItemMessage
,如果想要知道在控件上按下Tab键后会跳到哪个控件上去,可以使用GetNextDlgTabItem
使用单选框和复选框
- 查看一个单选框或复选框是否被选中可以用
isDlgButtonChecked
来检测 - 选中单选框或复选框可以用’CheckDlgButton’函数
使用静态控件
- 静态控件是基于static类的子窗口控件,它是“安静的”——它们不向对话框发送WM_COMMAND消息。
用法:
-用SetWindowText
或发送WM_SETTEXT消息来动态改变显示的文本,也可以用GetWindowText
或发送WM_GETTEXT消息来获取其中的文本。
- 静态控件还有一个用途是做图形显示,可以通过向控件发送STM_SETIMAGE消息来设置新的图片,消息的wParam指定图片的格式,取值可以是IMAGE_BITMAP,IMAGE_CURSOR和IMAGE_ICON,lParam是图片的句柄。
使用文本编辑控件
-
每当用户在文本编辑控件中输入一个字符的时候,控件就会向对话框发送一个WM_COMMAND消息。要获得编辑框中的文本有多种办法,可以用
GetWindowText
,也可以用发送WM_GETTEXT消息的办法,要设置文本,同样可以用GetWindowText
或发送WM_SETTEXT,但最简单的是使用GetDlgItemText
和SetDlgItemText
函数 -
文本编辑控件输入输出数值型参数,使用函数
SetDlgItemInt
和GetDlgItemInt
使用滚动条
- 水平滚动条向对话框发送WM_HSCROLL,垂直滚动条则发送WM_VSCROLL消息,消息的参数:wParam的低16位是滚动条的动作码,高16位是滚动条当前位置。lParam是滚动条控件的窗口句柄。只有当动作码是SB_THUMBPOSTION或SB_THUMBTRACK时才有效,其他时候为0.
滚动条的动作码:
-
SB_BOTTOM ——滚动条移到了最下/右边
-
SB_ENDSCROLL——用户停止了滚动动作
-
SB_THUMBPOSITION——滚动条被拖动到某处。
-
SB_THUMBTRACK——滚动条在拖动中
-
SB_TOP——滚动条移到了最上边/左边
-
SB_LINELEFT——滚动条左移了一格(对于水平滚动条)
-
SB_LINERIGHT——滚动条右移了一格(对于水平滚动条)
-
SB_PAGELEFT——滚动条左移了一页(对于水平滚动条)
-
SB_PAGERIGHT——滚动条右移了一页(对于水平滚动条)
-
SB_LINEDOWN——滚动条下移了一格(对于垂直滚动条)
-
SB_LINEUP——滚动条上移了一格(对于垂直滚动条)
-
SB_PAGEDOWN——滚动条下移了一页(对于垂直滚动条)
-
SB_PAGEUP——滚动条上移了一页(对于垂直滚动条)
-
在初始化的时候,要发送SBM_SETRANGE消息来设定滚动范围
invoke SendDlgItemMessage,hWnd,IDC_SCROLL,SB_SETRANGE,最小值,最大值
-
计算好新的位置后,发送向滚动条发送SB_SETPOS消息设置滚动条位置。
-
获取滚动条信息,可以发送SBM_GETPOS可以获取滚动条当前位置,SBM_GETRANGE可以获取滚动的范围。
使用组合框
- 当用户在组合框中进行选择操作时,Windows向对话框过程发送WM_COMMAND消息,wParam参数的的低16位是组合框ID,高16位是通知码,用来表示用户的操作
消息 | wParam | lParam | 说明 |
---|---|---|---|
CB_ADDSTRING | 0 | 字符串地址 | 把一个字符串添加到列表中 |
CB_INSERTSRTING | 位置索引 | 字符串地址 | 把一个字符串插入到列表中 |
CB_FINDSTRING | 开始查找的位置索引 | 查找的字符串 | 在列表中查找以lParam字符串开头的项,找到则返回位置索引,未找到则返回CB_ERR |
CB_FINDSRTINGXACT | 位置索引 | 查找的字符串 | 精确查找字符串 |
CB_DELETESTRING | 位置索引 | 0 | 删除一个列表项 |
CB_RESETCONTENT | 0 | 0 | 删除所有的列表项 |
CB_GETLBTEXT | 位置索引 | 缓冲区地址 | 获取指定列表项的字符串,缓冲区必须足够大 |
CB_GETLBTEXTLEN | 位置索引 | 0 | 获取指定列表项的字符串长度 |
CB_GETCOUNT | 0 | 0 | 获取列表项的总项数 |
CB_SETCURSEL | 位置索引 | 0 | 选中一个列表项,并将列表项中的文字拷贝到编辑控件中 |
CB_SELECTSTRING | 开始查找的位置索引 | 字符串地址 | 查找以lParam指定的字符串开始的列表项,如果找到则选中它并将字符串拷贝到编辑控件中 |
CB_GETCURSEL | 0 | 0 | 获取当前选中的位置索引,没有选中额项目则返回CB_ERR |
CB_SHOWDROPDOWN | 状态 | 0 | 打开(状态为TRUE)或收起(状态为FALSE)下拉列表 |
CB_GETDROPPEDSTATE | 0 | 0 | 检测列表的当前下拉状态,返回TRUE表示拉下,FALSE表示收起 |
通知码 | 说明 |
---|---|
CBN_SELCHANGE | 用户将要选择一个项目(鼠标移动到了这个项目上) |
CBN_CLOSEUP | 下拉列表关闭(可能是选择完成也可能是取消选择) |
CBN_SELENDOK | 用户完成选择项目 |
CBN_SELENDCANCEL | 用户取消选择(鼠标移动到了某个项目上,但并没有按下而是点击了其他控件,或按了Esc键) |
CBN_DBLCLK | 在CBS_SIMPLE的组合框中双击了一个列表项 |
CBN_DROPDOWN | 用户打开了下拉框(按动了编辑框边的下拉按钮) |
使用列表框
风格 | 说明 |
---|---|
LBS_DISABLENOSCROLL | 在不需要滚动的时候也显示垂直滚动条 |
LBS_EXTENDEDSEL | 在多选列表框中允许按住Shift键的同时选中一个范围 |
LBS_MULTIPLESE | 允许多选,如果不定义的话则是单选列表框 |
LBS_NOSEL | 列表框项目只能查看不能选择 |
LBS_NOTIFY | 用户单击或双击项目时向父窗口发送WM_COMMAND消息 |
LBS_SORT | 自动按字母顺序排序插入的项目 |
LBS_USETABSTOPS | 列表框项目的文本中允许将Tab字符的位置展开 |
LBS_STANDARD | 组合LBS_NOTIFY,LBS_SORT,WS_VSCROLL和WS_BORDER (单选列表定义此风格) |
当列表框有LBS_NOTIFY风格,用户有所动作列表框会向父窗口发送WM_COMMAND消息,wParam高16位是通知码,
列表框的通知码:
- LBN_DBLCLK——用户双击了一个项目
- LBN_ERRSPACE——插入项目时无法申请到足够的内存
- LBN_KILLFOCUS——输入焦点被切换到其他控件中,列表框丢失了焦点
- LBN_SELECANCEL——用户撤销了一个选择
- LBN_SELECHANGE——选定状态改变
- LBN_SETFOCUS——列表框得到输入焦点
列表框通知父窗口是通过发送WM_COMMAND消息,而程序控制列表框是通过向列表框发送消息来完成的
消息 | wParam | lParam | 说明 |
---|---|---|---|
LB_ADDSTRING | 0 | 字符串地址 | 添加一个项目,返回加入后的索引 |
LB_DELETESTRING | 位置索引 | 0 | 删除一个项目,返回剩余的项数 |
LB_FINDSTRING | 开始索引 | 字符串地址 | 查找以字符串开头的项目,找到则返回位置索引,未找到则返回LB_ERR |
LB_FINDSTRINGGEXACT | 开始索引 | 字符串地址 | 精确查找一个项目,返回值同上 |
LB_GETANCHORINDEX | 0 | 0 | 返回多选列表框多选时的起始位置 |
LB_GETCARETINDEX | 0 | 0 | 多选列表框中的当前焦点项目位置 |
LB_GETCOUNT | 0 | 0 | 返回列表框中的项目数 |
LB_GETCURSEL | 0 | 0 | 返回单选列表框当前选中的项目的索引 |
LB_GETSEL | 位置索引 | 0 | 检测指定项目的选中状态,返回非0为选中,返回0为未选中 |
LB_GETSELCOUNT | 0 | 0 | 返回多选列表框选中项目的总数 |
LB_GETSELITEMS | 最大项数 | 缓冲区地址 | 返回多选列表框的选中项目索引列表到缓冲区中 |
LB_GETTEXT | 位置索引 | 缓冲区地址 | 返回某个项目的字符串 |
LB_GETTEXTLEN | 位置索引 | 0 | 返回某个项目的字符串长度 |
LB_GETTOPPINDEX | 0 | 0 | 返回当前可见的第一个项目位置 |
LB_INSERTSTRING | 插入位置 | 字符串地址 | 在指定位置插入一个项目 |
LB_RESETCONTENT | 0 | 0 | 删除所有项目 |
LB_SELECTSTRING | 开始位置 | 字符串地址 | 将以指定字符串开头的项目选中 |
LB_SETCURSEL | 位置索引 | 0 | 在单选列表框中选中一个项目 |
LB_SETSEL | 选择状态 | 位置索引 | 在多选框中将一个项目选中或清除 |
LB_SETTOPPINDEX | 位置索引 | 0 | 滚动显示到指定的项目 |
LB_DIR | 属性 | 文件通配符 | 搜索目录并将符合文件通配符的文件名加入到列表框中 |
LB_SELITEMRANGE | 选择状态 | 范围 | 在多选框中将一个范围选中或清除 |
LB_DIR可以指定目录中的文件名自动累出来并加入到列表框中。LB_DIR消息中wParam参数可以指定的属性:
- DDL_ARCHIVE——加入归档属性的文件
- DDL_DIRECTORY——加入目录
- DLL_DRIVES——加入驱动器名
- DLL_HIDDEN——包含隐藏文件
- DLL_READONLY——包含可读写的文件
- DLL_SYSTEM——包含系统文件
字符串资源
在资源脚本中定义字符串的语法是:
STRINGTABLE [DISCARDABLE]
BEGIN
字符串ID1 "字符串1"
字符串ID2 "字符串2"
END
版本信息资源的定义
- FILEVERSION—定义文件版本号,可以定义4个16位版本号xx.xx.xx.xx
- PRODUCTVERSION——定义产品版本号,可以定义4个16位版本号xx.xx.xx.xx
- FILEFLAGSMASK——指定FILEFLAGS属性中哪些位有效。
- FILEFLAGS——文件标志,是一些标志位的组合:VS_FF_PATCHED,VS_FF_DEBUG,VS_FF_PRIVATEBUILD,BS_FF_INFOINFERRED,VS_FF_PRERELEASE和VS_FF_SPECI_ALBUILD.
- FILEOS——定义适用的操作系统,可定义为VOS_UNKNOWN,VOS_DOS,VOS_NT,VOS_WINDOWS16,VOS_WINDOWS32,VOS_DOS_WINDOWS16,VOS_DOS_WINDOWS32或VOS_NT_WINDOWS32.
- FILETYPE——定义文件类型。
使用二进制资源
win32资源中允许用户自己定义二进制的资源或者自定义格式的资源,资源内容可以是任何数据,可以将一个磁盘文件按二进制格式包括进去,二进制资源的格式是:
资源ID RCDATA [DISCARDABLE]
BEGIN
数据定义
END
也可以用一个磁盘文件当做资源
资源ID RCDATA [DISCARABLE] 文件名
在程序使用资源内容时,可以通过以下步骤将资源装入内存使用:
(1). 用 FindResource
函数查找资源,如果找到资源则返回资源信息的句柄。
(2). 用LoadResource
函数装入资源,装入成功后会返回一个资源句柄
(3). 用LockResource
函数将资源锁定到内存中,函数返回资源装入的内存地址,程序就可以使用内存中的数据了。
(4). 如果想知道装入的资源的大小是多少,可以使用FindResource
返回的句柄来调用SizeofResource
从而得到资源大小。
使用自定义资源
自定义资源的定义格式比二进制资源更灵活,它和二进制资源的区别在于可以指定资源类别为自定义的名称:
资源ID 类型ID [DISCARDABLE]
BEGIN
数据定义
END
或用一个磁盘文件当做资源的内容:
资源ID 类型ID [DISCARDABLE] 文件名
类型ID要大于255的数值或字符串