WIN32下的按钮标准控件

今天学习了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