Win32编程API 基础篇 -- 5.使用资源
使用资源
你可能想参考教程结尾的附近,为了获得跟VC++和BC++资源相关的信息。
在我们讲得更加深入之前,我将大致讲解一下资源的主题,这样在每个小节中我就不必再去重讲一遍了。在这一小节中,你不需要编译任何东西,这里的代码只是个例子。
资源是以二进制的格式存储在你的可执行文件内部的预定义的数据,在资源脚本中我们创建资源,所谓的资源脚本就是有”.rc”扩展名的群文件,商业编译器通常有一个视觉资源编辑器老让你在不需要手动编辑的情况下创建资源,但很多时候手动这是唯一的创建资源的方法,如果你的编译器没有视觉编辑器的话,或者它很糟糕,不支持你所需要的具体功能。
很不幸的是不同的编译器套件处理资源的方式是不一样的,我将竭尽所能来解释一般情况下资源工作的共同特征。
资源编辑器附带MSVC++使它很难手动编辑资源,因为它执行一个专有格式,并且如果你手动创建了一个资源,整个文件都可能被完全损坏,所以一般情况下你不应该打扰资源文件的创建,但是明白如何手动修改它们有时又是很有用的。另一个比较蛋疼的就是MSVC++将默认资源头文件的命名为“resuorce.h”即使你想使用其他命名。为了简单起见我将以这个文档中数据为基础,但在附录中会向您展示如何在编辑器中进行修改。
首先,让我们看一段非常简单的资源脚本,一个图标。
#include "resource.h" IDI_MYICON ICON "my_icon.ico"
这是整个的文件,IDI_MYICON是资源标识符,ICON是类型,“my_icon.ico”包含资源文件的扩展名,在所有的编译器中都应该生效。
#include "resource.h"跟什么相关呢?嗯,你的程序需要一种定义图标的方式,最好的方式就是分配一个唯一的ID(IDI_MYICON),我们可以通过创建一个“resource.h”文件然后在我们的资源脚本文件和源代码文件中引入。
#define IDI_MYICON 101
正如你所看到的,我们指定了IDI_MYICON的值为101,我们可以不使用定义直接使用101当引入图标的时候,但是IDI_MYICON引入的写法更加清爽,并且在大量引入资源文件的时候更容易记住。
现在让我们添加一个菜单资源:
#include "resource.h" IDI_MYICON ICON "my_icon.ico" IDR_MYMENU MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
END
同样的IDR_MYMENU是资源的名称而MENU是资源类型。现在好点,看到了开始和结束了么?一些资源编辑器或编译器使用“{”和“}”分别用来替代BEGIN和END,如果你的编译器两个都支持随意选择其中一种方式。如果它只支持其中一种或者其他方式,你需要进行必要的更换工作保证正常使用。
我们也添加了一个新的标识符ID_FILE_EXIT,所以为了在我们的程序中使用,我们需要把它添加在我们的资源头文件resource.h中。
#define IDI_MYICON 101
#define ID_FILE_EXIT 4001
在大型的项目中生成和跟踪这些ID是一件很蛋疼的事,这就是大多数人使用为你完成这些工作的视觉资源编辑器的原因。但它仍然会时不时弄糟,你可能最终会遇到多个项目相同ID或类似的问题,这时候手动调整有利于解决问题。
现在下面有一个如何在你的程序中使用资源的栗子:
HICON hMyIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
LoadIcon和许多资源使用函数的第一个参数就是当前窗口实例的句柄(这个在我们的WinMain()中被给出了,同时也可以使用我们前面提到的GetModuleHandle()来得到这个句柄)第二个参数就是资源的标识符。
你可能会想MAKEINTRESOURCE()是用来干嘛的,也可能会想当我们要传递给LoadIcon()资源ID参数时,为什么会取一个LPCTSTR类型的参数而不是用UINT。所有的MAKEINTRESOURCE()做的事情就是把一个整型的ID变成LPCTSTR类型,而这是LoadIcon想要的参数类型。这就引出了定义资源的第二种方式,就是直接使用字符串,几乎不会有人再这样做,所以在这里我们简略说说,但是基本上如果你没有用#define的方式为你的资源指定ID,那么这个资源名就会被解析成字符串,在你的程序中可以这样子引用:
HICON hMyIcon = LoadIcon(hInstance, "MYICON");
LoadIcon()和其他加载资源的API可以区分传递的是一个资源ID还是一个指向字符串的指针通过检查这个值的高16位,如果高16位是0(整数的范围是0到65535)将被认定为传入的是一个资源ID,这很有效如果你限定你的资源ID在65535以下,这个应该够用了除非你有超多资源,所以应该没有问题;如果高16位不是0那么就会被认定为是一个指向字符串的指针,加载资源的函数就会通过资源名去查找资源。永远不要依赖于API去实现这个除非它在文档中被明确规定。
例如,这并不适合像ID_FILE_EXIT菜单命令,因为他们只能是整数。
PS.由于本人英文水平所限,只能翻译到这个程度了,有纰漏还望多多指出,附上本篇翻译的英文原版教程地址:http://www.winprog.org/tutorial/resources.html
Win32编程API 基础篇 -- 5.使用资源的更多相关文章
- Win32编程API 基础篇 -- 1.入门指南 根据英文教程翻译
入门指南 本教程是关于什么的 本教程的目的是向你介绍使用win32 API编写程序的基础知识(和通用的写法).使用的语言是C,但大多数C++编译器也能成功编译,事实上,教程中的绝大多数内容都适用于任何 ...
- Win32编程API 基础篇 -- 6.菜单和图标
菜单和按钮 例子:菜单1 本小节仅仅向你展示如果向你的窗口中加入一个基本的菜单,通常你会用到一个提前制作好的菜单资源,这会是一份.rc文件并且会被编译链接进你的.exe可执行程序中.这是具体的流程做法 ...
- Win32编程API 基础篇 -- 4.消息循环
消息循环 理解消息循环 为了编写任何即使是最简单的程序,了解windows程序的消息循环和整个消息发送结构是非常有必要的.既然我们已经尝试了一点消息处理的东西,我们应该对整个程序有更深入的理解,如果你 ...
- Win32编程API 基础篇 -- 3.消息处理 根据英文教程翻译
消息处理 例子:窗口点击 好的,现在我们已经得到一个窗口了,但我们什么也做不了除了DefWindowProc()允许窗口大小被调整,最大最小化等...这不是很激动人心啊 在接下来的一小节中我将向你展示 ...
- Win32编程API 基础篇 -- 2.一个简单的窗口 根据英文教程翻译
一个简单的窗口 例子:简单的窗口 有时人们在IRC提问,”我应该怎样制作一个窗口”...嗯,这恐怕不是完全这么简单好回答!其实这并不难一旦你明白你在做什么,但在你得到一个可展示的窗口之前还有一些事情需 ...
- ASP.NET Web API 基础篇1
ASP.NET Web API 直到我膝盖中了一箭[1]基础篇 无题 蓦然回首,那些年,我竟然一直很二. 小时候,读武侠小说的时候,看到那些猪脚,常常会产生一种代入感,幻想自己也会遭遇某种奇遇,遇到悬 ...
- (转)Android高性能编程(1)--基础篇
关于专题 本专题将深入研究Android的高性能编程方面,其中涉及到的内容会有Android内存优化,算法优化,Android的界面优化,Android指令级优化,以及Android应用内存占 ...
- 【TCP/IP】之Java socket编程API基础
Socket是Java网络编程的基础,深入学习socket对于了解tcp/ip网络通信协议很有帮助, 此文讲解Socket的基础编程.Socket用法:①.主要用在进程间,网络间通信. 文章目录如下: ...
- 我拖拖拖--H5拖放API基础篇
不要搞错,本文不是讲如何拖地的.看过<javascript精粹>朋友应该知道,他实现拖放的过程比较复杂,现在时代不同了,我们用H5的新的拖放API就能非常方便的实现拖放效果了.最近在园子见 ...
随机推荐
- 洛谷2019 3月月赛 T4
T3做不来.. 直接滚去T4 orz 乍一看 T4是个DP 题干 复杂度??(N^4) 咋优化... 还带一只捆绑 捆绑啥的最烦人了 最后20pts 直接废了 T了 很烦 不过拿到80pts已经很开心 ...
- 【知识总结】多项式全家桶(三)(任意模数NTT)
经过两个月的咕咕,"多项式全家桶" 系列终于迎来了第三期--(雾) 上一篇:[知识总结]多项式全家桶(二)(ln和exp) 先膜拜(伏地膜)大恐龙的博客:任意模数 NTT (在页面 ...
- Joseph UVA 1452 Jump
题目传送门 /* 数学:约瑟夫环问题的变形,首先定义f[i]表示剩下i个人时,最后一个选出的人,有个公式:f[i] = (f[i-1] + m) % i f[1] = 0(编号从0开始),那么类似最后 ...
- ACM_01背包
背包1 Time Limit: 2000/1000ms (Java/Others) Problem Description: 有n个重量和价值分别为Wi,Vi的物品,现从这些物品中挑选出总量不超过 W ...
- 视图解析器InternalResourceViewResolver在什么情况下需要配置?在什么情况下不需要配置?
如果路径名是逻辑名的话,必须配置 -------------- 相对路径,即逻辑名称如果路径名是真实名的话,可选配置 若是绝对路径,则不用配置,即真实名称 注:试一下逻辑名和真实名的例子*****有用 ...
- DHTML_____document对象的方法
<html> <head> <meta charset="utf-8"> <title>document对象的方法</titl ...
- MySQL的主从复制(windows)
在我们实际的开发中,当系统业务到达一定的程度,可能数据库会到达一定的瓶颈,但实际开发中最容易到达数据库瓶颈的应该是数据库的读性能,一般的业务大多都是读多写少,我们可以通过提高读的性能来提高数据库的整体 ...
- python中os模块中文帮助
python中os模块中文帮助 python中os模块中文帮助文档文章分类:Python编程 python中os模块中文帮助文档 翻译者:butalnd 翻译于2010.1.7——2010.1.8 ...
- PHP开发心得二
如何解决错误:PHP SOAP Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML documen ...
- (转)解决office软件无法卸载也无法安装的顽固问题
原文地址 http://jingyan.baidu.com/article/f3ad7d0fcfe32509c3345bab.html 有时会出现office下载失败,然后又无法重新安装,导致offi ...