WindowsAPI学习笔记五 - 资源在Windows编程中的应用

WindowsAPI学习笔记五 - 资源在Windows编程中的应用

windows 应用程序中有几种不同类型的资源,如加速键,位图,光标,对话框,菜单,工具条和字符串等。在最初的 API 编程阶段,程序员可以用文本编辑器来编写资源脚本,这种方式比较灵活,但代码量很大。

Winodws 的可执行文件中,资源是独立于代码的,使用单独的 Resource Compiler 来编译,并嵌入到可执行文件中。在编程过程中,代码是可重用的,资源文件也可重用的,通过资源的“导入”和“导出”功能来实现资源的可复用。此外,程序的国际化也是通过资源来实现的。

术语“资源文件”可以指若干文件类型,包括:

·                 程序的资源脚本 (.rc) 文件。

·                 资源模板 (.rct) 文件。

·                 作为独立文件存在的个别资源,如从 .rc 文件引用的位图、图标或光标文件。

·                 由开发环境生成的头文件(如 Resource.h),它从 .rc 文件中引用。

其他类型的文件(如 .exe .dll .res 文件)中也可以作为资源。

 

资源的操作一般过程为:资源的创建,在资源文件中定义,资源的加载等。

不同类型的资源定义方式不太相同,一般都是使用一种“描述”类的语言来说明该资源的各种属性。资源通过 ID 号来进行标识, ID 是资源名,用以标识特定和资源,应用程序也是通过 ID 来加载指定的资源。一般使用一个 1~65535 之间的整数来表示。

 

Ÿ           图标资源

一个图标就是代表一个应用程序的特殊最小位图。在图标上双击鼠标就可以执行该应用程序。

1.         图标的创建
用户可以使用系统提供的默认图标也可以自定义扩展名为 ico 的文件。
系统提供的一些图标标识为:
IDI_APPLICATION     
默认图标
IDI_QUESTION          
问号图标
IDI_EXCLAMATION   
惊叹号图标

2.         在资源文件中定义图标
其形式如下:        图标名     ICON      图标文件名( .ico

3.         加载图标
在应用程序中通过 LoadIcon 函数加载图标 , 此过程常在定义窗口类时进行 , 如:

wndClass.hIcon = LoadIcon(hInst, lpszIconName);

 

Ÿ           位图资源

对于绘画或照片一类位图数据量一般都较大,因此为了提高显示刷新速度,位图操作必须在内存中进行。因此程序首先要通过 CreateCompatibleDC 向系统申请内在设备环境。

与其它资源的加载类似,位图也可以使用 LoadBitmap 函数来加载,并使用 BitBlt 函数来进行输出。

BOOL BitBlt

(

       HDC hdcDest,                            // 目地设备环境

       int nXDest, int nYDest,         // 目地设备显示位图的基点

       int nWidth, int nHeight,         // 显示区域的高宽

       HDC hdcSrc,                       // 源设备环境

       int nXSrc, int nYSrc,            // 源设备中位图的左上角坐标

       DWORD dwRop                  // 位图的显示方式

)

      

Ÿ           菜单

1.         定义菜单

定义形式为:

ID MENU [ 载入特性选项 ]

{

       菜单项列表

}

其中菜单项列表用于说明菜单的各个组成部分。

2.         加载菜单

一般的 Windows 程序中加载菜单有三种方法:

(1)      在窗口类中加载

(2)      在创建窗口时加载        CreateWindow 函数)

(3)      动态加载

获得菜单句柄后通过 SetMenu 动态地加载菜单,以提高程序灵活性。

3.         菜单项操作

(1)      禁止或激活菜单项

(2)      设置或取消选中标志

(3)      增加菜单项

(4)      删除菜单项

(5)      修改菜单项

菜单项里方法较,不一一罗列出来,需要可以参见 MSDN

 

Ÿ           加速键

