这篇博文将会简单介绍下菜单、图标与光标在Windows窗口程序中如何使用。
一、菜单、图标、光标都是作为资源在资源文件中定义的。
1、菜单的定义方法:
菜单ID MENU [DISCARDABLE]
BEGIN
菜单项定义
END
菜单项定义:
定义普通菜单项:
MENUITEM 菜单文字 ,命令ID [,选项列表]
定义分割线:
MENUITEM SEPARATOR
定义弹出式菜单:
POPUP 菜单文字 [,选项列表]
BEGIN
菜单项定义
END
2、图标与光标的定义
图标ID ICON [DISCARDABLE] 图标文件名
光标ID CURSOR [DISCARDABLE] 光标文件名
3、注意
所谓的XXID都是用户自定义的一些数值,范围是0~0FFFFH
DISCARDABLE是内存选项,表示在不用时可以自动释放内存
4、例子
#include <resource.h> //菜单选项 #define IDM_MAIN 0x1000 #define IDM_ICOHEAD 0x2000 #define IDM_ICOARROW 0x2001 #define IDM_CURDINOSAUR 0x2002 #define IDM_CURHAND 0x2003 //图标 #define ICON_HEAD 0x3000 #define ICON_ARROW 0x3001 //光标 #define CUR_HAND 0x4000 ICON_ARROW icon discardable "Arrow.ico" ICON_HEAD icon discardable "Head.ico" CUR_HAND cursor discardable "Hand.cur" IDM_MAIN menu discardable BEGIN popup "图标与光标选项(&C)..." BEGIN menuitem "头像图标", IDM_ICOHEAD menuitem "箭头图标", IDM_ICOARROW menuitem separator menuitem "恐龙光标", IDM_CURDINOSAUR menuitem "手掌光标", IDM_CURHAND END END
二、在主窗口程序中使用菜单、图标、光标资源
1、如何建立窗口:第二篇 第一个窗口程序
2、使用方法
①使用菜单
首先,在获得模块句柄后将菜单(由菜单ID—IDM_MAIN指定)加载进应用程序
invoke GetModuleHandle,NULL mov hInstance,eax invoke LoadMenu,hInstance,IDM_MAIN mov hMenu,eax
其次,在建立窗口时将菜单句柄hMenu作为参数传递进去
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\ offset szClassName,offset szClassName,\ WS_OVERLAPPEDWINDOW,\ 200,200,300,200,\ NULL,hMenu,hInstance,NULL
②使用光标与图标的方法
在调用CreateWindowEx建立窗口时,在函数返回前系统会向窗口程序发出WM_CREATE消息。我们可以
此时加载光标与图标资源。然后紧接着调用SendMessage函数将缺省建立的图标与光标类型发送给窗口程
序处理。
.if eax == WM_CREATE invoke LoadIcon,hInstance,ICON_HEAD mov hIconHead,eax invoke LoadIcon,hInstance,ICON_ARROW mov hIconArrow,eax invoke LoadCursor,hInstance,CUR_HAND mov hCurHand,eax invoke LoadCursorFromFile,addr szCursorFile mov hCurDinosaur,eax invoke SendMessage,hWnd,WM_COMMAND,IDM_ICOHEAD,NULL invoke SendMessage,hWnd,WM_COMMAND,IDM_CURHAND,NULL
3、例子
.386 .model flat,stdcall option casemap:none include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib ;下面的equ定义千万不要写成0x... ;菜单ID的定义 IDM_MAIN equ 1000h IDM_ICOHEAD equ 2000h IDM_ICOARROW equ 2001h IDM_CURDINOSAUR equ 2002h IDM_CURHAND equ 2003h ;图标ID的定义 ICON_HEAD equ 3000h ICON_ARROW equ 3001h ;静态光标文件的定义 CUR_HAND equ 4000h ;句柄定义 .data? hInstance dd ? hMenu dd ? hWinMain dd ? hCurDinosaur dd ? hCurHand dd ? hIconHead dd ? hIconArrow dd ? .const szCursorFile db 'Dinosaur.ani',0 ;存储于磁盘上的动态光标文件 szClassName db 'Icon and Cursor!',0 .code _Quit proc invoke DestroyWindow,hWinMain invoke PostQuitMessage,NULL ret _Quit endp _WinMainProc proc uses ebx edi esi hWnd,uMsg,wParam,lParam mov eax,uMsg .if eax == WM_CREATE invoke LoadIcon,hInstance,ICON_HEAD mov hIconHead,eax invoke LoadIcon,hInstance,ICON_ARROW mov hIconArrow,eax invoke LoadCursor,hInstance,CUR_HAND mov hCurHand,eax invoke LoadCursorFromFile,addr szCursorFile mov hCurDinosaur,eax invoke SendMessage,hWnd,WM_COMMAND,IDM_ICOHEAD,NULL invoke SendMessage,hWnd,WM_COMMAND,IDM_CURHAND,NULL .elseif eax == WM_COMMAND mov eax,wParam movzx eax,ax .if eax == IDM_ICOHEAD ;ICON_BIG是WM_SETICON中预定义的 invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,hIconHead invoke CheckMenuRadioItem,hMenu,IDM_ICOHEAD,IDM_ICOARROW,\ IDM_ICOHEAD,MF_BYCOMMAND .elseif eax == IDM_ICOARROW ;ICON_SMALL是WM_SETICON中预定义的 invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL,hIconArrow invoke CheckMenuRadioItem,hMenu,IDM_ICOHEAD,IDM_ICOARROW,\ IDM_ICOARROW,MF_BYCOMMAND .elseif eax == IDM_CURDINOSAUR invoke SetClassLong,hWnd,GCL_HCURSOR,hCurDinosaur invoke CheckMenuRadioItem,hMenu,IDM_CURDINOSAUR,IDM_CURHAND,\ IDM_CURDINOSAUR,MF_BYCOMMAND .elseif eax == IDM_CURHAND invoke SetClassLong,hWnd,GCL_HCURSOR,hCurHand invoke CheckMenuRadioItem,hMenu,IDM_CURDINOSAUR,IDM_CURHAND,\ IDM_CURHAND,MF_BYCOMMAND .endif .elseif eax == WM_CLOSE invoke _Quit .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif mov eax,0 ret _WinMainProc endp _WinMain proc local @stWndClass:WNDCLASSEX local @stMsg:MSG invoke GetModuleHandle,NULL mov hInstance,eax invoke LoadMenu,hInstance,IDM_MAIN mov hMenu,eax invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass push hInstance pop @stWndClass.hInstance mov @stWndClass.cbSize,sizeof @stWndClass mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW mov @stWndClass.lpfnWndProc,offset _WinMainProc mov @stWndClass.hbrBackground,COLOR_WINDOW + 1 mov @stWndClass.lpszClassName,offset szClassName invoke RegisterClassEx,addr @stWndClass invoke CreateWindowEx,WS_EX_CLIENTEDGE,\ offset szClassName,offset szClassName,\ WS_OVERLAPPEDWINDOW,\ 200,200,300,200,\ NULL,hMenu,hInstance,NULL mov hWinMain,eax invoke ShowWindow,hWinMain,SW_SHOWNORMAL invoke UpdateWindow,hWinMain .while TRUE invoke GetMessage,addr @stMsg,NULL,0,0 .break .if eax == 0 invoke TranslateMessage,addr @stMsg invoke DispatchMessage,addr @stMsg .endw ret _WinMain endp start: invoke _WinMain invoke ExitProcess,NULL end start
三、代码中图标与光标文件下载
图标与光标文件
四、关于本篇博文的例子
程序运行起来后,选择菜单中的项目可以看到图标与光标的改变。