windows编程 标准控件的使用(按钮,文本框)

基本控件的使用

标准控件的创建

在我们创建窗口并且在CREATE的时候创建。

case WM_CREATE:
		CreateWindowW(WC_BUTTON, L"移动按钮", WS_CHILD | WS_VISIBLE, 50, 20, 200, 50,hwnd, (HMENU)0x100, hInstance, NULL);
		CreateWindowW(WC_BUTTON, L"获取文本框内容", WS_CHILD | WS_VISIBLE, 50, 100, 200, 50, hwnd, (HMENU)0x101, hInstance, NULL);
		CreateWindowW(WC_BUTTON, L"设置文本框内容", WS_CHILD | WS_VISIBLE, 50, 160, 200, 50, hwnd, (HMENU)0x102, hInstance, NULL);
		CreateWindowW(WC_BUTTON, L"设置父窗口", WS_CHILD | WS_VISIBLE, 50, 220, 200, 50, hwnd, (HMENU)0x103, hInstance, NULL);
		CreateWindowW(WC_BUTTON, L"枚举所有窗口", WS_CHILD | WS_VISIBLE, 350, 300, 200, 50, hwnd, (HMENU)0x105, hInstance, NULL);
		CreateWindowW(WC_EDIT, L"文本编辑框", WS_CHILD | WS_BORDER | WS_VISIBLE, 50, 300, 200, 50, hwnd, (HMENU)0x104, hInstance, NULL);
		CreateWindowW(WC_EDIT, L"文本输入框", WS_CHILD | WS_BORDER | WS_VISIBLE, 50, 360, 200, 50, hwnd, (HMENU)0x106, hInstance, NULL);
		break;

标准控件我们使用 WM_COMMAND来处理消息,其中wParam的高字节存储控制消息的通知代码,低字节存储控件的表示符,lParam存储控件的句柄。

处理WM_COMMAND消息,并且获取每个部件的标识符

case WM_COMMAND:
{
	WORD Controlid = LOWORD(wParam);
	switch (Controlid)
	{
		case ....
	}
}

移动按钮

我们要实现点击按钮,然后让按钮随机在窗口内移动,该如何操作?

我们只需获取其句柄,然后指定其在窗口的范围内Move即可,注意,我们需要获取其能移动的最大距离,不能越界,我们可以获取整个窗口的长和宽,存储在RECT的结构体中,然后MOVE移动,让他在这个范围MOVE即可:

case 0x100:
{
		//随机获取坐标: 来一个区间范围
		RECT rect{ 0 };
		GetClientRect(hwnd, &rect);
		int x = rand() % (rect.right - 200);
		int y = rand() % (rect.bottom - 50);
		MoveWindow((HWND)lParam, x, y, 200, 50, TRUE);
		break;
	}

获取文本框的内容

首先获得文本框的句柄,再从句柄里获取消息即可:

两种方法:

  1. GetDlgItem:获取句柄;GetWindowTextW:从指定的句柄里获取消息
  2. GetDlgItemTextW:直接从句柄里获取消息
case 0x101:
	{
		/*
		获取文本框的内容
		*/
		WCHAR str_dst[100]{ 0 };
		HWND hedit=GetDlgItem(hwnd,0x104);		//首先获取文本框窗口的句柄
		//GetDlgItemTextW(hwnd, 0x104, str_dst, 100);
		GetWindowTextW(hedit, str_dst, 100);	//根据得到的子窗口的句柄得到字符串并且放入一个字符数组中
		MessageBoxW(hwnd, str_dst, L"提示", MB_OK);	//读取文本框的内容
		break;
	}

自动设置文本框内容

任务:从一个文本框里输入信息,然后经过一个按钮点击,把这个消息发送到另一个文本框,相当于复制内容.

两种方法:

  1. 获取读取的原始文本框句柄, 然后得到其文本,然后根据此文本直接放入另一个文本框。
  2. 再次获取目标句柄,然后再发送文本。