加速键是经常与菜单一同使用的资源,通过加速键可以使程序使用起来更加方便快捷。

1.         资源定义

加速键格式为:

加速键名 ACCELERATORS ID [ 类型 ] [NOINVERT] [ALT] [SHIFT] [CONTROL]

后面的一些可选项表示加速键的组合方式。

2.         加载

通过 LoadAccelerators 即可加载定义好的加速键

3.         翻译加速键

想要加速键产生效果还必须响应加速键按下后产生的消息,翻译加速键的工作一般在应用程序的消息循环中进行。

TranslateAccelerator 函数是翻译过程的核心,它对照加速键表将 WM_KEYDOWN WM_KEYUP 翻译成 WM_COMMAND WM_SYSCOMMAND 消息。

 

Ÿ              应用示例
 这次使用资源脚本(rc文件)和resource.h头文件来描述程序里的资源,头文件内容如下:

// 菜单
#define  IDM_OPEN 1000
#define  IDM_CLOSE 1001
#define  IDM_EXIT 1002
#define  IDM_ABOUT 1003
#define  IDM_PIC1 1004
#define  IDM_PIC2 1005
         在这里定义了六个菜单的ID,其实直接在描述文件里使用数字也可以,不过失去了字面意义,不方便编写复杂程序。
         资源脚本其实是一个可以用文本编辑器打开的文本文件,不过为了方便一般都使用VS提供的可视化工具。这里为了了解资源定义
         加载的原理,使用了手工编写的方式。
#include  " resource.h "

VSICON ICON res\vs.ico

PIC1 BITMAP res\pic1.bmp
PIC2 BITMAP res\pic2.bmp

MENUOPEN MENU MOVEABLE
BEGIN
    POPUP 
" 文件(&F) "
    BEGIN
        MENUITEM 
" 打开(&O) " , IDM_OPEN  // 虽可以直接定义数字ID,但由于数字没有字面意义
        MENUITEM  " 关闭(&C) " , IDM_CLOSE  // 故一般不使用这种方式,而使用define方式
        MENUITEM SEPARATOR       
        MENUITEM  " 退出(&X) " , IDM_EXIT
    END
    POPUP 
" 关于(&A) "
    BEGIN
        MENUITEM 
" 关于程序 " , IDM_ABOUT
    END
END


MENUPIC MENU MOVEABLE
BEGIN
    POPUP 
" 位图 "
    BEGIN
        MENUITEM 
" 位图一 " , IDM_PIC1
        MENUITEM 
" 位图二 " , IDM_PIC2
    END
END
         这里的资源文件包括:一个程序图标(ico文件),两张位图文件(pic1.bmp和pic2.bmp)全部放于程序目录的res文件夹内。其它
         部分是定义了一系列的菜单资源。
         在这次的程序里。程序把一个图标资源加载为最后生成程序的图标(不用再使用原来那种恶心的默认图标了),程序加载了一个文件
         菜单,里面有“打开”和“关闭”两项。打开按下后,动态产生一个新的菜单组,按下里面的菜单项选择在用户区显示两个位图。
// 首先需要在InitWindowClass方法里改变这两行内容
wndClass.hIcon  =  LoadIcon(NULL,  " VSICON " ); // 加载一个程序图标vs.ico

wndClass.lpszMenuName 
=   " MENUOPEN " ; // 加载程序菜单

// 然后是全局定义变量
HDC hdc, hdcMem;
HBITMAP hBmp;
BITMAP bmp;
HMENU hmenu, haddMenu;
HINSTANCE hCurInst;
// 当前应用程序句柄

