《Windows API每日一练》9.1 资源-图标

本节讲述图标、鼠标指针位图、字符串资源表、自定义资源的添加和应用。

本节必须掌握的知识点:

        图标

        第56练:ICON图标资源

        鼠标指针位图

        字符串资源表

        自定义资源

        第57练:字符串资源表和自定义资源

9.1.1 图标

在 Windows 窗口编程中,图标(Icon)是用于表示应用程序、窗口或文件的小图像。Windows 提供了几种不同尺寸和颜色深度的图标,用于在窗口标题栏、任务栏、文件资源管理器等地方显示。

以下是一些与图标相关的常见任务和概念:

●创建图标文件:

1.图标文件通常使用 .ico 扩展名,可以包含多个图标资源。

2.可以使用图标编辑器(如 Visual Studio、Visual Studio Code、GIMP 等)创建或编辑图标文件。

●加载和显示图标:

1.使用 LoadIcon 函数从 .ico 文件或资源中加载图标。

2.使用 DrawIcon 函数将图标绘制到设备上下文(DC)中的指定位置。

●获得图标的大小:

cxIcon = GetSystemMetrics (SM_CXICON) ;

cyIcon = GetSystemMetrics (SM_CYICON) ;

●设置窗口图标:

1.使用 WM_SETICON 消息或 SetClassLongPtr 函数设置窗口的大图标和小图标。

2.大图标通常在窗口的标题栏和任务栏中显示,小图标显示在窗口的任务栏按钮中。

●资源文件中的图标:

1.可以将图标资源添加到应用程序的资源文件(.rc)中。

2.在应用程序启动时,可以使用 LoadIcon 或 LoadIconEx 函数加载资源文件中的图标。

在应用程序中使用图标

Windows程序可以在定义一个带有WNDCLASS结构并使用RegisterClass注册的窗口类中指定图标。当图标文件同时包含标准大小和小号图像时。在需要显示图标图像时,Windows会在图标文件中选择大小最合适的图像。

RegisterClass有一个增强版本,名为RegisterClassEx,它使用一个名为WNDCLASSEX 的结构。WNDCLASSEX结构有两个额外的字段:cbSize和blconSm。cbSize字段表示 WNDCLASSEX结构的大小,而hlconSm应该被设为小图标的句柄。因此,在WNDCLASSEX结构中你需要设定与两个图标文件相关联的两个图标句柄—— 一个是标准图标而另一个是小图标。

因为Windows可以从单个图标文件中提取了正确尺寸的图标图像。RegisterClassEx似乎没有必要。如果hlconSm字段引用的是一个包含多个图像的图标文件,那么只有第一个会被使用。这可以是一个标准尺寸的图标,只不过之后会被缩小。RegisterClassEx似乎是为使用多个图标图像设计的,这些图像每个只包含一个图标尺寸。因为可以在同一个文件中包含多个图标尺寸,所以使用 WNDCLASS 和 RegisterClass也是可以的。

如果想在程序运行时动态改变程序的图标,可以通过调用SetClassLong函数来实现。 比如,如果有另一个和标识符IDI_ALTICON 相关联的图标文件,便可以使用下面的语句 切换到那个图标:

SetClassLong (hwnd, GCL_HICON,

       LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ALTICON))) ;

如果不想保存程序图标的句柄,而是使用Drawlcon函数来在某处显示它,那么你可以 调用GetClassLong函数来获得句柄。比如:

DrawIcon (hdc, x, y, GetClassLong (hwnd, GCL_HICON)) ;

在Windows文档的某些地方,LoadIcon被描述为“已过时”,而Loadlmage被推荐使 用。LoadImage当然更灵活,但它目前还无法代替Loadlcon的简洁性。你会注意到在 ICONDEMO中Loadlcon对同一图标被调用了两次。这不是个问题,不会因此有更多内存被使用。Loadlcon是少有的这样几个函数之一:它获得一个句柄,但不要求该句柄被销毁。 实际上确实存在一个DestroyIcon函数,但它是和Createlcon、Createlconlndirect以及 CreateIconFromResource配套使用的。这些函数允许程序用算法动态生成图标。

■下面是一个示例代码片段,展示了如何加载和设置窗口图标:

HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)); //加载图标资源

SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); //设置大图标

SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); //设置小图标

在上述示例中,hInstance 是应用程序的实例句柄,IDI_ICON1 是图标资源的 ID。可以使用资源编辑器将图标资源添加到应用程序的资源文件中,并分配一个唯一的 ID 给它。

VS添加资源步骤:

1.选中资源文件,鼠标右键>添加>资源

图9-1 添加资源

  2.点击添加后,自动生成ICONDEMO.rc和resource.h文件。选择Icon,点击新建或导入现有的Icon图标资源。

 图9-2 新建或导入图标资源

 3.资源视图窗口,选中已添加的资源ID_ICON1,鼠标右键选择属性或者ALT+ENTER键打开图标编辑器修改ID。

 图9-3 定义图标资源属性

4.修改ico文件名和ID并保存,或者按下ALT+ENTER键修改资源属性。

 图9-4 修改图标文件名和ID

9.1.2 第56练:ICON图标资源

/*------------------------------------------------------------------------

 056 WIN32 API 每日一练

     第56个例子ICONDEMO.C:ICON图标资源

     LoadIcon 函数

     MAKEINTRESOURCE

     DrawIcon函数

     按下ALT+ENTER键修改资源属性

 (c) www.bcdaren.com 编程达人

-----------------------------------------------------------------------*/

#include <windows.h>

#include "resource.h" //编译器添加资源时自动创建的头文件

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

TCHAR szAppName[] = TEXT("IconDemo");//程序名

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

 PSTR szCmdLine, int iCmdShow)

{

     //TCHAR szAppName[] = TEXT("IconDemo");

     HWND hwnd;

     MSG msg;

     WNDCLASSEX wndclass;

     wndclass.cbSize = sizeof(WNDCLASSEX);  //新增

     wndclass.hIconSm = NULL;               //新增

     wndclass.style = CS_HREDRAW | CS_VREDRAW;

     wndclass.lpfnWndProc = WndProc;

     wndclass.cbClsExtra = 0;

     wndclass.cbWndExtra = 0;

     wndclass.hInstance = hInstance;

     //szAppName为字符串ID,对应资源中的位图ID需要修改为字符串ID"IconDemo"

    // wndclass.hIcon = LoadIcon(hInstance, szAppName);

     wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));//数字ID

     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

     wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);

     wndclass.lpszMenuName = NULL;

     wndclass.lpszClassName = szAppName;

     if (!RegisterClassEx(&wndclass))   //RegisterClassEx

     {

          MessageBox(NULL, TEXT("This program requires Windows NT!"),

               szAppName,

               MB_ICONERROR);

          return 0;

     }

     hwnd = CreateWindow(szAppName, TEXT("Icon Demo"),

          WS_OVERLAPPEDWINDOW,

          CW_USEDEFAULT, CW_USEDEFAULT,

          CW_USEDEFAULT, CW_USEDEFAULT,

          NULL, NULL, hInstance, NULL);

     ShowWindow(hwnd, iCmdShow);

     UpdateWindow(hwnd);

     while (GetMessage(&msg, NULL, 0, 0))

     {

          TranslateMessage(&msg);

          DispatchMessage(&msg);

     }

     return msg.wParam;

}

LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam, LPARAM

lParam)

{

     static HICON hIcon;

     static int cxIcon,cyIcon,cxClient,cyClient;

     HDC hdc;

     HINSTANCE hInstance;

     PAINTSTRUCT ps;

     int x,y;

     switch (message)

     {

     case WM_CREATE:

          hInstance = ((LPCREATESTRUCT)lParam)->hInstance;

          //hIcon = LoadIcon(hInstance,szAppName);//字符串ID

          hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));//数字ID

         

          cxIcon = GetSystemMetrics(SM_CXICON);//获取图标尺寸

          cyIcon = GetSystemMetrics(SM_CYICON);

          return 0;

     case WM_SIZE:

          cxClient = LOWORD(lParam);//图标位置

          cyClient = HIWORD(lParam);

          return 0;

     case WM_PAINT:

          hdc = BeginPaint(hwnd,&ps);

          //绘制图标

          for (y = 0;y < cyClient;y += cyIcon)

          {

               for (x = 0;x < cxClient;x += cxIcon)

               {

                    DrawIcon(hdc,x,y,hIcon);//显示图标

               }

          }

          EndPaint(hwnd,&ps);

          return 0;

     case WM_DESTROY:

          PostQuitMessage(0);

          return 0;

     }

     return DefWindowProc(hwnd,message,wParam,lParam);

}

/******************************************************************************

LoadIcon 函数:从与应用程序实例关联的可执行(.exe)文件中加载指定的图标资源。

HICON LoadIconA(

  HINSTANCE hInstance,//模块实例的句柄,其可执行文件包含要加载的图标。加载标准图标时,此参数必须为NULL。

  LPCSTR    lpIconName//要加载的图标资源的名称。或者,此参数可以在低位字中包含资源标识符,在高位字中包含零。

                      //使用MAKEINTRESOURCE宏来创建此值。

);

返回值

类型:HICON

如果函数成功,则返回值是新加载的图标的句柄。

*******************************************************************************

MAKEINTRESOURCEA宏:将整数值转换为与资源管理功能兼容的资源类型。使用此宏代替包含资源名称的字符串。

void MAKEINTRESOURCEA(

   i //要转换的整数值。

);

*******************************************************************************

DrawIcon函数:将图标或光标绘制到指定的设备上下文中。若要指定其他绘图选项,请使用DrawIconEx函数。

BOOL DrawIcon(

  HDC   hDC,   //设备上下文的句柄,将在其中绘制图标或光标。

  int   X,     //图标左上角的逻辑x坐标。

  int   Y,     //图标左上角的逻辑y坐标。

  HICON hIcon  //要绘制的图标的句柄。

);

*/

●Resource文件:

//{{NO_DEPENDENCIES}}

// Microsoft Visual C++ 生成的包含文件。

// 供 056_ICONDEMO.rc 使用

//

#define IDI_ICON1                       101

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE        102

#define _APS_NEXT_COMMAND_VALUE         40001

#define _APS_NEXT_CONTROL_VALUE         1001

#define _APS_NEXT_SYMED_VALUE           101

#endif

#endif

●056_ICONDEMO.rc:

// Microsoft Visual C++ generated resource script.

//

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS

/

//

// Generated from the TEXTINCLUDE 2 resource.

//

#include "winres.h"

/

#undef APSTUDIO_READONLY_SYMBOLS

/

// 中文(简体,中国) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)

LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED

#ifdef APSTUDIO_INVOKED

/

//

// TEXTINCLUDE

//

1 TEXTINCLUDE

BEGIN

    "resource.h\0"

END

2 TEXTINCLUDE

BEGIN

    "#include ""winres.h""\r\n"

    "\0"

END

3 TEXTINCLUDE

BEGIN

    "\r\n"

    "\0"

END

#endif    // APSTUDIO_INVOKED

/

//

// Icon

//

// Icon with lowest ID value placed first to ensure application icon

// remains consistent on all systems.

IDI_ICON1               ICON                    "icon1.ico"

#endif    // 中文(简体,中国) resources

/

#ifndef APSTUDIO_INVOKED

/

//

// Generated from the TEXTINCLUDE 3 resource.

//

/

#endif    // not APSTUDIO_INVOKED

       运行结果:

图9-5 图标资源

 

总结

实例ICONDEMO.C添加了一个图标资源,并且在窗口客户区内填充图标位图。图标位图文件icon1.ico位于当前编译目录。

添加图标资源的方法在上一小节中已经讲述,在解决方案的“资源文件”目录下点击鼠标右键,选择添加>资源>ICON,导入icon1.ico位图文件。然后VS自动创建re’source资源头文件和056_ICONDEMO.rc资源脚本文件。re’source资源头文件中包含图标资源的数字ID 101,056_ICONDEMO.rc资源脚本文件的资源类型为ICON,将图标资源ID绑定图标位图文件:

IDI_ICON1               ICON                    "icon1.ico"

实例的WinMain主程序中,定义了一个扩展窗口类WNDCLASSEX,对比WNDCLASS结构新增了“cbSize”结构大小字段和“hIconSm”小图标字段。在hIcon字段添加图标:

wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));//数字ID

【注意】由于添加图标资源时使用的是数字ID,所以这里需要使用MAKEINTRESOURCE宏将IDI_ICON1转换为字符串ID。

