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 小时前
编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET... 拒绝访问
c语言·windows
搏博15 小时前
基于Python3.10.6与jieba库的中文分词模型接口在Windows Server 2022上的实现与部署教程
windows·python·自然语言处理·flask·中文分词
有梦想的攻城狮1 天前
Java 11中的Collections类详解
java·windows·python·java11·collections
忒可君1 天前
C# winform FTP功能
开发语言·windows·c#
十五年专注C++开发1 天前
CMake进阶: CMake Modules---简化CMake配置的利器
linux·c++·windows·cmake·自动化构建
degree5201 天前
全平台轻量浏览器推荐|支持Win/macOS/Linux,极速加载+隐私保护+扩展插件,告别广告与数据追踪!
windows·macos·电脑
许泽宇的技术分享2 天前
Windows桌面自动化的革命性突破:深度解析Windows-MCP.Net Desktop模块的技术奥秘
windows·自动化·.net
七仔的博客2 天前
【摸鱼办公神器】七仔的桌面工具超进化 -> 灵卡面板 v1.1.9
windows·神器·摸鱼
码农阿豪2 天前
Windows从零到一安装KingbaseES数据库及使用ksql工具连接全指南
数据库·windows
CC__xy3 天前
demo 通讯录 + 城市选择器 (字母索引左右联动 ListItemGroup+AlphabetIndexer)笔记
windows