首页
社区
课程
招聘
[原创]C++ Window API 学习笔记 - 标准控件调用代码演示
2021-5-28 15:18 4226

[原创]C++ Window API 学习笔记 - 标准控件调用代码演示

2021-5-28 15:18
4226

C++ Window API 学习笔记 - 标准控件调用代码演示

一;按钮

    1:按钮的种类

    按钮控件允许用户通过单击来执行操作,其功能可以显示文本,又可以显示图像,当按钮被单击的时候,它看起来被按下,然后被释放。按钮是Windows标准控件。也是子窗口,其窗口类名为button。

    其主要分为如下:

  • 按钮(Button)

  • 单选按钮(Radio Button)

  • 复选按钮(Check Button)

    2;按钮消息

    对于我们操作按钮,同样会产生消息。一般按钮控件会向父窗口发送命令消息“WM_COMMAND”消息。即我们如果需要处理按钮控件,可以匹配“WM_COMMAND”消息。其他简单消息如下:

BN_CLICKED用户在按钮上单击鼠标时,会向父窗口发送BN_CLICKED消息
BN_DOUBLECLICKED双击鼠标时会向父窗口发送BN_DOUBLECLICKED消息。

   3;位图按钮 

    对于我们操作按钮,除了使用操作系统自带的外观,同样可以使用图片来修饰按钮。参考代码:

    程序逻辑如下:

  1. 使用"BS_BITMAP"格式来创建按钮。

  2. 使用函数LoadImage() 来导入位图。

  3. 调用SendMessage()来绑定按钮与位图。

case  WM_CREATE:
	{
		LPCREATESTRUCT   pcs = (LPCREATESTRUCT)lParam; 

		//创建位图按钮
		HWND   hBtn = CreateWindow(L"BuTtOn" /*不区分大小写*/, 
			L"XXX", WS_CHILD | WS_VISIBLE | BS_BITMAP,//指定为图片
			30, 30, 217, 46, hWnd, (HMENU)1000, pcs->hInstance, NULL);

		//加载位图
		HBITMAP  hBmp=(HBITMAP)LoadImage(NULL, L"C:\\Users\\35497\\Desktop\\code\\016\\Debug\\btn1.bmp",
			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

		//向控件发送BM_SETIMAGE消息设置按钮图片
		LRESULT  ret=SendMessage(hBtn, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);


		return 0;
	}

     N:案例

    程序注释

  • 按钮本质也是窗口,所以可以通过匹配消息“WM_CREATE”,调用CreateWindow()函数来创建。

  • 每个控件都有唯一的ID值。

#include <Windows.h>
#include <windowsx.h>
#include <stdio.h>


//自定义窗口过程
LRESULT CALLBACK MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM IParam)
{
	switch (Msg)
	{
		////////////////////////////   创建按钮控件    //////////////////////////////////
	case WM_CREATE:
	{
		/*LPCREATESTRUCT定义传递给应用程序的窗口过程的初始化参数。这些成员与CreateWindowEx函数的参数相同。*/
		LPCREATESTRUCT pcs = (LPCREATESTRUCT)IParam;
		//创建控件或者子窗口

		//普通按钮BS_PUSHBUTTON
		HWND hBtn = CreateWindow(L"Button", L"普通按钮", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 30, 30, 80, 30, hWnd,
			(HMENU)1000,//控件ID,需要唯一
			pcs->hInstance, //父窗口句柄
			NULL);

		//单选按钮
		HWND hBtn1 = CreateWindow(L"Button", L"单选按钮", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 30, 60, 80, 30, hWnd,
			(HMENU)1001,//控件ID,需要唯一
			pcs->hInstance, //父窗口句柄
			NULL);

		//复选按钮
		HWND hBtn2 = CreateWindow(L"Button", L"复选按钮", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 30, 90, 80, 30, hWnd,
			(HMENU)1002,//控件ID,需要唯一
			pcs->hInstance, //父窗口句柄
			NULL);
		return 0;
	}
	case WM_COMMAND:
	{
		WORD id = LOWORD(wParam);
		WORD code = HIWORD(wParam);
		HWND hCtrl = (HWND)IParam;
		if (id == 1000 && code == BN_CLICKED)
		{
			MessageBox(hWnd, L"普通按钮被单击!", L"提示", MB_OK);
		}
		else if (id == 1001)
		{
			MessageBox(hWnd, L"单选按钮被单击!", L"提示", MB_OK);
			if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
			{
				MessageBox(hWnd, L"被选中!", L"提示", MB_OK);
			}
			else if (SendMessage(hCtrl, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
			{
				MessageBox(hWnd, L"未选中!", L"提示", MB_OK);
			}
		}
		else if (id == 1002)
		{
			MessageBox(hWnd, L"复选按钮被单击!", L"提示", MB_OK);
			if (Button_GetCheck(hCtrl) == BST_CHECKED)
			{
				MessageBox(hWnd, L"被选中!", L"提示", MB_OK);
			}
			else if (Button_GetCheck(hCtrl) == BST_UNCHECKED)
			{
				MessageBox(hWnd, L"未选中!", L"提示", MB_OK);
			}
		}
	}break;
	default:
		return DefWindowProcW(hWnd, Msg, wParam, IParam);
	}
	return 0;
}

//主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
//int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	//注册窗口类
	WNDCLASS wind;
	wind.cbClsExtra = 0;
	wind.cbWndExtra = 0;
	wind.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));// 设定背景色
	wind.hCursor = LoadCursor(NULL, IDC_ARROW); //光标
	wind.hIcon = LoadCursor(NULL, IDI_APPLICATION);//图标
	wind.lpfnWndProc = MyWindowProc; //自定义的窗口过程函数
	wind.lpszClassName = L"Aaron.xu"; //窗口类名
	wind.lpszMenuName = NULL; // 菜单资源名称
	wind.style = CS_HREDRAW;//窗口类,样式
	wind.hInstance = hInstance;//实例句柄
	RegisterClass(&wind); //注册窗口类

	//创建窗口
	HWND hWnd = CreateWindow(L"Aaron.xu", L"天象独行",
		WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);
	//显示窗口
	//ShowWindow(hWnd, nShowCmd);
	ShowWindow(hWnd, nCmdShow);
	//更新窗口
	UpdateWindow(hWnd);

	//消息循环(收到WM_QUIT消息退出)
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0)) //GetMessage()从消息队列取出消息
	{
		TranslateMessage(&msg); //将虚拟键消息转换为字符消息
		DispatchMessage(&msg); //将WM_AAA消息分配窗口过程MyWindowProc
	}
}

