Win32程序资源的使用

作为一个可执行的应用程序文件,应该包含2部分,一部分是数据区,另一部分是程序代码区。数据区一般可分为2类:读写数据和只读数据。对于windows程序,有大量的只读数据。所谓资源就是应用程序运行期间通常不能更改或不需要更改的数据。

windows程序资源有以下几种:

  1. 加速键 Accelerator
  2. 位图 Bitmap
  3. 光标 Cursor
  4. 对话框 Dialog
  5. HTML
  6. 图标 Icon
  7. 菜单 Menu
  8. 字符串表 String Table
  9. 工具条 ToolBar
  10. 版本 version
  11. 以及用户自定义的资源。

1.资源的使用方法

  1. 定义资源
  2. 加载资源
  3. 使用资源

定义资源:资源出的创建和用户的程序时分离的,资源是以rc为扩展名的资源描述文件中,而再以cpp作为扩展名的源代码文件中,资源需要使用定义语句描述后才能使用.
资源描述问价语句,并不是c/c++语句,而是特殊的资源语句.你可以新建一个win32程序,然后用VS打开该程序的.rc文件.一旦创建了.rc文件,就可以使用资源编辑器将其译成.res文件,然后被链接到.exe文件中.


加载资源:尽管资源数据也是作为应用程序文件的一部分,但在程序装入内存是,它并不自动装入,而是由程序根据需要,通过调用API函数来装入,这个过程称为资源的加载.
每种资源的加载函数不同,但是大致的格式相似.资源加载函数都是以load加上具体的资源名来命名的,如加载图标的函数是LoadIcon(),加载光标是LoadCursor().


使用资源:每种资源的定义和加载过程大同小异,但是资源的使用就不尽相同了.每种资源使用的概念、使用的具体方法和步骤都有可能不同,需要结合具体的情况讲解.


1.图标的使用

当你打开一个人应用程序是,应用程序的左上角会有一个图标,对应于下面的任务栏也会有一个图标,这两个图标分别对应以下两句:

    wcex.hIcon          = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));//IDI_ICON1是我自己的图标。
    wcex.hIconSm        = LoadIcon(NULL, IDI_QUESTION);

那么就给我们指明了修改应用程序图标的方向:在窗口类注册的时候修改。如果你想动态修改图标,那么可能还需要用到WM_SETICON消息。


  1. 一个Icon就是一个小的位图,一般是代表一个应用程序的特殊最小位图。同常用的资源一样,你可以使用系统预定义资源和你自己定义的,系统预定义的图标是一些常见的形状,用宏定义方式,所以使用的时候不需要使用转换宏:MAKEINTERSOURCE。但是要注意,使用系统预定义的图标时,LoadIcon的第一个参数要设为NULL。下面是IDI_QUESTION的图标截图:
    这里写图片描述
    可以看到变成了一个问号。
  2. vs是集成了资源编辑器的,所以你也可以自己编一个图标。具体操作是:视图->资源视图->Icon->右键->添加资源->Icon->新建。系统会自动生成一个名为IDI_ICON1的图标。利用编辑工具可以编辑自己的图标,如下:
    这里写图片描述
    注意如果你只是选择了其中的一种格式进行编辑,则需要删除其它的格式。右键删除图标类型即可。
    然后去ATOM MyRegisterClass(HINSTANCE hInstance)函数里面将wcex.Icon改为IDI_ICON1即可。
    效果如下
  3. 在新建资源的时候,我们也看到还有其它的选项,其中有一个是导入,我们自己画的可能不那么好,这是可以导入别人创建的,如下:
    这里写图片描述
    导入了一个256*256的彩色图片,导入后,直接在原来的地方改一下名字即可,效果如下:
    这里写图片描述

2.光标的使用

光标是表示当前鼠标的形状,从本质上来说也是一个图像,作为资源Cursor,其使用方法和和Icon的使用类似。在注册窗口类时,同样有这一句:wcex.hCursor = LoadCursor(NULL, IDC_ARROW);也就是说我们可以在这儿修改,系统预定义的光标类型有箭头,十字形,手型,沙漏型等等比如改为手型,就将IDC_ARROW改为IDC_HAND。

  1. 当使用系统光表时,LoadCursor的第一个参数需要设置为NULL。这种改变只在客户窗口区有效,如果要在整个框架内都有效,需要在创建消息WM_CREATE中设置。
    这里写图片描述
  2. 当然也可以自己绘制一个光标,如下是我绘制的一个光标:
    这里写图片描述
    绘制完成后,将原来的IDC_ARROW修改为IDC_CURSOR1,注意还要将LoadCursor的第一个参数改为当前的实例,即hInstance,否则LoadCursor会加载失败。加载成功后的例子:
    这里写图片描述
  3. 同样自己绘制的效果有限,可以导入别人绘制好的光标,不要将一个位图强行改为.cur格式,去网上下吧,有很多好看的。例如我导入一个如下:
    这里写图片描述
    然后直接替换第二个参数就可以了这里写图片描述

