Windows编程入门-窗口控件-资源操作

window控件:

控件是常见的窗口上的交互元素例如:一个按钮,一个复选框,一个列表框等。

当控件的特定功能被触发后,会主动发送消息通知父窗口,父窗口可以通过发送消息给控件控制控件的行为。

控件的本质是一个窗口

windows窗口风格

windows窗口从其特点是主要分为两大类

  1. 表明窗口和其他窗口关系的(WS_OVERLAPED(重叠)、WS_POPPUP(弹出)、WS_CHILD(子窗口))
  2. 表明窗口自身外观特征的(WS_BORDER、WS_CAPITON...)

windows标准控件:

窗口类名 控件名称
WC_BUTTON 按钮
WC_STATIC 静态文本
WC_COMBOBOX 复合框
WC_EDIT 编辑框
WC_LISTBOX 列表框
WC_SCROLLBAR 滚动条

windows通用控件:

WC_LISTVIEW 列表框控件

WC_TREEVIEW 树控件

WC_TABCONTROL Tab控件

...

控件的响应

子控件通知父窗口一些事件,例如子控件被点击,需要通过以下两类消息

标准控件的消息:WM_COMMAND

通用控件的消息:WM_NOTIFY

添加一个按钮演示

cpp 复制代码
{
	static HINSTANCE hInstance = GetModuleHandleW(NULL);
	switch (uMsg)
	{
	case WM_CREATE:
		//添加控件
		CreateWindowW(WC_BUTTON,L"按钮1",WS_CHILD|WS_VISIBLE,10,10,80,60,hwnd,(HMENU)0x100, hInstance,0);
		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
		PostQuitMessage(0);
		break;
	}
	return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

按钮消息处理

cpp 复制代码
LRESULT CALLBACK WindowProc(
	_In_ HWND hwnd,
	_In_ UINT uMsg,
	_In_ WPARAM wParam,
	_In_ LPARAM lParam
)
{
	static HINSTANCE hInstance = GetModuleHandleW(NULL);
	switch (uMsg)
	{
	case WM_CREATE:
		//添加控件
		CreateWindowW(WC_BUTTON,L"按钮1",WS_CHILD|WS_VISIBLE,10,10,80,60,hwnd,(HMENU)0x100, hInstance,0);
		CreateWindowW(WC_BUTTON,L"按钮2",WS_CHILD|WS_VISIBLE,10,80,80,60,hwnd,(HMENU)0x101, hInstance,0);
		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
		PostQuitMessage(0);
		break;
	case WM_COMMAND:
		WORD ContrlId = LOWORD(wParam);
		if (ContrlId==0x100) 
		{
			MessageBoxW(hwnd, L"按钮1", L"提示", MB_OK);
		}else if(ContrlId == 0x101) 
		{
			MessageBoxW(hwnd, L"按钮2", L"提示", MB_OK);
		}
		break;
	}
	return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}


窗口操作函数的使用

操作窗口的通用函数

函数 说明
MoveWindow 移动窗口
UpdateWindow 更新窗口
GetWindowText 获取窗口标题
SetWindowText 设置窗口标题
FindWindow 查找窗口返回句柄
GetClientRect 获取窗口客户区大小
SetWindowPos 设置窗口位置
EnumChildWindows 枚举窗口下的所有子窗口

实现按钮(窗口)移动

cpp 复制代码
#include<Windows.h>
#include<iostream>
#include<CommCtrl.h>
LRESULT CALLBACK WindowProc(
	_In_ HWND hwnd,
	_In_ UINT uMsg,
	_In_ WPARAM wParam,
	_In_ LPARAM lParam
)
{
	static HINSTANCE hInstance = GetModuleHandleW(NULL);
	switch (uMsg)
	{
	case WM_CREATE:
		//添加控件
		CreateWindowW(WC_BUTTON,L"移动按钮",WS_CHILD|WS_VISIBLE,10,10,80,60,hwnd,(HMENU)0x100, hInstance,0);
		CreateWindowW(WC_BUTTON,L"获取文本框内容",WS_CHILD|WS_VISIBLE,10,80,80,60,hwnd,(HMENU)0x101, hInstance,0);
		CreateWindowW(WC_BUTTON,L"设置文本框内容",WS_CHILD|WS_VISIBLE,10,160,80,60,hwnd,(HMENU)0x102, hInstance,0);
		CreateWindowW(WC_BUTTON,L"设置父窗口",WS_CHILD|WS_VISIBLE,10,240,80,60,hwnd,(HMENU)0x103, hInstance,0);
		CreateWindowW(WC_EDIT,L"文本框内容",WS_CHILD|WS_BORDER|WS_VISIBLE,10,320,80,60,hwnd,(HMENU)0x104, hInstance,0);
		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
		PostQuitMessage(0);
		break;
	case WM_COMMAND:
		WORD ContrlId = LOWORD(wParam);
		switch (ContrlId)
		{
			case 0x100:
			{
				RECT rect{ 0 };
				GetClientRect(hwnd, &rect);
				int x = rand() % rect.right;
				int y = rand() % rect.bottom;
				MoveWindow((HWND)lParam, x, y, 80, 60, TRUE);
			}
		}
		break;
	}
	return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPreInstance,
	LPSTR lpCmdLine,
	int nCmdShow
)
{
	//1、创建一个窗口类
	WNDCLASSW myClass = { 0 };
	myClass.lpszClassName = L"xiaowang";
	myClass.lpfnWndProc = WindowProc;
	myClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
	//2、注册窗口类
	RegisterClassW(&myClass);
	//3、创建窗口
	HWND hwindow=CreateWindowW(
		myClass.lpszClassName,
		L"xiaowang",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		0,
		CW_USEDEFAULT,
		0,
		NULL,
		NULL,
		hInstance,
		0
	);
	//4、显示窗口
	ShowWindow(hwindow,SW_SHOWNORMAL );
	//5、获取消息
	MSG msg = { 0 };
	while (GetMessageW(&msg,0,0,0)) 
	{
		DispatchMessageW(&msg);//分发消息给消息处理函数
	}
	
	return 0;
}

实现获取文本框内容

cpp 复制代码
case 0x101:
{
    WCHAR buff[100]{ 0 };
    HWND hedit = GetDlgItem(hwnd, 0x104);
    GetWindowTextW(hedit, buff, 100);
    MessageBoxW(hwnd, buff, L"提示", MB_OK);
    break;
}

设置文本内容

cpp 复制代码
case 0x102:
{
    HWND hedit = GetDlgItem(hwnd, 0x104);
    //SetWindowTextW(hedit, L"设置了文本内容");
    SetDlgItemTextW(hedit, 0x104,L"设置了文本内容SetDlgItemTextW");

    break;
}

设置父窗口

cpp 复制代码
case 0x103:
{
    HWND hnote = FindWindowW(NULL, L"记事本");
    SetParent((HWND)lParam, hnote);
    break;
}

使文本框内容可编辑

加上

TranslateMessage(&msg);

cpp 复制代码
	//4、显示窗口
	ShowWindow(hwindow,SW_SHOWNORMAL );
	//5、获取消息
	MSG msg = { 0 };
	while (GetMessageW(&msg,0,0,0)) 
	{
		TranslateMessage(&msg);
		DispatchMessageW(&msg);//分发消息给消息处理函数
	}
	
	return 0;
}