请读者测试:如果我们将资源中的图标位图ID修改为字符串ID"IconDemo",则不需要转换:

wndclass.hIcon = LoadIcon(hInstance, szAppName);

窗口过程:

处理WM_CREATE消息:调用LoadIcon函数加载图标资源,获取图标资源句柄。然后调用GetSystemMetrics函数获取图标资源尺寸。

处理WM_SIZE消息:获取窗口客户区宽和高。

处理WM_PAINT消息:调用DrawIcon函数在窗口客户区内填充图标。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

知识付费系统3.0整站源码知识付费网课平台网创资源付费带自动采集同步插件

程序说明&#xff1a; 1.修复更新到最新版本 2.自动采集插件重写 3.关闭采集授权域名直接对接 4.更新插件主动请求同步资源 5.带自动采集插件 原始功能 支持分类替换 将主站同步过来的文章分类进行替换 支持自定义文章作者&#xff08;选择多个作者则同步到的文章作者将会随机分…

java中==和equals()的区别探究

目录 一、Object对象 二、 三、String类的equals()方法 四、示例 4.1直接定义两个相同的值比较 4.2直接定义两个值不同的字符串进行比较 4.3直接定义一个字符串和new一个字符串进行比较&#xff08;两者值相同&#xff09; 4.4直接定义一个字符串和new一个字符串进行…

Halcon Ean13 一维码读取

一 EAN码介绍 1 EAN码定义: EAN码是国际物品编码协会制定的一种商品用条码&#xff0c;通用于全世界。EAN码符号有标准版&#xff08;EAN-13&#xff09;和缩短版&#xff08;EAN-8&#xff09;两种。标准版表示13位数字&#xff0c;又称为EAN13码&#xff0c;缩短版表示8位数…

VScode免密链接ubuntu

Ubuntu 下载&#xff1a; sudo apt-get install openssh-serverps -e | grep sshd参考IP &#xff1a; ifconfig VScode配置 重新尝试连接&#xff0c;输入的密码是虚拟机用户密码 免密链接 Windows生成公钥 1、打开CMD 2、输入命令ssh-keygen 3、连续回车确认即可生成 …

正态、威布尔、指数分布、伽马分布、对数正态分布介绍

目录 正态、威布尔、指数分布、3.1 概念介绍概率密度函数&#xff08;PDF&#xff09;累积分布函数&#xff08;CDF&#xff09;性质应用 3.2 参数及绘图参数概率密度函数&#xff08;PDF&#xff09;累积分布函数&#xff08;CDF&#xff09;绘图图像解读 3.3 指数分布拟合代码…

第11章 规划过程组(二)(11.10制订进度计划)

第11章 规划过程组&#xff08;二&#xff09;11.10制订进度计划&#xff0c;在第三版教材第395~397页&#xff1b;文字图片音频方式 第一个知识点&#xff1a;定义及作用 分析活动顺序、持续时间、资源需求和进度制约因素&#xff0c;创建项目进度模型&#xff0c;从而落实项目…

Docker定时清理

一、循环调度执行 1、检查cron状态 systemctl status crond 2、创建要执行的shell脚本 vim /home/cleanup_docker.sh #! /bin/bash # 清理临时文件 echo $(date "%H:%M:%S") "执行docker清理命令..." docker system prune -af-a 清理包括未使用的镜像 …

Android EditText+ListPopupWindow实现可编辑的下拉列表

Android EditTextListPopupWindow实现可编辑的下拉列表 &#x1f4d6;1. 可编辑的下拉列表✅步骤一&#xff1a;准备视图✅步骤二&#xff1a;封装显示方法✅步骤三&#xff1a;获取视图并监听 &#x1f4d6;2. 扩展上下箭头✅步骤一&#xff1a;准备上下箭头icon图标✅步骤二&…

Redisson分布式锁、可重入锁

介绍Redisson 什么是 Redisson&#xff1f;来自于官网上的描述内容如下&#xff01; Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格客户端&#xff08;In-Memory Data Grid&#xff09;。它不仅提供了一系列的 redis 常用数据结构命令服务&#xff0c;还提供了…

北森锐途人才竞聘盘点管理测评:高管领导力六大评判标准深度解析万达商管中国绿发等