3.位图的使用

位图是一种数字化的图形表示,是表示一个图像目标的具体数据。前面的Icon、Cursor本质上都是 图像,只是文件的存储格式不同。

  1. 使用位图要定义位图,位图通常是用户自定义的资源,因为系统很难确定用户经常使用的位图资源,它不想光标和图标有大家默认的、熟悉的预定义的图像。同样你可以利用资源编辑器绘制位图,或者加载位图,一般加载位图用的较多,加载位图的函数是
HBITMAP LoadBitmap(HINSTANCE hInstance,LPCTSTR lpBitmaoName);

参数hInstance为包含该位图的应用程序实例句柄,lpBitmapName是资源文件中的位图名字。

  1. 注意:位图是一种资源,使用时一定要先加载位图;通常在用户区显示位图,这是一种输出操作,需符合windows应用输出的过程步骤;位图是一种GDI绘图工具对象,必须将该工具选进DC中才能使用,因此位图和Icon,Curson有差别。
    3.图像所包含的数据量比较大,所以为了提高刷新速度,位图操作通常必须先在内存中进行,这就是通常说的先画内存,再画图像。因此,用于位图操作的的系统设备描述表通常称为内存设备描素表。先画内存,再画屏幕,即位图最后还是要在某个输出设备上显示,,例如,在屏幕上,那就意味着,这个内存和后面的输出设备是有关系的,故而获取内存设备描述表调用的是CreateCompatibleDC函数,他的原型如下:`HDC CreateCompatibleDC(HDC hDC);参数hDc指定一个已经存在的DC, 通常就是位图最终要现在在哪个设备的DC,NULL表示已经存在的设备就是当前应用窗口的屏幕,函数表示创建一个与hDc所指定的设备描述表相兼容的的内存设备描述表。函数创建成功,返回的是内存设备描述表,失败则返回NULL。

  2. 显示位图可以调用函数bitblt或StretchBlt,前者按照原图大小进行显示,后者可以对图像进行缩放。
    其中StretchBlt函数的原型如下:

BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORD dwRop);

hdcDest:指向目标设备环境的句柄。
hdcSrc:指向源设备环境的句柄。
nXOriginDest:指定目标矩形左上角的X轴坐标,按逻辑单位表示坐标。
nYOriginDest:指定目标矩形左上角的Y轴坐标,按逻辑单位表示坐标。
nWidthDest:指定目标矩形的宽度,按逻辑单位表示宽度。
nHeightDest:指定目标矩形的高度,按逻辑单位表示高度。
nXOriginSrc:指向源矩形区域左上角的X轴坐标,按逻辑单位表示坐标。
nYOriginSrc:指向源矩形区域左上角的Y轴坐标,按逻辑单位表示坐标。
nWidthSrc:指定源矩形的宽度,按逻辑单位表示宽度。
nHeightSrc:指定源矩形的高度,按逻辑单位表示高度。
dwRop:指定要进行的光栅操作。光栅操作码定义了系统如何在输出操作中组合颜色,这些操作包括刷子、源位图和目标位图等对象。

  1. 下面是具体的代码:
    先导入一张位图:取名为map.bmp
    然后我们在WM_PAINT消息里面实现显示。

“`
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
HICON hIcon;
//先声明几个全局变量
HDC hMemdc;
BITMAP bitmap;
HBITMAP hbitmap;
switch (message)
{
case WM_COMMAND:
……
……
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hMemdc=CreateCompatibleDC(hdc);//创建兼容的内存DC
hbitmap=LoadBitmap(hInst,(LPCTSTR)IDB_BITMAP2);//加载位图资源
SelectObject(hMemdc,hbitmap);//将位图选进内存DC。
GetObject(hbitmap,sizeof(BITMAP),&bitmap);//获取位图信息
StretchBlt(hdc,20,20,200,200,hMemdc,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);//显示
DeleteDC(hMemdc);

    // TODO: 在此添加任意绘图代码...
    EndPaint(hWnd, &ps);
    break;

效果如下:
这里写图片描述
我们将其放大试试,不仅改变了大小,还改变了长宽比,可以看到边缘出现了锯齿。
这里写图片描述
同样你还可以改变参数实现裁剪
这里写图片描述
BitBlt函数与此类似,就不再赘述。


String资源

String资源使用很简单,在StringTable中定义一个字符串,使用LoadString加载到全局内存中,即可使用。
这里写图片描述
在以下几处地方涉及代码:

  1. // 全局变量:
    HINSTANCE hInst; // 当前实例
    TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
    TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
    TCHAR buff[100];
  2. // 初始化全局字符串
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_SOURCE, szWindowClass, MAX_LOADSTRING);
    LoadString(hInstance, IDS_STRING104, buff, MAX_LOADSTRING);
  3. hWnd = CreateWindow(szWindowClass, buff, WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    我们完全可以参照系统自动生成的字符串来实现,通过上面几步,标题变为:
    这里写图片描述

未完待续。。。。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值