Windows编程资源,菜单资源,图标资源,光标资源,上下文菜单,字符串资源,加速键资源

Windows资源是一种二进制数据,由链接器链接进程序成为程序的一部分,通过资源的方式可以很方便的对应用程序进行扩展。在Windows中资源可以是系统自定义的,也可以是用户自定义的。在本篇文章中为大家讲解菜单资源,上下文菜单,图标资源,光标资源,加速键资源的创建方法,这里我使用的编译器为visual studio2022版本。

文章目录

  • 一.菜单资源
    • 1.菜单分类
    • 2.如何创建菜单资源
    • 3.实操展示
  • 二.上下文菜单
    • 1.显示上下文菜单(右键菜单)
    • 2.上下文菜单中的WM_RBUTTONUP消息
    • 3.WM_CONTEXTMENU消息
  • 三.图标资源,光标资源
    • 1.添加图标资源
    • 2.加载图标资源
    • 3.添加光标资源
    • 4.加载光标资源
    • 5.设置资源
    • 5.WM_SETCURSOR消息
  • 三.字符串资源
  • 四.加速键资源
    • 1.添加加速键资源
    • 2.加速键资源的使用


一.菜单资源

1.菜单分类

  • 窗口顶层菜单
  • 弹出式菜单
  • 系统菜单
  • HMENU类型表示菜单,ID表示菜单项

2.如何创建菜单资源

对于目前的编译器,我们自己添加资源还是非常容易的,我们只需要使用可视化图形界面就可以。

  • 1.添加菜单资源
    • <1>.右键单击资源文件,选择添加–>资源
      添加菜单资源
    • <2>.选择添加Menu资源 添加Menu资源
    • <3>.添加想要的菜单资源,并且设置消息ID
      添加想要的菜单资源
  • 2.获取本进程菜单句柄
HMENU LoadMenu(
	HINSTANCE hInstance;         //包含要加载的菜单资源模块的句柄
	LPCSTR lpMenuName            //菜单资源的名称
);
  • 3.加载菜单资源
    • <1>.注册窗口类时设置菜单(lpszMenuName)
    • <2>.创建窗口时,传参设置菜单
    • <3>.在主窗口WM_CREATE消息中使用SetMenu函数设置菜单
SetMenu(
	HWND hWnd,        //窗口句柄
	HMENU hMenu,      //菜单句柄
);设置成功,返回非零

在这里对SetMenu函数不做过多的解释了,大家可以到MSDN官方文档解释SetMenu函数中查看该函数的详细介绍。

  • 4.处理菜单消息
    在学习处理菜单消息之前,我们来学习一种常见的消息类型:WM_COMMAND
    • 发出时间:当用户从菜单中选择命令项,空间将通知消息发送到其父窗口或翻译快捷键击时发送。
    • 附加信息
      • wParam:
        • HIWORD:对于菜单为0
        • LOWORD:菜单项的ID
      • lParam:对于菜单为0

3.实操展示

我们来使用WM_COMMAND消息来处理菜单按钮:
设置菜单:
菜单编辑
回调函数处理:

