C++ Windows窗口程序:子窗口控件之按钮类button

这篇博客介绍了在Windows窗口程序设计中如何使用CreateWindow函数创建不同类型的按钮控件,包括普通按钮、默认按钮、单选按钮、复选按钮、三态按钮、自动单选按钮、自动复选按钮、自动三态按钮、分组框和自画类型按钮。通过设置不同的窗口风格和按钮风格,可以实现各种交互效果。示例代码展示了如何在WM_CREATE和WM_COMMAND消息中处理按钮创建和点击事件。
摘要由CSDN通过智能技术生成

Windows窗口程序设计中,按钮、文本编辑框等控件都作为一个子窗口在WM_CREATE事件中创建的。其中按钮类button有多种类型和风格,常见的单选钮、复选钮、分组框也在此类中,见下表:

子窗口控件:按钮类button

按钮类型,可以是按钮风格与窗口风格的组合

窗口风格:
WS_CHILD             子窗口,必须有
WS_VISIBLE           窗口可见,一般都有
WS_DISABLED          禁用窗口,创建初始状态为灰色不可用的按钮时使用
WS_TABSTOP           可用Tab键选择
WS_GROUP             成组,用于成组的单选按钮中的第一个按钮

按钮风格:
BS_PUSHBUTTON        下压式按钮,也即普通按钮
BS_CHECKBOX          复选按钮,不常用
BS_AUTOCHECKBOX      含自动选中状态的复选按钮
BS_RADIOBUTTON       单选按钮,不常用
BS_AUTORADIOBUTTON   含自动选中状态的单选按钮
BS_3STATE            三态复选按钮,不常用
BS_AUTO3STATE        含自动选中状态的三态复选按钮
BS_GROUPBOX          分组框,用来放置单选或复选按钮的
BS_OWNERDRAW         用于自定义形状的类型,比如画个圆形的按钮

以上风格指定了创建的按钮类型,不能同时使用,但必须有其一
其中非自动类型的按钮需要自己编程来实现选中与否的状态切换

BS_BITMAP            按钮上将显示位图
BS_DEFPUSHBUTTON     设置为默认按钮,只用于下压式按钮,一个对话框中只能指定一个默认按钮

创建方法:
        HWND hwndButton;
        hwndButton = CreateWindow ( TEXT("button"),        /*子窗口类名称*/
                TEXT("Command Button"),                    /*按钮上的文字*/
       			WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,     /*按钮类型*/
           		left, top, width, height,                  /*位置*/
                hwnd,                                      /*父窗口句柄*/
                (HMENU)IDcmdButton,                        /*按钮ID,一个自定义整型常量*/
                ((LPCREATESTRUCT) lParam)->hInstance, NULL);

		if (!hwndButton) MessageBox(NULL,"创建按钮失败","Message",MB_OK|MB_ICONERROR);
		ShowWindow(hwndButton,SW_SHOW);
        UpdateWindow(hwndButton);

再来用DEV-C++的windows application示例代码,创建这十种button类按钮。(代码获得方法见上一篇博文《C++ 用DEV-C++建一个Windows窗口程序带文本框和命令按钮》)

先建一个结构数组,存放这些按钮类型常数:

struct button {
	int swStyle;
	const char *szText;
}
Buttons[] = {
	BS_PUSHBUTTON,		TEXT("普通按钮"),
	BS_DEFPUSHBUTTON,	TEXT("默认按钮"),
	BS_RADIOBUTTON,		TEXT("单选按钮"),
	BS_CHECKBOX,		TEXT("复选按钮"),
	BS_3STATE,			TEXT("三态按钮"),
	BS_AUTORADIOBUTTON,	TEXT("自动单选按钮"),
	BS_AUTOCHECKBOX,	TEXT("自动复选按钮"),
	BS_AUTO3STATE,		TEXT("自动三态按钮"),
	BS_GROUPBOX,		TEXT("按钮分组框"),
	BS_OWNERDRAW,		TEXT("自画类型按钮")
};

然后在WM_CREATE事件中遍历数组创建全部按钮,在WM_COMMAND事件中写入鼠标单击响应代码就完成了:

#include <windows.h>