// 最后程序的消息处理函数作为结束
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg,
                         UINT wParam,
                         LONG lParam)
{
    PAINTSTRUCT ps;
    
switch(iMsg)
    
{
        
case WM_CREATE://获取设备环境
            hdc = GetDC(hWnd);
            hdcMem 
= CreateCompatibleDC(hdc);
            
break;

        
case WM_COMMAND://处理菜单消息
            switch (LOWORD(wParam))
            
{
                
case IDM_OPEN://处理打开菜单按下的消息
                    hmenu = GetMenu(hWnd);//获取主菜单句柄
                    haddMenu = CreateMenu();//创建动态菜单
                    
//动态增加菜单中项
                    AppendMenu(haddMenu, MF_ENABLED, IDM_PIC1, "位图一");
                    AppendMenu(haddMenu, MF_ENABLED, IDM_PIC2, 
"位图二");
                    
//将创建的菜单插入到主菜单中
                    InsertMenu(hmenu, 1, MF_POPUP|MF_BYPOSITION
                                                , (UINT)haddMenu, 
"打开图片");
                    
//相应改变“文件”菜单中相关菜单项属性
                    EnableMenuItem(hmenu, IDM_OPEN, MF_GRAYED);//打开菜单变灰不可用
                    EnableMenuItem(hmenu, IDM_CLOSE, MF_ENABLED);//关闭菜单变可用
                    DrawMenuBar(hWnd);//重新显示窗口菜单
                    break;

                
case IDM_CLOSE://关闭菜单消息
                    DeleteMenu(hmenu, 1, MF_BYPOSITION);//删除加入的菜单项
                    
//相应改变“文件”菜单中相关菜单项属性
                    EnableMenuItem(hmenu, IDM_OPEN, MF_ENABLED);//打开变可用
                    EnableMenuItem(hmenu, IDM_CLOSE, MF_GRAYED);//关闭变不可用
                    DrawMenuBar(hWnd);
                    
break;
                 
                
case IDM_PIC1://在用户区加入一个位图并进行显示
                    SelectObject(hdc, (HPEN)GetStockObject(WHITE_PEN));
                    Rectangle(hdc, 
0,010001000);
                    hBmp 
= LoadBitmap(hCurInst, "PIC1");
                    GetObject(hBmp, 
sizeof(BITMAP), (LPVOID)&bmp);//获取位图尺寸
                    SelectObject(hdcMem, hBmp);
                    BitBlt(GetDC(hWnd), 
00, bmp.bmWidth, bmp.bmHeight, hdcMem, 00, SRCCOPY);
                    EnableMenuItem(hmenu, IDM_PIC1, MF_GRAYED);
//位图二变不可用
                    EnableMenuItem(hmenu, IDM_PIC2, MF_ENABLED);
                    
break;
                
case IDM_PIC2://显示图片二
                    SelectObject(hdc, (HPEN)GetStockObject(WHITE_PEN));
                    Rectangle(hdc, 
0,010001000);
                    hBmp 
= LoadBitmap(hCurInst, "PIC2");
                    GetObject(hBmp, 
sizeof(BITMAP), (LPVOID)&bmp);//获取位图尺寸
                    SelectObject(hdcMem, hBmp);
                    BitBlt(GetDC(hWnd), 
00, bmp.bmWidth, bmp.bmHeight, hdcMem, 00, SRCCOPY);
                    EnableMenuItem(hmenu, IDM_PIC2, MF_GRAYED);
//位图一变不可用
                    EnableMenuItem(hmenu, IDM_PIC1, MF_ENABLED);
                    
break;
                
case IDM_EXIT://退出被按下,发送一个WM_DESTROY消息退出程序
                    SendMessage(hWnd, WM_DESTROY, 00);
                    
break;
                
default:
                    
break;
            }

            
break;

        
case WM_DESTROY://在窗口退出后释放所有资源
            DeleteObject(hBmp);
            ReleaseDC(hWnd, hdc);
            DeleteDC(hdcMem);
            PostQuitMessage(
0);
            
return 0;
        
default:
            
return (DefWindowProc(hWnd, iMsg, wParam, lParam));
    }

    
return 0;
}

你可能感兴趣的:(WindowsAPI学习笔记五 - 资源在Windows编程中的应用)