北森锐途人才管理测评&#xff1a;高管领导力评判标准深度解析 在企业高管的盘点与竞聘测评领域&#xff0c;众多管理人才面临评估自身领导力的挑战。面对能力卓越、职级显赫的同僚&#xff0c;许多管理者感到缺乏一套权威且专业的评价体系。然而&#xff0c;无论是天赋异禀的领…

vue+cesium之加载天地图影像底图与注记

目录 1.创建地图容器2.叠加天地图影像底图与矢量注记 关键代码3.示例效果图 Cesium是默认加载了微软公司的Bing地图&#xff0c;并提供了BingMapslmageryProvider类来加载Bing地图。也就是说&#xff0c;在创建Viewer时&#xff0c;如果不指定lmageryProvider类就默认加载Bing地…

2024年7月2日~2024年7月8日周报

目录 一、前言 二、完成情况 2.1 吴恩达机器学习系列课程 2.1.1 分类问题 2.1.2 假说表示 2.1.3 判定边界 2.2 学习数学表达式 2.3 论文写作情况 2.3.1 题目选取 2.3.2 摘要 2.3.3 关键词 2.3.4 引言部分 2.3.4 文献综述部分 三、下周计划 3.1 存在的问题 3.2 …

C语言之数据在内存中的存储(1),整形与大小端字节序

目录 前言 一、整形数据在内存中的存储 二、大小端字节序 三、大小端字节序的判断 四、字符型数据在内存中的存储 总结 前言 本文主要讲述整型包括字符型是如何在内存中存储的&#xff0c;涉及到大小端字节序这一概念&#xff0c;还有如何判断大小端&#xff0c;希望对大…

2、需求工具 - 编程实战工具系列文章

需求分析工具 笔者对于需求分析工具的应用&#xff0c;主要是思维导图软件和Word。思维导图用来理清需要的需求功能&#xff0c;而Word用来记录每个需求功能的实际内容。 对于思维导图软件&#xff0c;笔者用过几个&#xff0c;但是有些需要注册码&#xff0c;有些需要费用&…

谷粒商城学习-09-配置Docker阿里云镜像加速及各种docker问题记录

文章目录 一&#xff0c;配置Docker阿里云镜像加速二&#xff0c;Docker安装过程中的几个问题1&#xff0c;安装报错&#xff1a;Could not resolve host: mirrorlist.centos.org; Unknown error1.1 检测虚拟机网络1.2 重设yum源 2&#xff0c;报错&#xff1a;Could not fetch…

Redis基础教程(十五):Redis GEO地理信息查询与管理

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

绝区伍--2024年AI发展路线图

2024 年将是人工智能具有里程碑意义的一年。随着新模式、融资轮次和进步以惊人的速度出现&#xff0c;很难跟上人工智能世界发生的一切。让我们深入了解 2024 年可能定义人工智能的关键事件、产品发布、研究突破和趋势。 2024 年第一季度 2024 年第一季度将推出一些主要车型并…

从零开始读RocketMq源码(二)Message的发送详解

目录 前言 准备 消息发送方式 深入源码 消息发送模式 选择发送方式 同步发送消息 校验消息体 获取Topic订阅信息 高级特性-消息重投 选择消息队列-负载均衡 装载消息体发送消息 压缩消息内容 构造发送message的请求的Header 更新broker故障信息 异步发送消息 …

Open3D KDtree的建立与使用

目录 一、概述 1.1kd树原理 1.2kd树搜索原理 1.3kd树构建示例 二、常见的领域搜索方式 2.1K近邻搜索&#xff08;K-Nearest Neighbors, KNN Search&#xff09; 2.2半径搜索&#xff08;Radius Search&#xff09; 2.3混合搜索&#xff08;Hybrid Search&#xff09; …

后端之路——登录校验前言(Cookie\ Session\ JWT令牌)

前言&#xff1a;Servlet 【登录校验】这个功能技术的基础是【会话技术】&#xff0c;那么在讲【会话技术】的时候必然要谈到【Cookie】和【Session】这两个东西&#xff0c;那么在这之前必须要先讲一下一个很重要但是很多人都会忽略的一个知识点&#xff1a;【Servlet】 什么是…