WindowsAPI窗口程序设计-常用控件
WindowsAPI窗口程序设计-常用控件
按钮类
本篇搞一个全是按钮的页面,从上到下分别是普通按钮、图标按钮、位图按钮和自绘按钮,接下来是三个分组框。第一个叫政治面貌,里面有一组单选按钮,分别是中共党员、共青团员、无党派人士。第二个叫个人爱好,里面有3个多选框,分别是看书、唱歌、听音乐。第三个叫荣誉称号,里面有三个三态多选框,即有对勾、有灰色对勾和无对勾,分别是团队核心、技术能手和先进个人。最后有个默认按钮为获取单选复选状态。
常用按钮样式:
枚举值 | 含义 |
---|---|
BS_PUSHBUTTON | 普通按钮 |
BS_NOTIFY | 系统发送带有BN_KILLFOCUS和BN_SETFOCUS通知码的WM_COMMAND消息到父窗口 |
BS_ICON | 图标按钮 |
BS_BITMAP | 位图按钮 |
BS_OWNERDRAW | 自绘按钮,按钮需要重绘时父窗口收到WM_DRAWITEM消息 |
BS_GROUPBOX | 分组框 |
BS_AUTORADIOBUTTON | 自动单选窗口 |
BS_AUTOCHECKBOX | 自动复选框 |
BS_AUTO3STATE | 自动三态复选框 |
BS_DEFPUSHBUTTON | 默认按钮 |
常用属性如下,因为窗口等控件都统称窗口,属性即窗口样式:
枚举值 | 含义 |
---|---|
WS_STOP | 按下Tab时可接收键盘焦点 |
WS_GROUP | 一组控件的第一个控件 |
WS_CHILD | 子窗口 |
WS_VISIBLE | 最初可见 |
例如:
1 | // 全局变量 |
创建17个按钮与分组框:
1 | for (SIZE_T i = 0; i < NUM; i++) |
调整分组框位置:
1 | MoveWindow(hwndButton[4], 10, arrPos[4], 170, 115, TRUE); |
父窗口向子窗口控件发送消息:
1 | LRESULT SendDlgItemMessage( |
对于BS_ICON或BS_BITMAP样式的按钮,发送BM_SETIMAGE消息为按钮设置图标或位图,wParam指定图标IMAGE_ICON或IMAGE_BITMAP,lParam指定为图像句柄HICON或HBITMAP。
1 | // 为图标按钮、位图按钮设置图标、位图 |
其中LoadBitmap
用于从指定模块中加载指定位图资源:
1 | HBITMAP LoadBitmap( |
其中LoadImage
用于加载图标、光标、位图等:
1 | HANDLE WINAPI LoadImage( |
对于fuLoad参数有些常用 选项:
枚举值 | 含义 |
---|---|
LR_DEFAULTCOLOR | 默认值 |
LR_LOADFROMFILE | 黑白方式加载 |
LR_SHARED | 多次加载同一资源时直接返回先前返回的句柄,加载系统图标或光标时必须用这个 |
没指定LR_SHARED时,不再使用加载的图标、光标或位图时需要用DestroyIcon
删除图标、DestroyCursor
删除光标、DeleteObject
删除位图。
设置子窗口控件文本:
1 | BOOL WINAPI SetDlgItemText( |
例如:
1 | // 设置默认按钮的文本 |
用CheckRadioButton
设置单选按钮组,用CheckDlgButton
设置复选按钮组和三态复选按钮组:
1 | BOOL CheckDlgButton( |
这俩函数实现方式都是用SendDlgItemMessage
发送BM_SETCHECK消息,状态有:选中BST_CHECKED、取消选中BST_UNCHECKED、三态复选框灰色不确定状态BST_INDETERMINATE。
当用户单击按钮时,系统向按钮父窗口发送包含BN_CLICKED通知码的WM_COMMAND消息,对于自动单选按钮、自动复选框和自动三态复选框通常不需要处理该消息,自动设置即可,这里只实现默认按钮的处理。
1 | case WM_COMMAND: { |
用IsDlgButtonChecked
获取按钮选中状态,本质就是用SendDlgItemMessage
发送BM_GETCHECK消息:
1 | UINT IsDlgButtonChecked( |
其中处理默认按钮的方法:
1 | VOID OnDefPushButton(HWND hwnd) { |
自绘按钮的处理:
1 | case WM_DRAWITEM: { |
例如子窗口(控件)的可见与隐藏:
1 | ShowWindow(hwndChild, SW_SHOW); |
子窗口的启用与禁用方法:
1 | BOOL WINAPI EnableWindow( |
每个按钮背景都是灰色的,但窗口背景是白色的,很难看。推荐把窗口背景也改成灰色,改按钮背景很麻烦:
1 | wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); |
子窗口控件字体很难看,给子控件发送WM_SETFONT消息即可:
1 | hFont = CreateFont(12, 0, 0, 0, 0, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, TEXT("宋体")); |
其中SendMessage
与SendDlgItemMessage
功能相同:
1 | LRESULT SendMessage( |
源代码:
1 |
|
编辑/文本类
关于界面太难看的问题,可以这样解决,启动控件版本6:
1 |
编辑控件的一些常用属性:
枚举值 | 含义 |
---|---|
ES_AUTOHSCROLL | 对于单行编辑器自动水平滚动 |
ES_PASSWORD | 输入的字符显示为星号 |
ES_NUMBER | 只输入数字 |
界面绘制:
1 | hInstance = ((LPCREATESTRUCT)lParam)->hInstance; |
改字体:
1 | hFont = CreateFont(12, 0, 0, 0, 0, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, TEXT("宋体")); |
编辑框常用消息:
枚举值 | 含义 |
---|---|
EM_SETLIMITTEXT | 限制字符数 |
EM_LINELENGTH | 获取指定行的字符数 不含终止空字符 |
EM_GETLINE | 复制指定行文本并返回复制的字符数 |
限制输入框长度:
1 | // 用户名、密码、年龄分别限制输入20、12、3个字符 |
窗口坐标大小设定:
1 | // 设置程序窗口大小,客户区所需最小大小为320 * 175 |
窗口变动时重新调整:
1 | case WM_SIZE: { |
对于EM_GETLINE消息来说,接收缓冲区的第一个字符必须为缓冲区长度。单行编辑控件不用wParam参数,多行编辑控件在wParam指定具体获取哪一行的,例如:
1 | TCHAR szbuf[128] = { 0 }; |
编辑框的消息一般用于多行编辑控件,单行编辑控件还有更简单的方法,例如获取编辑框中字符串并转换为数值型返回:
1 | UINT WINAPI GetDlgItemInt( |
单击按钮后:
1 | case WM_COMMAND: { |
对于WM_CTLCOLORSTATIC消息来说,针对静态控件、只读或禁用的编辑控件,这里只是用GetSysColorBrush
返回一个白色画刷的画刷句柄:
1 | case WM_CTLCOLORSTATIC: { |
完整代码:
1 |
|
列表框
列表框的常用样式就一个LBS_NOTIFY,当用户单击、双击或取消选中列表框时,向父窗口分别发送包含LBN_SELCHANGE、LBN_DBLCLK、LBN_SELCANCEL通知码的WM_COMMAND消息。
界面布局如下:
1 | hInstance = ((LPCREATESTRUCT)lParam)->hInstance; |
普通列表框可以变成拖动列表框,列表项可以被鼠标拖拽并改变位置:
1 | // 更改为拖动列表框 并注册WM_DRAGLIST消息 |
列表框常用消息:
枚举值 | 含义 |
---|---|
LB_ADDSTRING | 添加一个字符串类型列表项 |
LB_SETITEMDATA | 为一个列表项设置项目数据 |
LB_GETITEMDATA | 获取与一个列表项关联的项目数据 |
LB_SETCURSEL | 选中一个列表项 |
LB_GETCURSEL | 获取当前选中项的索引 |
LB_DELETESTRING | 删除一个列表项 |
LB_INSERTSTRING | 插入指定位置 |
LB_GETCOUNT | 获取列表框列表项总数 |
LB_GETTEXT | 获取指定列表项字符串文本 |
对于LB_ADDSTRING消息,添加到列表末尾,wParam参数缺省,lParam为字符串指针,返回新添加列表项索引。发生错误返回LB_ERR,内存空间不够返回LB_ERRSPACE,例如:
1 | nIndex = SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)TEXT("汇编语言")); |
在这里添加一堆表项:
1 | // 添加一些列表项 |
对于LB_SETITEMDATA消息,wParam指定列表项索引,lParam缺省,发生错误返回LB_ERR。
1 | nResult = SendMessage(hwndListBox, LB_SETITEMDATA, 2, (LPARAM)lpData); |
例如:
1 | // 设置项目数据,具体编程中可以根据需要添加所需的项目数据,例如某些自定义数据的指针 |
对于LB_SETCURSEL消息,wParam指定列表项索引,lParam缺省,发生错误返回LB_ERR:
1 | nCount = SendMessage(hwndListBox, LB_GETTEXTLEN, 2, 0); |
对于LB_GETCURSEL消息,wParam和lParam都缺省,没有选中项返回LB_ERR。
1 | nIndex = SendMessage(hwndListBox, LB_GETCURSEL, 0, 0); |
对于LB_DELETESTRING消息,wParam为列表项索引,lParam缺省,返回剩余列表项个数,发生错误返回LB_ERR。
1 | nCount = SendMessage(hwndListBox, LB_DELETESTRING, 2, 0); |
对于LB_INSERTSTRING消息,wParam指定插入位置索引,-1表示列表末尾,返回新添加列表项索引。发生错误返回LB_ERR,内存不够返回LB_ERRSPACE。
1 | nIndex = SendMessage(hwndListBox, LB_INSERTSTRING, 1, (LPARAM)TEXT("汇编语言")); |
对于LB_GETCOUNT消息,wParam和lParam都缺省,错误返回LB_ERR。
例如增改查操作:
1 | case BN_CLICKED: { |
对于LB_GETTEXT消息,wParam指定列表项索引,lParam为字符串缓冲区,返回字符个数,不含终止空字符。错误返回LB_ERR:
1 | nCount = SendMessage(hwndListBox, LB_GETTEXT, 2, (LPARAM)szBuf); |
对于LB_GETITEMDATA消息,wParam指定列表项索引,lParam缺省,返回指定列表项关联的项目数据。错误返回LB_ERR:
1 | lpData = (LPVOID)SendMessage(hwndListBox, LB_GETITEMDATA, 2, 0); |
更改所选中的列表项时:
1 | // 列表框中的选择已更改 |
编辑矿建内容变化:
1 | // 编辑控件的内容已变化 |
至于拖动部分的处理不讲。
源代码:
1 |
|