最近在学习罗云彬大侠的win32汇编教程,顺便把windows的api和消息机制也好好学习了下。在学习"图标和光标"一节时遇到了一些问题,这里将主要实验步骤和结果列出,供后来者参考。
一、实验前的准备
1、代码文件icon.cpp的内容:
#include <windows.h> LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch(uMsg) { case WM_CLOSE: DestroyWindow(hWnd); PostQuitMessage(0); break; default: return DefWindowProc(hWnd,uMsg,wParam,lParam); } return 0;} int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR szCmdLine , int iCmdShow ) { HWND hWinMain; WNDCLASSEX stWndClass={0}; MSG stMsg={0}; char szClassName[]="IconTest"; stWndClass.hCursor=LoadCursor(0,IDC_ARROW); stWndClass.hInstance = hInstance; stWndClass.cbSize = sizeof(WNDCLASSEX); stWndClass.style = CS_HREDRAW |CS_VREDRAW; stWndClass.lpfnWndProc = WndProc; stWndClass.hbrBackground =(HBRUSH) (COLOR_WINDOW+1); stWndClass.lpszClassName = szClassName; RegisterClassEx(&stWndClass); hWinMain = CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szClassName ,WS_OVERLAPPEDWINDOW,100,100,600,400,0,0,hInstance,0); ShowWindow(hWinMain,SW_SHOWNORMAL); UpdateWindow(hWinMain); while(GetMessage(&stMsg,0,0,0)) { TranslateMessage(&stMsg); DispatchMessage(&stMsg); } ExitProcess(0); return 0;}
2、准备两个图标文件 big.ico和small.ico,前者为256*256,后者为16*16,读者可以从罗云彬教材中的附带光盘中找到这两个素材文件 。
二、实验步骤
1、在vc6中新建一个空白的win32程序IconTest1,然后将main.cpp加入到项目中,进行编译。此时观察程序各图标的运行结果是
(1)程序标题栏左部的图标为vc自带的默认小图标。如图1画圈处所示。
(2)任务栏中程序名左部的图标也是vc自带的默认小图标。如图2画圈处所示。
(3)在资源管理器中看到的程序名左部图标也是vc自带的默认小图标。如图3画圈处所示。
(4)在按alt+tab出现的程序管理器中看到的程序图标是vc自带的默认大图标。
(在xp下按alt+tab之后出现的图我没法截,如果有知道的大侠请告诉我^O^)
2、建立icontest2.在项目中加入一个rc文件,内容为
#define ICO_SMALL 0x1001
ICO_SMALL ICON "Small.ico"
,实验结果为
(1)程序标题栏左部的图标仍然为vc自带的默认小图标。
(2)任务栏中程序名左部的图标为刚才加入的small.ico文件,如下图所示
(3)资源管理器中的图标为刚才加入的small.ico,如下图所示
(4) 程序管理器的图标为vc默认的大图标
3、在rc中再加入两句
#define ICO_BIG 0x1000
ICO_BIG ICON "Big.ico"
结果为
(1) 程序标题栏左部的图标仍然为vc自带的默认小图标。
(2)任务栏中的图标为small.ico
(3)资源管理器的图标为big.ico,如下图所示
(4)程序管理器中的图标为vc自带
4、新建test3,将main.cpp中加入到项目中,代码中加入一句
stWndClass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(ICO_SMALL));
rc文件内容为:
ICO_SMALL ICON "Small.ico"
此时,四个图标均为small.ico
5、将4中的代码改为
stWndClass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(ICO_BIG));
rc文件内容不变,则此时的结果相当有趣
(1)标题栏左部的图标为vc自带
(2)任务栏中的图标为small.ico
(3)资源管理器中的图标为small.ico
(4)程序管理器中的图标为vc自带
6、将4中的代码改为
stWndClass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(ICO_BIG));
stWndClass.hIconSm= LoadIcon(hInstance,MAKEINTRESOURCE(ICO_SMALL));
rc文件内容为
ICO_BIG ICON "Big.ico"
ICO_SMALL ICON "Small.ico"
结果为
(1)标题栏和任务栏的图标为small.ico
(2)资源管理器的图标为big.ico
(3)程序管理器中的图标为big.ico
7、建立test4,代码为原始代码,rc文件为
ICO_BIG ICON "Big.ico"
ICO_SMALL ICON "Small.ico"
此时,标题栏和程序管理器的图标为vc自带
任务栏和资源管理器为big.ico。
8、将test4的WndProc代码中加入
case WM_CREATE:
SetClassLong(hWnd,GCL_HICON,(LONG)hSmall);
break;
则运行后标题栏、任务栏和程序管理器中的图标均为small.ico,
而资源管理器中的图标为big.ico。
小结:api编程中的小图标指的是标题栏和任务栏上的程序图标,一般为16*16像素的ico文件
大图标为资源管理器和程序管理器中出现的图标,一般为256*256像素
setclasslong更改的是程序运行时的相关图标,对资源管理器上的静态图标没有影响。
题外话:
今天在星羽的帮助下,终于把WM_SETICON这个消息的使用要点搞明白了。
根据http://msdn.microsoft.com/en-us/library/windows/desktop/ms632643%28v=vs.85%29.aspx里的描述
发送WM_SETICON消息的常见写法是
SendMessage(hWnd,WM_SETICON,ICON_BIG,(LPARAM)(hIconBig));
这里注意第3个参数必须是系统预定义的两个常数ICON_BIG和ICON_SMALL之一。在我的机器上,这两个常数在
vs6安装目录\vc98\include\winuser.h文件中。
根据msdn的描述,这两个常数的意思是
如果参数为ICON_BIG,则修改的是程序管理器中的图标(也就是按alt+tab之后出现的东西);
如果参数为ICON_SMALL,则修改的是程序标题栏左侧的图标;
第4个参数则为图标文件的句柄。