case 0x102:
{
	/*
	根据读取的文本框的内容再复制到另一个文本框
	*/
	WCHAR wchar_buff[100]{ 0 };
	//获取文本框的句柄
	HWND handle=GetDlgItem(hwnd, 0x104);		//获取目标编辑框句柄
	GetWindowTextW(handle, wchar_buff,100);	//获取读入的内容
	SetDlgItemTextW(hwnd, 0x106, wchar_buff);

	//HWND dst_HWND = GetDlgItem(hwnd, 0x106);
	//SetWindowTextW(dst_HWND, wchar_buff);
	break;
}

注意:
SetDlgItemTextW 等价于:首先GetDlgItem,然后再SetWindowTextW。

设置父窗口

打开记事本,保证记事本的名字正确,运行代码,你就会发现你的0x103标识的按钮跑到记事本窗口上去了。

case 0x103:
{
		HWND handle=FindWindowW(NULL, L"无标题 - 记事本");
		SetParent((HWND)lParam, handle);	//原窗口句柄和新的父窗口句柄
		break;
	}

枚举出所有窗口

怎么知道你的主窗口上有多少个子窗口?
可以枚举来显示一下:

case 0x105: 
{
	EnumChildWindows(hwnd, EnumChildProc, 0);
	break;
}
//枚举子窗口的回调函数
BOOL CALLBACK EnumChildProc(
	HWND hwnd,
	LPARAM lparam
)
{
	WCHAR wchar_buff[100]{ 0 };
	GetWindowText(hwnd, wchar_buff, 100);
	println(L"子窗口: %s\n", wchar_buff);
	return TRUE;
}

注意,我们需要一个格式化输出的函数,以便于我们能够获取其输出内容:

//格式化输出函数
void println(LPCWSTR format, ...)
{
	WCHAR wchar_buff[100]{ 0 };
	va_list args;	//参数列表拷贝到args变量中
	va_start(args, format);	//保存参数列表
	wvsprintfW(wchar_buff, format, args);		//格式化输出到wchar_buff
	va_end(args);	//清理工作
	OutputDebugStringW(wchar_buff);		//内容发送到Debug进行调试
}

在这里插入图片描述

测试代码

#include <iostream>
#include <Windows.h>
#include <CommCtrl.h>

//格式化输出函数
void println(LPCWSTR format, ...)
{
	WCHAR wchar_buff[100]{ 0 };
	va_list args;	//参数列表拷贝到args变量中
	va_start(args, format);	//保存参数列表
	wvsprintfW(wchar_buff, format, args);		//格式化输出到wchar_buff
	va_end(args);	//清理工作
	OutputDebugStringW(wchar_buff);		//内容发送到Debug进行调试
}

//枚举子窗口的回调函数
BOOL CALLBACK EnumChildProc(
	HWND hwnd,
	LPARAM lparam
)
{
	WCHAR wchar_buff[100]{ 0 };
	GetWindowText(hwnd, wchar_buff, 100);
	println(L"子窗口: %s\n", wchar_buff);
	return TRUE;
}