struct button {
	int swStyle;
	const char *szText;
}
Buttons[] = {
	BS_PUSHBUTTON,		TEXT("普通按钮"),
	BS_DEFPUSHBUTTON,	TEXT("默认按钮"),
	BS_RADIOBUTTON,		TEXT("单选按钮"),
	BS_CHECKBOX,		TEXT("复选按钮"),
	BS_3STATE,			TEXT("三态按钮"),
	BS_AUTORADIOBUTTON,	TEXT("自动单选按钮"),
	BS_AUTOCHECKBOX,	TEXT("自动复选按钮"),
	BS_AUTO3STATE,		TEXT("自动三态按钮"),
	BS_GROUPBOX,		TEXT("按钮分组框"),
	BS_OWNERDRAW,		TEXT("自画类型按钮")
};

/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	int num = sizeof Buttons / sizeof Buttons[0];
	switch(Message) {
		//在 WM_CREATE 事件中创建所有按钮类型 
		case WM_CREATE: {
			for (int i = 0; i < num; i++) {
				CreateWindow( TEXT("button"),
				Buttons[i].szText,
				WS_CHILD | WS_VISIBLE | WS_TABSTOP | Buttons[i].swStyle,
				80 + (i >= num / 2 ? 240 : 0),
				60 + i * 50 - (i >= num / 2 ? 250 : 0),
				160, 40,
				hwnd,
				(HMENU)i,
				((LPCREATESTRUCT) lParam)->hInstance,
				NULL);
			}
			break;
		}
		
		//在 WM_COMMAND 事件中会响应button类的鼠标单击,但其中GROUPBOX不响应操作
		case WM_COMMAND: {
			MessageBox(NULL, Buttons[LOWORD(wParam)].szText, "Button_Click()", MB_OK);
			break;
		}
				
		/* Upon destruction, tell the main thread to stop */
		case WM_DESTROY: {
			PostQuitMessage(0);
			break;
		}
		
		/* All other messages (a lot of them) are processed using default procedures */
		default:
			return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}
 
/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc; /* A properties struct of our window */
	HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
	MSG msg; /* A temporary location for all messages */
 
	/* zero out the struct and set the stuff we want to modify */
	memset(&wc,0,sizeof(wc));
	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.lpfnWndProc	 = WndProc; /* This is where we will send messages to */
	wc.hInstance	 = hInstance;
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	
	/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszClassName = "WindowClass";
	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
 
	if(!RegisterClassEx(&wc)) {
		MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}
 
	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Button Style",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, /* x */
		CW_USEDEFAULT, /* y */
		640, /* width */
		480, /* height */
		NULL,NULL,hInstance,NULL);
 
	if(hwnd == NULL) {
		MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}
 
	/*
		This is the heart of our program where all input is processed and 
		sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
		this loop will not produce unreasonably high CPU usage
	*/
	while(GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
		TranslateMessage(&msg); /* Translate key codes to chars if present */
		DispatchMessage(&msg); /* Send it to WndProc */
	}
	return msg.wParam;
}

运行效果图:

好的,以下是一个简单的 C++ Windows 窗口程序,其中包含一个按钮和一段文字: ```c++ #include <windows.h> // 窗口过程函数 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // WinMain 函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 注册窗口 WNDCLASS wc = { 0 }; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = "MyWindowClass"; RegisterClass(&wc); // 创建窗口 HWND hwnd = CreateWindow("MyWindowClass", "My Window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 300, NULL, NULL, hInstance, NULL); // 创建按钮 HWND button = CreateWindow("BUTTON", "Click me!", WS_VISIBLE | WS_CHILD, 10, 10, 80, 30, hwnd, (HMENU)1, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL); // 显示窗口 ShowWindow(hwnd, nCmdShow); // 消息循环 MSG msg = { 0 }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // 返回退出代码 return msg.wParam; } // 窗口过程函数 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_COMMAND: if (LOWORD(wParam) == 1) { MessageBox(hwnd, "Hello, world!", "Message", MB_OK); } break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } ``` 这个程序会创建一个窗口窗口中包含一个按钮和一段文字。当用户点击按钮时,程序会弹出一个对话框显示一条消息。您可以根据您的实际需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hann Yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值