无法更改菜单位图 [英] Unable To Change Menu Bitmap
问题描述
我有一个为应用程序定制的皮肤,它消除了标题/标题栏.所有菜单项和系统按钮都是所有者绘制的.一切正常,除了一个小错误.
I have a custom-drawn skin for an app, that eliminates the caption/title bar. All of the menu items and system buttons are owner-drawn. Everything works as it should, except one little bug.
当按下 Maximize 按钮,并且窗口最大化时,代码也应该更改按钮位图,从Maximize"图标,到恢复"图标.然而,我无法让它改变.这是处理该按钮命令的代码:
When the Maximize button is pressed, and the window maximizes, the code should also change the button bitmap, from the "Maximize" icon, to the "Restore" icon. Yet, I cannot get it to change. Here is the code that handles that button command:
case ID_MENUBAR_MAX: {
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwnd, &wp);
mII.cbSize = sizeof(MENUITEMINFO);
mII.fMask = MIIM_BITMAP;
GetMenuItemInfo(hMenu, NUMMI+2, TRUE, &mII);
if (wp.showCmd == SW_SHOWNORMAL){ mII.hbmpItem = hMBB.restore; SendMessage(hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0); }
if (wp.showCmd == SW_SHOWMAXIMIZED){ mII.hbmpItem = hMBB.max; SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); }
SetMenuItemInfo(hMenu, NUMMI+2, TRUE, &mII);
DrawMenuBar(hwnd);
return 0;
}
正如我所提到的,一切正常.当按下按钮时,窗口会最大化或正常化,这是应该的.我只是无法让按钮上的位图随之改变.我错过了什么?一定很简单.
As I mentioned, everything works as it should. When the button is pressed the window maximizes or normalizes, as it should. I just can't get the bitmap on the button to change along with it. What am I missing? It must be something simple.
推荐答案
My Bad! 我忘记将 hMenu
声明为 static 变量.正因为如此,我失去了我的菜单句柄.这就是 SetMenuItemInfo()
稍后在命令代码块中不起作用的原因.我知道它必须很简单.
My Bad! I forgot to declare hMenu
as a static variable. Because of that, I was losing my menu handle. That's why SetMenuItemInfo()
would not work later, in the command code blocks. I knew that it had to be something simple.
无论如何,这是代码的最后部分.一、Max/Restore按钮的创建:
Anyway, here are the final bits of code. First, the creation of the Max/Restore buttons:
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hWnd, &wp);
if(wp.showCmd==SW_SHOWNORMAL){ mII.wID=ID_MENUBAR_MAX; mII.hbmpItem=hMBB.max; }
if(wp.showCmd==SW_SHOWMAXIMIZED){ mII.wID=ID_MENUBAR_RESTORE; mII.hbmpItem=hMBB.restore; }
InsertMenuItem(hMenu, NUMMI+2, TRUE, &mII);
这里是命令的处理:
case ID_MENUBAR_MAX:
SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
return 0;
case ID_MENUBAR_RESTORE:
SendMessage(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
return 0;
最后,我通过挂钩WM_SYSCOMMAND
来处理菜单按钮的更改.这样,即使命令来自系统菜单或其他系统命令,按钮也会改变:
Finally, I handled the changing of the menu button by hooking WM_SYSCOMMAND
. That way, the button would change, even if the command came through the system menu, or some other system command:
case WM_SYSCOMMAND: {
auto sysResult = DefWindowProc(hWnd, WM_SYSCOMMAND, wParam, lParam);
if(wParam==SC_MAXIMIZE) {
mII.cbSize = sizeof(MENUITEMINFO);
mII.fMask = MIIM_ID | MIIM_BITMAP;
mII.wID = ID_MENUBAR_RESTORE;
mII.hbmpItem = hMBB.restore;
SetMenuItemInfo(hMenu, NUMMI+2, TRUE, &mII);
DrawMenuBar(hWnd);
}
if(wParam==SC_RESTORE) {
mII.cbSize = sizeof(MENUITEMINFO);
mII.fMask = MIIM_ID | MIIM_BITMAP;
mII.wID = ID_MENUBAR_MAX;
mII.hbmpItem = hMBB.max;
SetMenuItemInfo(hMenu, NUMMI+2, TRUE, &mII);
DrawMenuBar(hWnd);
}
return sysResult;
}
注意:每当向系统或非客户端命令添加任何内容时,调用 DefWindowProc
很重要.使用消息参数的命令标题.typedef auto
用于处理函数返回的任何变量.
Note: It is important to call DefWindowProc
whenever adding anything to system or non-client commands. Use the command title for the message parameter. The typedef auto
is used, to handle whatever variable that the function returns.
这篇关于无法更改菜单位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!