二;静态文本

    静态文本控件是一种最简单的控件,它主要用来显示文本消息,不能接受用户输入,一般不需要处理消息。静态文本框控件既是Windows标准控件,也是子窗口,它的窗口类名是static

    一个静态控件用来显示一个文本字符串,框,矩形,图标,光标,位图,或增强的图元文件。它可以用来作为标签,框,或用来分隔其他的控件。一个静态控件不接受输入,也不提供输出;但是如果是由“SS_NOTIFY”风格创建的,则它可以通知其父关系设备点击消息。

2.1;静态文本控制发送消息

    可以向静态文本控件发送消息来设置图标,位图等

    静态文本控件向父窗口发送命令消息“WM_COMMAND”。消息种类如下:

2;举例:

    其中仅包含窗口过程部分

case WM_CREATE:
	{ //CreateWindow函数在窗口创建成功并且在返回之前直接发送WM_CREATE消息给窗口过程函数。

		LPCREATESTRUCT pcs = (LPCREATESTRUCT)IParam;

		//创建静态文本控件
		HWND hStatic = CreateWindow(L"Static", L"静态文本", WS_CHILD | WS_VISIBLE | WS_BORDER|SS_NOTIFY, 30, 30, 200, 30,
			hWnd, (HMENU)111, pcs->hInstance, NULL);

		//更改窗口标题
		SetWindowText(hWnd, L"123123");

		//设置控件(子窗口)内容
		SetWindowText(hStatic, L"更改后的内容!");

		//加载位图
		HBITMAP hBmp = LoadBitmap(pcs->hInstance, MAKEINTRESOURCE(IDB_BITMAP1));

		//向孔健发送STM_SETIMAGE消息设置静态控件的位图
		SendMessage(hStatic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmp);

		return 0;
	}

	case WM_COMMAND: 
	{
		WORD id = LOWORD(wParam);//控件ID
		WORD code = HIWORD(wParam); //消息类型
		HWND hCtrl = (HWND)IParam;//窗口句柄

		//父窗口接收到子控件发的消息
		if (id == 111 && code == STN_CLICKED) {
			MessageBox(NULL, L"静态文本被点击!", L"提示", MB_OK);
		}
		break;

三;编辑框

演示代码(仅包含窗口过程代码部分):

case WM_CREATE:
	{
		//LPCREATESTRUCT定义传递给应用程序的窗口过程的初始化参数。这些成员与CreateWindowEx函数的参数相同。
		LPCREATESTRUCT pcs = (LPCREATESTRUCT)IParam;

		//创建编程框控件
		HWND   hEdit = CreateWindow(L"ediT", L"编辑框", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_NOHIDESEL,
			30, 30, 200, 100, hWnd, (HMENU)111, pcs->hInstance, NULL);

		//向编辑框发送选择字符串得消息
		SendMessage(hEdit, EM_SETSEL, 2, 6);

		//剪切刚刚选择的文字
		 //SendMessage(hEdit, WM_CUT, 0, 0); 

		 //撤销
		 //SendMessage(hEdit, EM_UNDO, 0, 0);

		return 0;
	}
	case WM_COMMAND:
	{
		WORD id = LOWORD(wParam); //控件ID
		WORD code = HIWORD(wParam);//消息类型
		HWND hCtrl = (HWND)IParam;//窗口句柄

		//父窗口接收到子控件发得通知代码
		//EN_CHANGE 当用户执行的操作可能更改了编辑控件中的文本时发送。
		if (id == 111 && code == EN_CHANGE)
		{
			//MessageBox(NULL, L"编辑框的文本被改变", L"提示", MB_OK);
			TCHAR buf[64] = { 0 };
			GetWindowText(hCtrl, buf, sizeof(buf));
			MessageBox(NULL, buf, L"提示", MB_OK);
		}

	}

四;列表框

演示代码(仅包含窗口过程代码部分):

	case WM_CREATE:
	{
		LPCREATESTRUCT   pcs = (LPCREATESTRUCT)IParam;

		//创建列表框控件
		HWND   hListBox = CreateWindow(L"listBOX", L"XXX", WS_CHILD | WS_VISIBLE | LBS_SORT | LBS_NOTIFY,
			30, 30, 200, 100, hWnd, (HMENU)111, GetModuleHandle(NULL), NULL);

		//向末尾添加选项
		SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)L"B音乐");
		SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)L"A啤酒");
		SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)L"C啤酒");

		//插入字符串
		SendMessage(hListBox, LB_ADDSTRING, 1, (LPARAM)L"C炸鸡");

		//选择其中一项,选择索引为2的,单选模式才有效
		SendMessage(hListBox, LB_SETCURSEL, 2, 0);

		return 0;
	}
	case WM_COMMAND:
	{
		WORD  id = LOWORD(wParam);//控件ID
		WORD  code = HIWORD(wParam);//消息类型
		HWND   hCtrl = (HWND)IParam;//窗口句柄

		 //父窗口接收到子控件发的消息
		//LBN_SELCHANGE 通知应用程序列表框中的选定内容已因用户输入而发生更改。
		if (id == 111 && code == LBN_SELCHANGE)//创建时需指定LBS_NOTIFY样式
		{
			// 获取当前选择的索引
			int  index = SendMessage(hCtrl, LB_GETCURSEL, 0, 0);

			//获取索引对应的字符串 
			TCHAR  buf[64] = { 0 };
			//LB_GETTEXT从列表框中获取一个字符串。
			SendMessage(hCtrl, LB_GETTEXT, index, (LPARAM)buf);
			MessageBox(NULL, buf, L"提示", MB_OK);
		}
	}break;

