作者:Mitu_-_
本帖内容著作权归作者所有,转载请务必保留本文链接
今天在用SendMessage函数给WM_SETICON发送消息改变图标时发现:
1.如果刚开始设置了wParam参数为ICON_BIG(即设置大图标类型) 的话,WM_SETICON会将窗口标题栏、任务栏、Alt+Tab的图标都设为由SendMessage传来的lParam参数所指向的图标。

2.而进行第二次变换图标时,将wParam参数设为ICON_SMALL(即小图标类型)时,会发现只有窗口标题栏的图标变成想要的图标,
而任务栏、Alt+Tab的图标却没有发生改变

3.之后无论再点小图标还是大图标,图标都不会再变化了

这是SendMessage句法:
LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
这里放入部分代码:
*这是在创建窗口时载入图标并获得图标的句柄
.if eax == WM_CREATE
invoke LoadIcon, hInstance, ICO_BIG
mov hIcoBig, eax
invoke LoadIcon, hInstance, ICO_SMALL
mov hIcoSmall, eax
*这里通过WM_COMMAND消息来处理图标
invoke SendMessage, hWnd, WM_COMMAND, IDM_BIG, NULL
.elseif eax == WM_COMMAND
mov eax, wParam
movzx eax, ax ;如果加速键唤醒,就把高16位置零
.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_SMALL, hIcoSmall
invoke CheckMenuRadioItem, hMenu, IDM_BIG, IDM_SMALL, IDM_SMALL,MF_BYCOMMAND
我也纳闷过一阵子,不过再仔细一思考就发现其中的原因了:

上面这句话的意思是:将新的大图标或小图标与窗口关联。系统在ALT + TAB对话框中显示大图标,在窗口标题中显示小图标。
而WM_SetIcon接收的参数为wParam:

*上面的意思是:
ICON_BIG 设置窗口的大图标(即Alt+Tab图标)
ICON_SMALL 设置窗口的小图标(即窗口标题栏图标)
那么,如果按我的理解,发生如上所示问题的原因就是:
1.最初设置为大图标时会默认将大图标应用到窗口标题栏、任务栏和Alt+Tab中去;
(但是窗口标题栏没有被真正的覆盖,只是默认使用ICON_BIG设置的图标)
2.再设置小图标时,则由ICON_SAMLL设置窗口图标,仅会设置窗口标题栏的图标,其他还是大图标样式;
(这时窗口标题栏才被ICON_SMALL设置的图标真正地覆盖了)
3.接下来再点击大图标时,由ICON_BIG设置图标,仅会把Alt+Tab和任务栏的图标变换,而窗口标题栏仍是只能由ICON_SMALL掌控。
所以接下来无论怎么换,窗口图标样式都不会变化了。
如果想要切换大小图标按钮时,让所有的图标也随之变换那么如下所示:
解决方法:
将wParam参数都设为ICON_BIG,调用函数时只会默认地用当时ICON_BIG所设置的图标,而窗口标题栏图标并不会真正地被覆盖。你换大标题(wParam参数为ICON_BIG),所有图标就用大图标设置的图标。你换小标题(wParam参数也为IOCN_BIG),就用小标题设置的图标。
/**就打个比方吧~~~:
//
假如食堂每天做的饭都不是你喜欢吃的,而你只能吃食堂的饭。那么今天食堂做这个饭你就只能吃这个饭,明天做那个,就只能吃那个饭,,也就是“所见即所得”。
但它不会覆盖你心中理想的饭。假如你在家,那么这时你就可以做你心中想吃的饭了,无论食堂做什么,你也都不会理会,吃自己做的就OK了。
//
*这里放修改后的样式图



下面是改过后_ProcWinMain的完整代码:
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
mov eax,uMsg
;***********************************************************************************
.if eax == WM_CREATE
invoke LoadIcon, hInstance, ICO_BIG
mov hIcoBig, eax
invoke LoadIcon, hInstance, ICO_SMALL
mov hIcoSmall, eax
invoke LoadCursor, hInstance, CUR_1
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 ;如果是加速键唤醒,就把高16位置零
.if eax == IDM_EXIT
call _Quit
.elseif eax == IDM_BIG
;WM_SETICON收到wParam参数,来设置ICO_BIG(大窗标)的类型,lParam是载入的图标
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
;***********************************************************************************
.elseif eax == WM_CLOSE
call _Quit
;***********************************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;***********************************************************************************
xor eax,eax
ret
_ProcWinMain endp
谢谢你能观看到最后^ _ ^ ❤️ ❤️ ❤️
这是我第一次写blog,肯定会有很多的不足之处,还望大家多多指正并提出建议。
我会坚持下去的!!!
在Windows编程中,使用WM_SETICON消息改变窗口图标时,遇到大图标和小图标切换不生效的问题。原因在于WM_SETICON的参数设置。正确做法是始终使用ICON_BIG作为wParam参数,这样无论是大图标还是小图标,都会跟随设置的图标变化。
2133

被折叠的 条评论
为什么被折叠?



