今天学习了win32下的按钮控件,主要是普通按钮,单选按钮,复选框按钮.web
效果如图:windows
代码以下:svg
#include <windows.h> /** * 按钮风格 * BS_PUSHBUTTON: 指定一个命令按钮 * BS_CHECKBOX: 指定在矩形按钮的右侧带有标题的选择框,不会自动反选 * WS_TABSTOP: tap键能够停留在上面 */ LRESULT CALLBACK myWndProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { switch (message) { case WM_CREATE: { //在这里建立子窗口和控件 //建立普通按钮 HWND hwnd_btn = CreateWindow( L"Button", L"普通按钮", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 15,5, 100,40, hwnd,//指定button按钮的父窗口 (HMENU)10000, //控件ID号替代menu,控件ID号惟一 ((LPCREATESTRUCT)lparam)->hInstance, NULL ); //建立单选按钮 HWND hwnd_btn2 = CreateWindow( L"Button", L"单选按钮", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 15, 50, 100, 40, hwnd,//指定button按钮的父窗口 (HMENU)10001, //控件ID号替代menu,控件ID号惟一 ((LPCREATESTRUCT)lparam)->hInstance, NULL ); //复选框按钮 HWND hwnd_btn3 = CreateWindow( L"Button", L"复选按钮", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 15, 95, 100, 40, hwnd,//指定button按钮的父窗口 (HMENU)10002, //控件ID号替代menu,控件ID号惟一 ((LPCREATESTRUCT)lparam)->hInstance, NULL ); //如何识别这些按钮的点击消息? //当点击按钮控件的时候,会像父窗口发送命令消息WM_COMMAND // BN_CLICKED: 用户在按钮上单击鼠标时会像父窗口发送BN_CLICKED消息. // BN_DOUBALECLICKED: 同上,发送双击 BN_DOUBLECLICKED消息. } break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_COMMAND: { //根据控件ID来进行区分 switch (LOWORD(wparam))//低字节是控件ID { case 10000: if (HIWORD(wparam) == BN_CLICKED) //高位字节是控件触发的消息类型 { MessageBox(hwnd, L"点击了普通按钮!", L"提示", MB_OK); } break; case 10001: { MessageBox(hwnd, L"点击了单选按钮!", L"提示", MB_OK); HWND hbutton_radio = (HWND)lparam; //获取单选按钮的选中状态 if(SendMessage(hbutton_radio,BM_GETCHECK,0,0) == BST_CHECKED ) { MessageBox(hwnd, L"单选按钮被选中!", L"提示", MB_OK); } else if ( SendMessage(hbutton_radio, BM_GETCHECK, 0, 0) == BST_UNCHECKED ) { MessageBox(hwnd, L"单选按钮没有被选中!", L"提示", MB_OK); } } break; case 10002: { MessageBox(hwnd, L"点击了复选按钮!", L"提示", MB_OK); HWND hbutton_check = (HWND)lparam; //获取复选框的选中状态 if (SendMessage(hbutton_check,BM_GETCHECK,0,0) == BST_CHECKED ) { MessageBox(hwnd, L"复选按钮被选中!", L"提示", MB_OK); } else if (SendMessage(hbutton_check, BM_GETCHECK, 0, 0) == BST_UNCHECKED) { MessageBox(hwnd, L"复选按钮没有被选中!", L"提示", MB_OK); } } break; default: break; } } break; default: break; } return DefWindowProc(hwnd, message, wparam, lparam); } int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) { //1.注册窗口类 WNDCLASS wnd; wnd.cbClsExtra = 0; wnd.cbWndExtra = 0; wnd.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); wnd.hCursor = LoadCursor(hInstance, IDC_ARROW); wnd.hIcon = LoadIcon(hInstance, IDI_APPLICATION); wnd.lpszClassName = L"zhangkai"; wnd.lpszMenuName = NULL; wnd.lpfnWndProc = myWndProc; wnd.style = CS_HREDRAW | CS_VREDRAW; wnd.hInstance = hInstance; int ec = RegisterClass(&wnd); if ( ec == 0 ) { ec = GetLastError(); return ec; } //2.建立窗口 HWND hwnd = CreateWindow(L"zhangkai", L"window title", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL); if (hwnd == NULL) { //create window file return 0; } ShowWindow(hwnd, nShowCmd); UpdateWindow(hwnd); //3.消息循环 MSG msg; while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; }
接下来讲重点:函数
首先在win32下全部的控件其实都是子窗口.,因此咱们收到WM_CREATE消息后,建立控件的.学习
Button的class是 L"Button",不区分大小写,样式底层已经固定好了的.ui
HWND hwnd_btn = CreateWindow( L"Button", L"普通按钮", **WS_CHILD | WS_VISIBLE** | BS_PUSHBUTTON, 15,5, 100,40, hwnd,//指定button按钮的父窗口 (HMENU)10000, //控件ID号替代menu,控件ID号惟一 ((LPCREATESTRUCT)lparam)->hInstance, NULL );
建立的HMEU选项,这里是用来作控件ID,所以咱们必须保证控件ID的惟一,window style必须是WS_CHILD.spa
接下来介绍button的按钮事件 :code
当按钮被按下后,首先会像父窗口的处理函数发送WM_COMMAND消息,注意不是发送到窗口的消息循环函数中的.xml
那么问题来了,全部的窗口都会像父窗口发送WM_COMMAND消息,那么怎么进行区分控件呢?究竟是哪一个控件来发送的WM_COMMAND呢?blog
LRESULT CALLBACK myWndProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
咱们来看上面的窗口处理函数 :
message已经固定了,确定是WM_COMMAND,那么很天然的,咱们要借助wparam和lparam来进行区分了.
lparam在按钮事件中表明的是HWND,表示标准控件的窗口句柄.
wparam进行了区分:
高位表示按钮的消息类型,地位表示控件的id.
因此咱们通常的 处理方式是:
WORD nID = LOWORD(wparam);//区分究竟是哪个控件 WORD nCode = HTWORD(wparam);//控件的事件类型,好比BST_CHECKED / BST_UNCHECKED