五;组合框

演示代码(仅包含窗口过程代码部分):

	case  WM_CREATE:
	{
		LPCREATESTRUCT   pcs = (LPCREATESTRUCT)IParam;

		//创建组合框
		HWND   hComboBox = CreateWindow(L"comboBOX", L"XXX", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_SORT,
			30, 30, 200, 100, hWnd, (HMENU)111, pcs->hInstance, NULL);

		//向组合框添加选项 
		SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"C音乐");
		SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"A啤酒");
		SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"B炸鸡");
		//插入选项
		SendMessage(hComboBox, CB_INSERTSTRING, 2, (LPARAM)L"编程");

		//选择某一项
		SendMessage(hComboBox, CB_SETCURSEL, 3, 0);


		return 0;
	}



	case   WM_COMMAND:
	{

		WORD  id = LOWORD(wParam);//控件ID
		WORD  code = HIWORD(wParam);//消息类型
		HWND   hCtrl = (HWND)IParam;//窗口句柄

		 //父窗口接收到子控件发的消息
		if (id == 111 && code == CBN_SELCHANGE)
		{
			//获取当前选择的索引
			int   index = SendMessage(hCtrl, CB_GETCURSEL, 0, 0);
			//获取索引对应的文本
			TCHAR  buf[64] = { 0 };
			SendMessage(hCtrl, CB_GETLBTEXT, index, (LPARAM)buf);
			MessageBox(hWnd, buf, L"提示", MB_OK);
		}

	}break;

