I need to set all the non-client areas of my app (border, caption, menu bar) to a specific color.
I can set the caption and border with DwmSetWindowAttribute. But the menu bar eludes me.
I try creating a brush and using SetMenuInfo like this:
LOGBRUSH lbr;
memset(&lbr, 0, sizeof(LOGBRUSH));
lbr.lbColor = RGB(200,0,0);
HBRUSH GBRUSH = CreateBrushIndirect(&lbr);
// Apply Brush to the Menu
MENUINFO mi = { 0 };
memset(&mi, 0, sizeof(MENUINFO));
mi.cbSize = sizeof(mi);
GetMenuInfo(GetMenu(), &mi);
mi.fMask = MIM_BACKGROUND | MIM_APPLYTOSUBMENUS;
mi.hbrBack = GBRUSH;
BOOL bRet = SetMenuInfo(GetMenu(), &mi);
... but that affects only the popup submenus, not the menu bar itself.
I found advice to use SetWindowTheme to disable the theme; that works, and allows me to then set the menu bar color BUT then I can no longer set the caption and border.
Short of going full owner-draw on the entire menu, is there a way I can use these (or other) APIs to set all the non-client regions?
Using undocumented Windows messages and structures to custom menubar.
0x0091
WM_UAHDRAWMENUThis message is sent to draw the menu bar background. TheLPARAMis a UAHMENU pointer.Draw the background into hdc. The menu bar rect can be calculated by using
GetMenuBarInfoto get the rcBar,GetWindowRectto get the window rect, and thenOffsetRect(rcBar, -rcWindow.left, -rcWindow.top).0x0092
WM_UAHDRAWMENUITEMThis message is sent to draw an individual menu item. TheLPARAMis aUAHDRAWMENUITEMpointer.The zero-based position of the menu item is in
umi.iPosition. Draw the background and text intoum.hdcusing the rectangle indis.rcItem. The state of the menu item is indis.itemState, generally a combination of any(ODS_DEFAULT | ODS_INACTIVE | ODS_HOTLIGHT | ODS_SELECTED | ODS_GRAYED | ODS_DISABLED | ODS_NOACCEL)0x0094
WM_UAHMEASUREMENUITEMThis message is sent to measure an individual menu item. The LPARAM is aUAHMEASUREMENUITEMpointer.Forwarding this to
DefWindowProcwill fill in the values as expected, which is all you need if you are simply changing background colors or etc and not messing with the width. TheMEASUREITEMSTRUCTis intended to be filled in with the size of the text.This is a sample Based on VS windows desktop application. This is the menubarsample.cpp:
This is "UAHMenuBar.h":