WIN32汇编语言教程:第05章 使用资源 · 5.2 图标和光标(1)

图标和光标是图形资源,图标通常用做应用程序的“形象代表”出现在文件浏览器、运行窗口左上角或程序的快捷方式等所有代表文件的地方,为自己写的应用程序选一个合适的图标会使程序变得引人注目;而光标就是鼠标移动时屏幕上那个指示位置的东西,应用程序可以定义自己的光标,这样光标移到程序的客户区中就会变成需要的形状。

5.2.1 图标和光标的资源定义

和菜单、加速键等资源不同,在资源脚本文件中定义图标和光标时并不是一个个像素地定义,而是指定图标和光标的文件名,由资源编译器将像素数据读入再转换成二进制格式,所以在资源定义之前要用其他工具先创建图标和光标文件。图标和静态光标文件的扩展名分别是ico和cur,还有一种扩展名为ani的动态光标文件。

光标和图标在资源文件中的定义语句是:

图标ID ICON [DISCARDABLE] 图标文件名            ;定义图标

光标ID CURSOR [DISCARDABLE] 光标文件名         ;定义光标

DISCARDABLE关键字是内存选项,表示在不用的时候可以从内存暂时卸掉,当文件名包含空格时,两边要用双引号引起来,图标ID和光标ID同样也可以用16位的整数或字符串表示,这里是几个定义的例子:

MyIcon icon “1.ico”         ;把1.ico定义为ID为“MyIcon”的图标资源
1000 icon discardable 2.ico ;把2.ico定义为ID为1000的图标资源
1001 icon “big icon.ico”    ;把big icon.ico定义为ID为1001的图标资源
1002 cursor “big arrow.ani” ;把big arrow.ani定义为ID为1002的光标资源
GoodCursor cursor arrow.cur ;把arrow.cur定义为ID为“GoodCursor”的光标资源

资源文件中定义的图标可以不止一个,但Windows在“我的电脑”中列出文件的时候总是使用资源中的第一个图标当做文件的图标,所以在资源脚本文件中要把想用做程序图标的图标定义语句排在最前面。

5.2.2 使用图标和光标

在这里,用一个例子来说明图标和光标的用法,程序是建立在FirstWindow.asm和Menu.asm程序的基础上的,为了节省篇幅,在这里就不列出全部源程序了,完整的源程序可以在所附光盘的Chapter05\Icon目录中找到。程序中创建了一个菜单,运行后可以在“图标和光标”菜单中选择不同的图标和光标,选择不同的图标以后,窗口标题栏左边的图标和桌面任务栏上的窗口图标都会变化;选择不同的光标后,当鼠标移动到窗口客户区中的时候,光标会变成程序指定的光标。具体的效果如图5.3所示,大图标对应“笑脸”,小图标对应“箭头”,而光标A和B分别是“小恐龙”光标和“手型”光标,其中“小恐龙”光标是ani类型的动态光标,在屏幕上显示为一个走动中的恐龙模样。


图5.3 不同的图标和光标

资源文件Icon.rc的定义如下:

//##################################################################
#include         <resource.h>
//##################################################################
#define  ICO_BIG           Ox1000
#define  ICO_SMALL         Ox1001
#define  CUR_2             Ox1000
#define  IDM_MAIN               Ox2000
#define  IDM_EXIT               Ox2101
#define  IDM_BIG           Ox2201
#define  IDM_SMALL         Ox2202
#define  IDM_CUR1              Ox2203
#define  IDM_CUR2              Ox2204
//##################################################################
ICO_SMALL         ICON      "Small.ico"
ICO_BIG          ICON      "Big.ico"
CUR_2            CURSOR    "2.cur"
//##################################################################
IDM_MAIN menu    discardable
BEGIN
         popup   "文件(&F)"
         BEGIN
                  menuitem  "退出(&X)",    IDM_EXIT
         END
         popup   "图标和光标(&I)"
         BEGIN
                  menuitem  "大图标(&G)",  IDM_BIG
                  menuitem  "小图标(&M)",  IDM_SMALL
                  menuitem  separator
                  menuitem  "光标A(&A)",  IDM_CUR1
                  menuitem  "光标B(&B)",  IDM_CUR2
         END
END
//##################################################################

经过上一节的“洗礼”,读者对菜单的定义应该很熟悉了,这里就不再说明IDM_MAIN的定义了,脚本文件中定义了ICO_SMALL,ICO_BIG两套图标和CUR_2静态光标,磁盘上还有个动态光标文件1.ani。

Icon.asm的大部分是窗口模板程序的内容,和FirstWindow.asm是相同的,仅在窗口过程的WM_CREATE和WM_COMMAND增加了一些内容:

                      .const
szCursorFile db     '1.ani',0
                      .code
                      ...
             .if    eax == WM_CREATE
                     invoke LoadIcon,hInstance,ICO_BIG
                     mov    hIcoBig,eax
                     invoke LoadIcon,hInstance,ICO_SMALL
                     mov    hIcoSmall,eax
                      invoke LoadCursorFromFile,addr szCursorFile
                      mov    hCur1,eax
                   invoke LoadCursor,hInstance,CUR_2
                     mov    hCur2,eax
                     invoke SendMessage,hWnd,WM_COMMAND,IDM_BIG,NULL
                   invoke SendMessage,hWnd,WM_COMMAND,IDM_CUR1,NULL
            .elseif eax == WM_COMMAND
                     mov    eax,wParam
                   movzx  eax,ax
                     .if    eax ==   IDM_EXIT
                            call _Quit
                   .elseif eax ==   IDM_BIG
                            invoke   SendMessage,hWnd,WM_SETICON,ICON_BIG,hIcoBig
                           invoke   CheckMenuRadioItem,hMenu,\
                              IDM_BIG,IDM_SMALL,IDM_BIG,MF_BYCOMMAND
                    .elseif eax ==   IDM_SMALL
                            invoke   SendMessage,hWnd,\
                             WM_SETICON,ICON_BIG,hIcoSmall
                          invoke   CheckMenuRadioItem,hMenu,\
                              IDM_BIG,IDM_SMALL,IDM_SMALL,MF_BYCOMMAND
                    .elseif eax ==   IDM_CUR1
                            invoke   SetClassLong,hWnd,GCL_HCURSOR,hCur1
                            invoke   CheckMenuRadioItem,hMenu,\
                           IDM_CUR1,IDM_CUR2,IDM_CUR1,MF_BYCOMMAND
                   .elseif eax ==   IDM_CUR2
                            invoke   SetClassLong,hWnd,GCL_HCURSOR,hCur2
                            invoke   CheckMenuRadioItem,hMenu,\
                               IDM_CUR1,IDM_CUR2,IDM_CUR2,MF_BYCOMMAND
                      .endif

上页:第05章 使用资源 · 5.1 菜单和加速键(7) 下页:第05章 使用资源 · 5.2 图标和光标(2)

第05章 使用资源

版权所有 © 云南伯恩科技 证书:粤ICP备09170368号