资源操作

无法直接定位到资源,并使用函数操作他们,和窗口一样,一般情况需要得到资源的句柄

LoadXXX:XXX是资源类型

LoadTcon 载入图标、LoadCursor载入光标 LoadMenu 载入菜单

图标资源:LoadIcon

光标资源:LoadCursor
菜单资源:
1、

lpszMenuName

2、

LoadMenu

CreateWindow();

3、

LoadMenu

GetSubMenu();

TrackPopupMenu()
图标

添加 一个资源

选择icon

载入图标

按钮点击后改变

cpp 复制代码
#include"resource.h"
case 0x101:
    {
        //MAKEINTRESOURCEW为强制转换
        //IDI_ICON1为资源视图中图标的名字
        HICON hIcon=LoadIcon(hInstance,MAKEINTRESOURCEW(IDI_ICON1));
        SetClassLongW(hwnd, GCL_HICON, (LONG)hIcon);
        break;
    }

窗口创建时改变图标

cpp 复制代码
	//1、创建一个窗口类
	WNDCLASSW myClass = { 0 };
	myClass.lpszClassName = L"xiaowang";
	myClass.lpfnWndProc = WindowProc;
	myClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
	myClass.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_ICON1));
	//系统提供图标
	//myClass.hIcon = LoadIconW(0, IDI_ERROR);
	//2、注册窗口类
	RegisterClassW(&myClass);