LRESULT CALLBACK Wndproc(
	HWND hwnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
)
{
	static HINSTANCE hInstance = GetModuleHandleW(NULL);	//获取当前窗口句柄
	switch (uMsg)
	{
	case WM_CREATE:
		CreateWindowW(WC_BUTTON, L"移动按钮", WS_CHILD | WS_VISIBLE, 50, 20, 200, 50,hwnd, (HMENU)0x100, hInstance, NULL);
		CreateWindowW(WC_BUTTON, L"获取文本框内容", WS_CHILD | WS_VISIBLE, 50, 100, 200, 50, hwnd, (HMENU)0x101, hInstance, NULL);
		CreateWindowW(WC_BUTTON, L"设置文本框内容", WS_CHILD | WS_VISIBLE, 50, 160, 200, 50, hwnd, (HMENU)0x102, hInstance, NULL);
		CreateWindowW(WC_BUTTON, L"设置父窗口", WS_CHILD | WS_VISIBLE, 50, 220, 200, 50, hwnd, (HMENU)0x103, hInstance, NULL);
		CreateWindowW(WC_BUTTON, L"枚举所有窗口", WS_CHILD | WS_VISIBLE, 350, 300, 200, 50, hwnd, (HMENU)0x105, hInstance, NULL);
		CreateWindowW(WC_EDIT, L"文本编辑框", WS_CHILD | WS_BORDER | WS_VISIBLE, 50, 300, 200, 50, hwnd, (HMENU)0x104, hInstance, NULL);
		CreateWindowW(WC_EDIT, L"文本输入框", WS_CHILD | WS_BORDER | WS_VISIBLE, 50, 360, 200, 50, hwnd, (HMENU)0x106, hInstance, NULL);

		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
		PostQuitMessage(NULL);
		break;
	case WM_COMMAND:
	{
		WORD Controlid = LOWORD(wParam);
		switch (Controlid)
		{
		case 0x100:
		{
			//随机获取坐标: 来一个区间范围
			RECT rect{ 0 };
			GetClientRect(hwnd, &rect);
			int x = rand() % (rect.right - 200);
			int y = rand() % (rect.bottom - 50);
			MoveWindow((HWND)lParam, x, y, 200, 50, TRUE);
			break;
		}
		case 0x101:
		{
			/*
			获取文本框的内容
			*/
			WCHAR str_dst[100]{ 0 };
			HWND hedit=GetDlgItem(hwnd,0x104);		//首先获取文本框窗口的句柄
			GetDlgItemTextW(hwnd, 0x104, str_dst, 100);
			//GetWindowTextW(hedit, str_dst, 100);	//根据得到的子窗口的句柄得到字符串并且放入一个字符数组中
			MessageBoxW(hwnd, str_dst, L"提示", MB_OK);	//读取文本框的内容
			break;
		}
		case 0x102:
		{
			/*
			根据读取的文本框的内容再复制到另一个文本框
			*/
			WCHAR wchar_buff[100]{ 0 };
			//获取文本框的句柄
			HWND handle=GetDlgItem(hwnd, 0x104);		//获取目标编辑框句柄
			GetWindowTextW(handle, wchar_buff,100);	//获取读入的内容
			SetDlgItemTextW(hwnd, 0x106, wchar_buff);

			//HWND dst_HWND = GetDlgItem(hwnd, 0x106);
			//SetWindowTextW(dst_HWND, wchar_buff);
			break;
		}
		case 0x103:
		{
			HWND handle=FindWindowW(NULL, L"无标题 - 记事本");
			SetParent((HWND)lParam, handle);	//原窗口句柄和新的父窗口句柄
			break;
		}
		case 0x105: 
		{
			EnumChildWindows(hwnd, EnumChildProc, 0);
			break;
		}
		}
		break;
	}
	}
	return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR     lpCmdLine,
	int       nShowCmd
)
{
	//1. 创建窗口类
	WNDCLASSW myClassWindow{ 0 };
	myClassWindow.lpszClassName = L"ylh";
	myClassWindow.lpfnWndProc = Wndproc;	//回调函数
	myClassWindow.hbrBackground = CreateSolidBrush(RGB(205, 156, 29));

	//2. 注册窗口 
	RegisterClassW(&myClassWindow);

	//3. 创建窗口
	HWND hWIndow = CreateWindowW(
		myClassWindow.lpszClassName,
		L"dasd",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		0,
		CW_USEDEFAULT,
		0,
		NULL,
		NULL,
		hInstance,
		NULL
	);

	//4. 显示窗口
	ShowWindow(hWIndow, SW_SHOWNORMAL);

	//5. 处理消息事件
	MSG msg{ 0 };
	while (GetMessageW(&msg, NULL, NULL, NULL))
	{
		TranslateMessage(&msg);
		DispatchMessageW(&msg);
	}
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Yuleo_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值