(四)给窗口添加控件
在Windows中,控件的本质是一个WS_CHILD样式的子窗口,所以我们想为窗口添加控件,就是要在窗口上添加子窗口。创建控件和创建窗口的方法几乎完全一样,也是调用CreateWindowEx,不同的是,创建控件可以使用预定义的窗口类,不必再自己创建窗口类,也不必写消息处理函数WndProc。
常见的控件窗口类如下,这些类在commctrl.h中有定义(例如L"button"定义为WC_BUTTON):
L"button" 按钮(包含下压按钮、复选框、单选框等)
L"edit" 文本框
L"static" 静态文本
L"listbox" 列表框
L"combobox" 组合框
在这里我们为上一节的窗口添加一个按钮,并处理按下它的消息
一、创建按钮
首先定义按钮的编号,这里定义ID_BUTTON为1
#define ID_BUTTON 1 // 按钮编号(必须小于65536)
窗口在创建时会调用
WM_CREATE消息,此时可以在窗口上创建各种控件,在这里我们创建一个普通按钮,代码如下
其中创建主窗口时的“菜单句柄”这个参数,一般创建控件时这个参数改做“控件编号"使用。
CreateWindowEx(
扩展样式, 窗口类名, 窗口标题, 窗口样式, // 窗口类名有固定名称,窗口样式常用WS_CHILD|WS_VISIBLE
左, 上, 宽, 高,
父窗句柄, 控件编号, 模块句柄, 可选参数 // 菜单句柄作控件编号使用
)
代码如下,注意窗口类名=
L"button",窗口样式=
WS_CHILD|WS_VISIBLE,父窗句柄=
hWnd,控件编号=
(void*)ID_BUTTON:
case WM_CREATE: // 窗口创建
// 创建ID_BUTTON按钮 - CreateWindowEx
// 扩展样式、窗口类名、窗口标题、窗口样式(类名=“button”,样式=子窗口+可见)
// 左、上、宽、高
// 父窗句柄、控件编号、模块句柄、可选参数(菜单句柄=控件编号)
CreateWindowEx(
0, L"button", L"按钮", WS_CHILD | WS_VISIBLE,
100, 20, 100, 30,
hWnd, (void*)ID_BUTTON, hInst, NULL);
return 0;
二、响应消息
按钮被按下的消息为
WM_COMMAND,其中WndProc的
第三个参数wp
低16位表示对应的控件编号,可使用
LOWORD(wp)提取之。
在这里我们在按钮按下时弹出一个消息框,代码如下:
case WM_COMMAND: // 接收到命令消息
switch (LOWORD(wp)) // 判断来源编号(包含在参数wp的低16位中)
{
case ID_BUTTON: // 来自ID_BUTTON按钮
MessageBox(hWnd, L"欢迎来到Win32编程世界", L"消息框", 0); // 弹出消息框
return 0;
}
break; // 消息未处理
三、运行效果
窗口中出现一个按钮,按下这个按钮,弹出一个消息框。
四、美化控件
我们新建的按钮有点丑,因为系统默认使用Common Controls V5(通用控件版本5),是Windows 98样式的,如果想让控件具有Windows XP以及以后系统的样式,需要指定应用程序使用Common Controls V6(通用控件版本6),最简单的方法是在代码中添加以下几行:
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
使用效果如下: