• 【免杀前置课——Windows编程】七、资源操作(图标资源添加、实现菜单窗口、实现右键下拉菜单、实现对话框资源添加)(附代码)


    资源操作

    如何添加资源:
    我们无法直接定位到资源,并使用函数操作他们,和窗口一样,一般情况我们都是需要得到资源的句柄
    LodaXXX:XXX是资源类型
    例如:LoadIcon载入图标、LoadCursor载入光标,LoadMenu载入菜单。。。

    图标资源:

    LoadIcon

    光标资源:

    LoadCursor
    SetCursor();

    在这里插入图片描述

    实现图标资源添加

    #include
    #include
    #include"resource1.h"
    
    void print(LPCWSTR format, ...)
    {
    	WCHAR outBuff[1024] = { 0 };
    	va_list args;
    	va_start(args, format);
    	wvsprintfW(outBuff, format, args);
    	va_end(args);
    	OutputDebugStringW(outBuff);
    }
    
    BOOL CALLBACK EnumChildProc(
    	_In_ HWND hwnd,
    	_In_ LPARAM lParam
    )
    {
    	WCHAR buff[100]{ 0 };
    	GetWindowTextW(hwnd, buff, 100);
    	print(L"窗口名称:%ls\n", buff);
    	return TRUE;
    }
    
    LRESULT CALLBACK WindowProc(
    	_In_ HWND hwnd,
    	_In_ UINT uMsg,
    	_In_ WPARAM wParam,//低两位存储控件ID
    	_In_ LPARAM lParam//存储控件句柄
    )
    {
    	static HINSTANCE hInstance = GetModuleHandle(NULL);//获取当前程序的实例句柄
    	switch (uMsg)
    	{
    	case WM_CREATE:
    		//添加控件
    		CreateWindowW(WC_BUTTON, L"移动按钮", WS_CHILD | WS_VISIBLE, 10, 10, 120, 40, hwnd, (HMENU)0x100, hInstance, 0);
    		CreateWindowW(WC_BUTTON, L"设置菜单", WS_CHILD | WS_VISIBLE, 10, 60, 120, 40, hwnd, (HMENU)0x101, hInstance, 0);
    		CreateWindowW(WC_EDIT, L"文本框内容", WS_CHILD | WS_BORDER | WS_VISIBLE, 10, 260, 320, 80, hwnd, (HMENU)0x104, hInstance, 0);
    		break;
    	case WM_CLOSE:
    		DestroyWindow(hwnd);
    		PostQuitMessage(0);
    		break;
    	case WM_COMMAND://标准控件的消息
    	{
    		WORD ControlId = LOWORD(wParam);//wParam低两个字节存储的是每个控件的不同IP
    		switch (ControlId)
    		{
    		case 0x100:
    		{
    			break;
    		}
    		case 0x101:
    		{
    			break;
    		}
    		case 0x102:
    		{
    			break;
    		}
    		case 0x103:
    		{
    			break;
    		}
    		case 0x105:
    		{
    			break;
    		}
    		default:
    			break;
    		}
    		break;
    	}
    	}
    	return DefWindowProcW(hwnd, uMsg, wParam, lParam);
    }
    
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	//1、创建窗口类
    	WNDCLASSW myWndClass{ 0 };
    	myWndClass.lpfnWndProc = WindowProc;
    	myWndClass.lpszClassName = L"dsdWindows";
    	myWndClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255, 255));//背景画布
    	myWndClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1);
    	//2、注册窗口类
    	RegisterClassW(&myWndClass);
    	//3、创建窗口
    	HWND hwnd = CreateWindowW(
    		myWndClass.lpszClassName,
    		L"dsdWindows",
    		WS_OVERLAPPEDWINDOW,//重叠窗口样式,其他窗口写在该窗口上方即16行代码
    		CW_USEDEFAULT,
    		0,
    		CW_USEDEFAULT,
    		0,
    		NULL,
    		NULL,
    		hInstance,
    		0
    	);
    	//4、显示窗口
    	ShowWindow(hwnd, SW_SHOWNORMAL);//SHOWWINDOWS展示样式
    	MSG msg{ 0 };
    	while (GetMessageW(&msg, 0, 0, 0)) {
    		TranslateMessage(&msg);//翻译消息为WM_CHAR 可以在文本框控件中对文字进行输入
    		DispatchMessageW(&msg);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113

    ICON的加载和更换

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    实现菜单窗口

    #include
    #include
    #include"resource.h"
    
    void print(LPCWSTR format, ...)
    {
    	WCHAR outBuff[1024] = { 0 };
    	va_list args;
    	va_start(args, format);
    	wvsprintfW(outBuff, format, args);
    	va_end(args);
    	OutputDebugStringW(outBuff);
    }
    
    BOOL CALLBACK EnumChildProc(
    	_In_ HWND hwnd,
    	_In_ LPARAM lParam
    )
    {
    	WCHAR buff[100]{ 0 };
    	GetWindowTextW(hwnd, buff, 100);
    	print(L"窗口名称:%ls\n", buff);
    	return TRUE;
    }
    
    LRESULT CALLBACK WindowProc(
    	_In_ HWND hwnd,
    	_In_ UINT uMsg,
    	_In_ WPARAM wParam,//低两位存储控件ID
    	_In_ LPARAM lParam//存储控件句柄
    )
    {
    	static HINSTANCE hInstance = GetModuleHandle(NULL);//获取当前程序的实例句柄
    	switch (uMsg)
    	{
    	case WM_CREATE:
    		//添加控件
    		CreateWindowW(WC_BUTTON, L"移动按钮", WS_CHILD | WS_VISIBLE, 10, 10, 120, 40, hwnd, (HMENU)0x100, hInstance, 0);
    		CreateWindowW(WC_BUTTON, L"设置菜单", WS_CHILD | WS_VISIBLE, 10, 60, 120, 40, hwnd, (HMENU)0x101, hInstance, 0);
    		CreateWindowW(WC_EDIT, L"文本框内容", WS_CHILD | WS_BORDER | WS_VISIBLE, 10, 260, 320, 80, hwnd, (HMENU)0x104, hInstance, 0);
    		break;
    	case WM_CLOSE:
    		DestroyWindow(hwnd);
    		PostQuitMessage(0);
    		break;
    	case WM_COMMAND://标准控件的消息
    	{
    		WORD ControlId = LOWORD(wParam);//wParam低两个字节存储的是每个控件的不同IP
    		switch (ControlId)
    		{
    		case 0x100:
    		{
    
    			break;
    		}
    		case 0x101:
    		{
    			HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
    			SetMenu(hwnd, hMenu);
    			break;
    		}
    		case 0x102:
    		{
    			break;
    		}
    		case 0x103:
    		{
    			break;
    		}
    		case 0x105:
    		{
    			break;
    		}
    		case ID_40001:
    			MessageBoxW(hwnd, L"子菜单1被点击了", L"提示", MB_OK);
    			break;
    		default:
    			break;
    		}
    		break;
    	}
    	}
    	return DefWindowProcW(hwnd, uMsg, wParam, lParam);
    }
    
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	//1、创建窗口类
    	WNDCLASSW myWndClass{ 0 };
    	myWndClass.lpfnWndProc = WindowProc;
    	myWndClass.lpszClassName = L"dsdWindows";
    	myWndClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255, 255));//背景画布
    	//myWndClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1);
    	//2、注册窗口类
    	RegisterClassW(&myWndClass);
    	//3、创建窗口
    	//HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
    	HWND hwnd = CreateWindowW(
    		myWndClass.lpszClassName,
    		L"dsdWindows",
    		WS_OVERLAPPEDWINDOW,//重叠窗口样式,其他窗口写在该窗口上方即16行代码
    		CW_USEDEFAULT,
    		0,
    		CW_USEDEFAULT,
    		0,
    		NULL,
    		NULL,
    		hInstance,
    		0
    	);
    	//4、显示窗口
    	ShowWindow(hwnd, SW_SHOWNORMAL);//SHOWWINDOWS展示样式
    	MSG msg{ 0 };
    	while (GetMessageW(&msg, 0, 0, 0)) {
    		TranslateMessage(&msg);//翻译消息为WM_CHAR 可以在文本框控件中对文字进行输入
    		DispatchMessageW(&msg);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120

    方法一:

    把整数值转化为能被使用的资源类型。
    在这里插入图片描述

    方法二:

    在创建窗口时,放入句柄的参数中。
    在这里插入图片描述

    方法三:

    通过按钮来执行菜单窗口。
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    实现右键下拉菜单

    在平常的工作中我们会使用右键来打开关于一个应用的内置下拉菜单,我们通过窗口机制来实现。

    #include
    #include
    #include"resource.h"
    
    void print(LPCWSTR format, ...)
    {
    	WCHAR outBuff[1024] = { 0 };
    	va_list args;
    	va_start(args, format);
    	wvsprintfW(outBuff, format, args);
    	va_end(args);
    	OutputDebugStringW(outBuff);
    }
    
    BOOL CALLBACK EnumChildProc(
    	_In_ HWND hwnd,
    	_In_ LPARAM lParam
    )
    {
    	WCHAR buff[100]{ 0 };
    	GetWindowTextW(hwnd, buff, 100);
    	print(L"窗口名称:%ls\n", buff);
    	return TRUE;
    }
    
    LRESULT CALLBACK WindowProc(
    	_In_ HWND hwnd,
    	_In_ UINT uMsg,
    	_In_ WPARAM wParam,//低两位存储控件ID
    	_In_ LPARAM lParam//存储控件句柄
    )
    {
    	static HINSTANCE hInstance = GetModuleHandle(NULL);//获取当前程序的实例句柄
    	switch (uMsg)
    	{
    	case WM_CREATE:
    		//添加控件
    		CreateWindowW(WC_BUTTON, L"移动按钮", WS_CHILD | WS_VISIBLE, 10, 10, 120, 40, hwnd, (HMENU)0x100, hInstance, 0);
    		CreateWindowW(WC_BUTTON, L"设置菜单", WS_CHILD | WS_VISIBLE, 10, 60, 120, 40, hwnd, (HMENU)0x101, hInstance, 0);
    		CreateWindowW(WC_EDIT, L"文本框内容", WS_CHILD | WS_BORDER | WS_VISIBLE, 10, 260, 320, 80, hwnd, (HMENU)0x104, hInstance, 0);
    		break;
    	case WM_RBUTTONDOWN:
    	{
    		//实现右键下拉菜单
    		/*WORD X = LOWORD(lParam);
    		WORD Y = HIWORD(lParam);*/
    		POINT point{ 0 };
    		/*point.x = X;
    		point.y = Y;*/
    		ClientToScreen(hwnd, &point);//ClientToScreen 函数将指定点的工作区坐标转换为屏幕坐标。
    		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);//弹出菜单,靠左显示窗口
    		SetMenu(hwnd, hMenu);
    		break;
    	}
    	case WM_CLOSE:
    		DestroyWindow(hwnd);
    		PostQuitMessage(0);
    		break;
    	case WM_COMMAND://标准控件的消息
    	{
    		WORD ControlId = LOWORD(wParam);//wParam低两个字节存储的是每个控件的不同IP
    		switch (ControlId)
    		{
    		case 0x100:
    		{
    
    			break;
    		}
    		case 0x101:
    		{
    			HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
    			SetMenu(hwnd, hMenu);
    			break;
    		}
    		case 0x102:
    		{
    			break;
    		}
    		case 0x103:
    		{
    			break;
    		}
    		case 0x105:
    		{
    			break;
    		}
    		case ID_40001:
    			MessageBoxW(hwnd, L"子菜单1被点击了", L"提示", MB_OK);
    			break;
    		default:
    			break;
    		}
    		break;
    	}
    	}
    	return DefWindowProcW(hwnd, uMsg, wParam, lParam);
    }
    
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	//1、创建窗口类
    	WNDCLASSW myWndClass{ 0 };
    	myWndClass.lpfnWndProc = WindowProc;
    	myWndClass.lpszClassName = L"dsdWindows";
    	myWndClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255, 255));//背景画布
    	//myWndClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1);
    	//2、注册窗口类
    	RegisterClassW(&myWndClass);
    	//3、创建窗口
    	//HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
    	HWND hwnd = CreateWindowW(
    		myWndClass.lpszClassName,
    		L"dsdWindows",
    		WS_OVERLAPPEDWINDOW,//重叠窗口样式,其他窗口写在该窗口上方即16行代码
    		CW_USEDEFAULT,
    		0,
    		CW_USEDEFAULT,
    		0,
    		NULL,
    		NULL,
    		hInstance,
    		0
    	);
    	//4、显示窗口
    	ShowWindow(hwnd, SW_SHOWNORMAL);//SHOWWINDOWS展示样式
    	MSG msg{ 0 };
    	while (GetMessageW(&msg, 0, 0, 0)) {
    		TranslateMessage(&msg);//翻译消息为WM_CHAR 可以在文本框控件中对文字进行输入
    		DispatchMessageW(&msg);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136

    方法一:
    在这里插入图片描述
    方法二:
    在这里插入图片描述
    在这我们获取的都是顶级菜单的ID而不是子菜单的ID,要想获得子菜单的ID用以下的方法。
    在这里插入图片描述
    在这里插入图片描述

    实现对话框资源添加

    对话框有两种:模态对话框和非模态对话框。
    在这里插入图片描述
    在这里插入图片描述

    #include
    #include
    #include"resource1.h"
    
    INT_PTR CALLBACK Dlgproc(
    	HWND hwnd,
    	UINT uMsg,
    	WPARAM wParam,
    	LPARAM lParam
    ) 
    {
    	switch (uMsg)
    	{
    	case WM_INITDIALOG://创建窗口
    		MessageBoxW(hwnd, L"窗口创建了", L"提示", MB_OK);
    		break;
    	case WM_CLOSE:
    		EndDialog(hwnd, 0);
    		//非模态对话框关闭窗口
    		/*DestroyWindow(hwnd);
    		PostQuitMessage(0);*/
    		break;
    	default:
    		return FALSE;
    	}
    	
    	return TRUE;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	//创建模态对话框
    	DialogBoxW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG1), NULL, Dlgproc);
    	//创建非模态对话框
    	//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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    除静电设备的工作原理及应用
    nginx清除缓存
    [PAT练级笔记] 41 Basic Level 1041 考试座位号
    《C语言图形界面-系统开发》专栏介绍 & 专栏目录
    imx6ull应用程序进systemd里踩坑
    人工智能-循环神经网络通过时间反向传播
    洋葱集团携手OceanBase实现分布式升级,全球数据首次实现跨云融合
    技术内幕 | StarRocks 支持 Apache Hudi 原理解析
    C++重载输入和输出运算符
    实例演示如何使用CCE XGPU虚拟化
  • 原文地址:https://blog.csdn.net/m0_62783065/article/details/127735823