LRESULT CALLBACK WindowProc(
	IN  HWND hwnd,
	IN  UINT uMsg,
	IN  WPARAM wParam,
	IN  LPARAM lParam
)
{
	char output[256] = { 0 };
	switch (uMsg)
	{
	//常见消息
	case WM_DESTROY: {
		PostQuitMessage(0);
		break;
		}
	case WM_SYSCOMMAND: {
		sprintf(output, TEXT("检测到WM_COMMAND消息\n"));
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_CREATE: {
	sprintf(output, "检测到WM_CREATE消息,将创建窗口。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_SIZE: {
		sprintf(output, "lParam:窗口宽变化为:%d,窗口高变化为:%d \n", HIWORD(lParam), LOWORD(lParam));
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	//菜单命令消息
	case WM_COMMAND: {
		switch(LOWORD(wParam)) {
			case MY_OPEN: {
				sprintf(output, "打开按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
				break;
			}
			case MY_QUIT: {
				sprintf(output, "退出按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
				break;
			}
			case IDM_ABOUT: {
				sprintf(output, "帮助按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
			}
			case MY_NEWFILE: {
				sprintf(output, "打开新文件按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
				break;
			}
			case MY_LASTTIMEFILE: {
				sprintf(output, "上次打开文件按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
				break;
			}
		}
		break;
	}
	//键盘消息
	case WM_KEYDOWN: {
		sprintf(output, "检测到WM_KEYDOWN消息,键码值:%d.\n", wParam);
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_KEYUP: {
		sprintf(output, "检测到WM_KEYUP消息,键码值:%d.该按键被放开\n", wParam);
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	//鼠标消息
	case WM_LBUTTONDOWN: {
		sprintf(output, "检测到WM_LBUTTONDOWN消息,鼠标左键被按下。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_LBUTTONUP: {
		sprintf(output, "检测到WM_LBUTTONUP消息,鼠标左键被放开。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output),0,0);
		break;
	}
	case WM_RBUTTONDOWN: {
		sprintf(output, "检测到WM_RBUTTON消息,鼠标右键被按下。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_RBUTTONUP: {
		sprintf(output, "检测到WM_RBUTTON消息,鼠标右键被放开。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
	}
	case WM_MOUSEMOVE: {
		sprintf(output, "检测到WM_MOUSEMOVE消息,鼠标移动中,鼠标位置(%d,%d).\n", LOWORD(lParam), HIWORD(lParam));
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_MOUSEWHEEL: {
		sprintf(output, "鼠标滚轮滚动中,偏移量:%d,鼠标当前位置(%d,%d)\n",HIWORD(wParam), LOWORD(lParam), HIWORD(lParam));
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

我们来看看处理效果:
WM_COMMAND消息处理

二.上下文菜单

1.显示上下文菜单(右键菜单)

MSDN官方文档解释TrankPopupMensu函数

BOOL TrankPopupMenu(
	HMENU hMenu,      //要显示的快捷菜单的句柄。
	UINT nFlags,      //指定显示方式
	int x,
	int y,            //x,y分别为快捷菜单位置,x为水平位置,y为垂直位置(屏幕坐标系)
	int nReserved,    //保留,必须为0
	HWND hWnd,        //拥有快捷菜单的窗口句柄
	const RECT* prcRext  //已忽略
	);

注意: 这里的第一个参数hMenu,可以通过CreatePopopMenu函数来创建一个新的快捷菜单,也可以通过GetSubMenu函数来检索与现有菜单项关联的子菜单句柄来获取句柄。
这个函数是阻塞函数

2.上下文菜单中的WM_RBUTTONUP消息

鼠标右键被放开为窗口坐标系坐标,如果要转化为屏幕坐标系的话,请使用ClientToScreen函数。

3.WM_CONTEXTMENU消息

MSDN官方文档结束WM_CONTEXTMENU消息

  • 产生时间:鼠标右键被放开时
  • 附加信息
    • wParam:右键点击的窗口句柄
    • lParam:
      • LOWORD:x
      • HIWORD:y (注意是屏幕坐标系)

我们在讲解鼠标消息的时候,鼠标右键被放开时会产生WM_RBUTTONUP消息,这里的WM_CONTEXTMENU消息是在WM_RBUTTONUP消息之后产生的。

三.图标资源,光标资源

1.添加图标资源

像我们添加菜单资源一样,添加Icon资源
添加图标资源
添加好之后,我们可以选择自己画一个图标或者从外部添加图标,注意图标大小,一个图形文件中,可以有多个大小不同的图标。

2.加载图标资源

将图标资源设置好之后,我们需要拿到图标资源句柄
我们可以使用LoadIcon函数来获取图标句柄:
MSDN官方文档解释LoadIcon函数

HICON LoadIcon(
	HINSTANCE hInstance,     //图标资源的实例句柄
	LPCTSTR lpIconName       //要加载的图标资源的名称
);

获取到图标资源句柄之后,我们只需要在注册窗口时将图标资源句柄传给hIcon参数即可。

3.添加光标资源

像前文讲到的添加菜单资源,图标资源一样,我们只需要选择Coursor
添加光标资源
添加好光标资源后,每个光标还有FotSpot,是当前鼠标的热点,只有在这一点上,光标才起作用。

4.加载光标资源

添加好光标资源后,我们还是需要拿到光标资源句柄,我们可以使用HCURSOR函数来获取光标资源句柄。
MSDN官方文档解释LoadCursor函数

HCURSOR LoadCursor(
	HINSTANCE hInstance,        //光标资源句柄可以为0
	LPCTSTR lpCursorName        //光标资源名称
	);

当hInstance参数为0时,获取系统默认的光标资源

5.设置资源

  • 我们拿到光标资源句柄后,在注册窗口时,设置hCursor参数为我们拿到的光标资源句柄即可。
  • 我们也可以在创建窗口时,显示窗口之前,使用SetCursor函数来设置光标资源。

5.WM_SETCURSOR消息

  • 产生时间:如果鼠标导致光标在窗口移动,并且未捕获鼠标输入,则发送到窗口
  • 附加消息:
    • wParam:包含光标的窗口句柄
    • lParam:
      • LOWORD:当前区域代码(指定触发此消息的窗口,当进入菜单模式时,此字段为0)
      • HIWORD:当前鼠标消息ID

三.字符串资源

在这里我们讲一下,字符串资源到底有什么作用呢?
我们在做开发的时候,客户可能有时候让我们做中文版界面,有时候又想让我们改为英文版界面,这时候字符串资源就显得特别重要了,不让我们要改很多源码。
同样,我们到可视化图形界面来添加字符串资源
字符串资源

  • 获取字符串资源句柄
int LoadString(
	HINSTANCE hInstance,     //包含字符串资源的可执行文件的实例句柄
	UINT uID,      //要加载的字符串标识符
	LPTSTR lpBuffer,    //存放字符串的Buff
	int nBufferMax     //字符串Buff长度
	);

四.加速键资源

加速键资源这里定义的有点抽象了,其实就是快捷键。

1.添加加速键资源

我们还是添加资源–>添加Accelerator资源
添加加速键资源

2.加速键资源的使用

  • 加载加速键表

MSDN官方文档解释LoadAccelerstors函数
加载指定的加速器表。

HACCEL LoadAccelerators(
	HINSTANCE hInstance,      //模块的实例句柄
	LPCTSTR lpTableName       //要加载的加速表的名称
	);

这里注意,我们加载完加速表后,不能直接使用加速键表,我们还需要翻译加速键,
MSDN官方文档解释TranslateAccelerator函数,函数作用:处理菜单命令的快捷键。

int TranslateAccelerator(
	HWND hWnd,         //要翻译其消息的窗口句柄
	HACCEL hAccTable,  //加速器表的句柄
	LPMSG lpMsg        //指向Msg结构的指针,其中包括检索得到的消息
	);

那么加速器到底是怎么工作的?我们来写一段伪代码为大家讲解:

TranslateAcceleator(hWnd,hAccTable,&Msg){
	if(Msg.message != WM_KEYDOWN) return 0;
	根据Msg.wParam获知按键到底是哪个
	查表,到hAccelTable中比对是否存在该加速键
	if(没找到) return 0;
	else{
	SendMesage(hWnd,WM_COMMAND,ID_NEW....);
	return 0;
	}

今天的分享就到这里,如果文章中有错误之处,还请大家指出来,我会非常虚心得学习,希望我们共同进步!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/18545.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PMP证书“扫盲”时间2023年考证人快看过来

二&#xff0c;PMP报考指南 学历与工作经验要求&#xff1a; 本科及以上学历&#xff0c;三年或以上的项目管理工作经验&#xff1b; 专科及以上学历&#xff0c;五年或以上的项目管理工作经验。 项目管理培训&#xff1a;35小时以上的项目管理教育/培训。 备注&#xff1…

Unity Audio -- (3)创建3D音效

本节会添加场景中小瀑布的音效。小瀑布的音效会有一个作用范围&#xff0c;也会根据角色所处的位置不同&#xff0c;产生不同的效果。 添加小瀑布的声音 1. 在Hierarchy中&#xff0c;点击右键&#xff0c;选择Audio -> Create Audio Source&#xff0c;将这个新的Audio So…

NOA上车「清一色」自主品牌,哪些供应商正在突围前线

随着入门级L2进入普及周期&#xff0c;以NOA&#xff08;高速、城区&#xff09;为代表的L2/L2赛道&#xff0c;正在成为主机厂、硬件供应商、算法及软件方案商的下一波市场制高点的争夺阵地。 高工智能汽车研究院监测数据显示&#xff0c;2023年1-3月中国市场&#xff08;不含…

MySQL基础(十一)数据处理之增删改

1. 插入数据 1.1 实际问题 解决方式&#xff1a;使用 INSERT 语句向表中插入数据。 1.2 方式1&#xff1a;VALUES的方式添加 使用这种语法一次只能向表中插入一条数据。 情况1&#xff1a;为表的所有字段按默认顺序插入数据 INSERT INTO 表名 VALUES (value1,value2,....)…

第十五届吉林省赛个人题解【中档题(不过可能对你来说是简单题)】(H、G、C)

文章目录 H. Visit the Park(STL)G. Matrix Repair(思维题)C.Random Number Generator(BSGS算法) H. Visit the Park(STL) 题意&#xff1a;给你一个无向图&#xff0c;每条边上都有一个数码&#xff0c;然后给你一个路径&#xff0c;每次你必须从Ai走到Ai1&#xff08;直接走…

能否实现有价值观的--AI ?

人机融合所形成的新系统确实有可能产生新的科技革命。人机融合可以将人类的智慧和创造力与机器的计算能力和数据处理能力相结合&#xff0c;从而创造出更加智能化和高效化的新系统和产品。例如&#xff0c;人机融合可以推动智能制造、智能医疗、智能交通、智慧城市等各个领域的…

Go:值与指针

1. 计算机中的值 在百万年的演化历史中&#xff0c;人类对事物的属性进行了抽象&#xff0c;有了数量、精度、信息等概念的表示&#xff0c;对应的我们称之为整数、小数、文本文字等。计算机出现后&#xff0c;我们使用计算机对真实世界的问题进行建模&#xff0c;通过计算机的…

俩小伙一晚上写了个 AI 应用,月入两万??(文末附开发教程)

开发出一款能够与 AI 对话生成和编辑思维导图的工具&#xff0c;听起来似乎只能是一群专业的 AI 背景团队花费大量的时间和精力训练模型&#xff0c;打磨应用才能完成的事情。 但是&#xff0c;两名大学生却在一夜之间完成了&#xff0c;就像炼金术士将庸俗的材料转化成黄金一…

【c语言】字符串比较 | API仿真

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ …

Snipaste介绍、安装、使用技巧(截图贴图工具)

一、简介 Snipaste 是一个简单但强大的截图贴图工具&#xff0c;也可以让你将截图贴回到屏幕上&#xff01;下载并打开 Snipaste&#xff0c;按下 F1 来开始截图&#xff0c;再按 F3&#xff0c;截图就在桌面置顶显示了。就这么简单&#xff01; 你还可以将剪贴板里的文字…

学习分享|一文搞懂WiFi 6/7 以及选择路由器改造网络那些事

目录 什么是 WiFi 6 WiFi 6 功能特点 WIFI 6 与前几代对比 速度更快 延时更低 容量更大 更安全 更省电 WiFi 4~WiFi 6对比 WiFi 6 核心技术 WiFi 7 WiFi 世代列表 路由器常用技术扩展 2.5Ge 网口 WAN/LAN口复用/网口盲插 双WAN口 双LAN口端口聚合 mesh组网 聊…

思维导图手撕MyBatis源码

文章目录 前置准备通过类加载器读取配置文件流创建sqlSessionFactory建造者模式的使用 打开SqlSession获取Mapper接口对象执行Mapper接口方法 前置准备 既然要读MyBatis的源码&#xff0c;那么我们就要先弄清楚MyBatis的入口在哪。这里我们直接写一个标准的MyBatis使用程序&am…

6.1.1 图:基本概念

一&#xff0c;基本概念 1.基本定义 &#xff08;1&#xff09;图的定义 顶点集不可以是空集&#xff0c;但边集可以是空集。 &#xff08;2&#xff09; 有向图的表示&#xff1a; 圆括号 无向图的表示&#xff1a; 尖括号 简单图、多重图&#xff1a; 简单图&#xff1a;…

基于 SpringBoot+WebSocket 无DB实现在线聊天室

0 项目说明 0.1 样例展示 0.2 源码地址 GitHub&#xff1a;https://github.com/ShiJieCloud/web-chat Gitee&#xff1a;https://gitee.com/suitbaby/web-chat GitCode&#xff1a;I’m Jie / web-chat GitCode 1 WebSocket 简介 1.1 HTTP 常用的 HTTP 协议是一种无状态…

刚进公司就负责项目,把老弟整蒙了!

刚进公司就负责项目&#xff0c;把老弟整蒙了&#xff01; 大家好&#xff0c;我是鱼皮&#xff0c;先把封面图送给大家&#xff1a; 又快到周末了&#xff0c;今天分享一些轻松的编程经验~ 还记得我学编程的老弟小阿巴么&#xff1f;他目前大二&#xff0c;听说最近刚刚找到…

Redis超详细入门手册教程!还不快来看看?

地址&#xff1a; RedisRedis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. Redis provides data structures …https://redis.io/ 1&#xff1a;NoSQL简介 1.1&#xff1a;数据库应用的演变历程 单…

线程的原子性、可见性、有序性及线程安全知识整理

要想保证线程安全&#xff0c;必须同时满足原子性、可见性、有序性。 一、定义 1.1 原子性 一个操作或者多个操作&#xff0c;要么全部执行&#xff0c;并且执行的过程不会被打断&#xff0c; 要么就全部不执行&#xff08;一个操作是不可被分割的&#xff09;。 Java中实现…

ApiPost简单使用

目录 环境与变量 设置与使用 随机参数变量 内置Mock字段随机参数 自定义随机参数 全局参数 使用手册 apipost可支持一键压测和自动化接口测试 环境与变量 设置与使用 设置 环境变量可设置环境名称、变量名称、变量初始值、URL&#xff1a; 可以在请求变量或者接口 URL…

攻防世界-web-simple js

题目描述&#xff1a;小宁发现了一个网页&#xff0c;但却一直输不对密码。(Flag格式为 Cyberpeace{xxxxxxxxx} ) 打开链接&#xff1a; 然后我们会发现不管我们输入什么密码&#xff0c;发现是都是这样的报错 1. 先用bp抓包看看&#xff0c;可以抓到这样的一串js脚本 看不懂…

matlab实现BP神经网络(完整DEMO)

本站原创文章&#xff0c;转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com 目录 一、BP神经网络Demo代码 1.1 代码整体思路 1.2 BP神经网络Demo代码 二、运行结果 2.1 拟合曲线 2.2训练误差与预测误差 三、相关文章 3.1-BP的入门学习目录&#xff1a;老饼…