光标

创建光标文件

载入光标

cpp 复制代码
case 0x102:
{
    HCURSOR hcursor = LoadCursorW(hInstance, MAKEINTRESOURCEW(IDC_CURSOR1));
    SetClassLongW(hwnd, GCL_HCURSOR, (LONG)hcursor);
    break;
}

窗口创建时改变光标

cpp 复制代码
//1、创建一个窗口类
	WNDCLASSW myClass = { 0 };
	myClass.lpszClassName = L"xiaowang";
	myClass.lpfnWndProc = WindowProc;
	myClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
	myClass.hCursor = LoadCursorW(hInstance, MAKEINTRESOURCEW(IDC_CURSOR1))

菜单

初始化时载入菜单

cpp 复制代码
//1、创建一个窗口类
	WNDCLASSW myClass = { 0 };
	myClass.lpszClassName = L"xiaowang";
	myClass.lpfnWndProc = WindowProc;
	myClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
	myClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1);

创建窗口时

cpp 复制代码
	//3、创建窗口
	HMENU hmenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
	HWND hwindow=CreateWindowW(
		myClass.lpszClassName,
		L"xiaowang",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		0,
		CW_USEDEFAULT,
		0,
		NULL,
		hmenu,
		hInstance,
		0
	);

通过按钮载入

cpp 复制代码
case 0x100:
    {
        HMENU hmenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
        SetMenu(hwnd, hmenu);

鼠标右键点击时出现菜单

cpp 复制代码
	switch (uMsg)
	{
	case WM_CREATE:
		.....
	case WM_RBUTTONDOWN:
	{
		POINT point{ 0 };
		ClientToScreen(hwnd, &point);
		GetCursorPos(&point);
		HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
		HMENU hSubMenu = GetSubMenu(hMenu, 0);
		TrackPopupMenu(hSubMenu, TPM_LEFTALIGN, point.x, point.y, 0, hwnd, NULL);
		break;
	}

捕获菜单被点击

cpp 复制代码
case ID_40001:
{
    MessageBoxW(hwnd, L"子菜单1被点击了",L"提示",MB_OK);
}


对话框资源

对话框资源可以创建一个对话框,以及其上的子控件。通过对话框可以进行可视化编辑。

对话框有两种形式:

模态对话框、非模态对话框

区别:模态对话框会阻塞主窗口,非模态对话框不会

添加一个对话框

创建非模态对话框

cpp 复制代码
#include<Windows.h>
#include<CommCtrl.h>
#include"resource.h"
INT_PTR CALLBACK Dlgproc(
	HWND hWnd,
	UINT Umsg,
	WPARAM wparam,
	LPARAM lparam
) {
	switch (Umsg)
	{
		case WM_INITDIALOG: 
		{
			MessageBox(hWnd,L"窗口创建了",L"标题",MB_OK);
			break;
		}
		case WM_CLOSE:
		{
			DestroyWindow(hWnd);
			PostQuitMessage(0);
			break;
		}
		default:
		{
			return FALSE;
		}
	}
	return TRUE;
}
int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPreInstance,
	LPSTR lpCmdLine,
	int nCmdShow
)
{
	HWND hwnd=CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG1),NULL,Dlgproc);
	ShowWindow(hwnd, SW_SHOWNORMAL);
	MSG msg{ 0 };
	while (GetMessage(&msg,0,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessageW(&msg);
	}
	return 0;
}
相关推荐
弗锐土豆6 小时前
Windows系统中Oracle VM VirtualBox的安装
windows·虚拟机·virtualbox
秋の花6 小时前
【JAVA基础】Java集合基础
java·开发语言·windows
零意@9 小时前
ubuntu切换不同版本的python
windows·python·ubuntu
写bug的小屁孩10 小时前
前后端交互接口(三)
运维·服务器·数据库·windows·用户界面·qt6.3
hairenjing112312 小时前
在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序
android·人工智能·windows·macos·智能手机
plmm烟酒僧15 小时前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
Jtti18 小时前
Windows系统服务器怎么设置远程连接?详细步骤
运维·服务器·windows
小奥超人18 小时前
PPT文件设置了修改权限,如何取消权?
windows·经验分享·microsoft·ppt·办公技巧
hairenjing11231 天前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word
九鼎科技-Leo1 天前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net