六;滚动条

演示代码(仅包含窗口过程代码部分):

	case  WM_CREATE:
	{
		/*
		* 发送 SBM _ SETRANGE 消息,以设置滚动条控件的最小和最大位置值。
		* 发送 SBM _ SETPOS 消息以便 (thumb) 设置滚动框位置,并在请求时重新绘制滚动条以反映滚动框的新位置。
		*/
		LPCREATESTRUCT   pcs = (LPCREATESTRUCT)IParam;

		//创建滚动条控件
		HWND hScrollBar = CreateWindow(L"scrollBAR", L"XXX", WS_CHILD | WS_VISIBLE | SBS_HORZ,
			30, 30, 200, 30, hWnd, (HMENU)111, pcs->hInstance, NULL);

		//设置滚动条的范围
		SendMessage(hScrollBar, SBM_SETRANGE, 0, 100); 

		//设置滚动条的滑块位置
		SendMessage(hScrollBar, SBM_SETPOS, 40, 1);


		return 0;
	}


	//水平滚动条发送的消息
	case   WM_HSCROLL:
	{

		WORD  code = LOWORD(wParam);//操作码
		HWND   hCtrl = (HWND)IParam;//控件句柄
	   //获取滚动条的滑块位置
		//发送 SBM _ GETPOS 消息以检索滚动条控件的滚动框的当前位置。 当前位置是依赖于当前滚动范围的相对值。
		int   pos = SendMessage(hCtrl, SBM_GETPOS, 0, 0);

		switch (code)
		{

			//点击左边箭头
		case SB_LINELEFT:
			OutputDebugString(L"SB_LINELEFT\n");
			pos -= 1;
			break;
			//点击右边箭头
		case SB_LINERIGHT:
			OutputDebugString(L"SB_LINERIGHT\n");
			pos += 1;
			break;
			//点击左空白区
		case SB_PAGELEFT:
			OutputDebugString(L"SB_PAGELEFT\n");
			pos -= 10;
			break;
			//点击右空白区
		case SB_PAGERIGHT:
			OutputDebugString(L"SB_PAGERIGHT\n");
			pos += 10;
			break;
			//拖动滑块时的消息
		case  SB_THUMBPOSITION:
			pos = HIWORD(wParam);//拖拽位置,仅当SB_THUMBPOSITION有用 
			char str[64];
			sprintf_s(str, "SB_THUMBPOSITION   %d\n", pos);
			OutputDebugStringA(str);
			break;
		}

		//设置滚动条的滑块位置
		SendMessage(hCtrl, SBM_SETPOS, pos, 1);

	}break;



[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2021-5-29 22:33 被天象独行编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回