December 11, 2024, 10:38:16 PM

News:

IWBasic runs in Windows 11!


Transparent mdi icon in window menu

Started by sapero, December 03, 2009, 07:50:57 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

sapero

December 03, 2009, 07:50:57 AM Last Edit: December 03, 2009, 08:26:30 AM by sapero
Sometimes when you use a customized menu background color (changed by SetMenuInfo) and have MDI, after maximizing a child window, to the window menu is added one icon to left (system), and three icons to right (min/max/close), but unfortunatelly the system icon is not drawn transparently.

I have set in the control panel menu background color to white, but could not find where to change menubar color, to keep it gray, so I need to change menu background color: MENUINFO mi;
mi.cbSize = sizeof(mi);
mi.fMask = MIM_BACKGROUND;
mi.hbrBack = GetSysColorBrush(COLOR_BTNFACE);
SetMenuInfo(g_menu, &mi);


Here is the code to make the system icon transparent: // Child message handler:
case WM_CHILDACTIVATE:
result = DefMDIChildProc(hWnd, uMsg, wParam, lParam);
ChildUpdateMenuIcon();
// your code here
return result;

// call me after reopening (at startup) all documents, and after changing child icon
sub ChildUpdateMenuIcon()
{
HMENU menu = GetMenu(g_hwndMain); // window menu
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_BITMAP|MIIM_DATA;

// if a mdi child is maximized, the first menu item will be HBMMENU_SYSTEM
if (GetMenuItemInfo(menu, 0, TRUE, &mii) && (mii.hbmpItem == HBMMENU_SYSTEM)
&& IsWindow(mii.dwItemData))
{
mii.hbmpItem = HBMMENU_CALLBACK; // force ownerdrawn
SetMenuItemInfo(menu, 0, TRUE, &mii);
DrawMenuBar(g_hwndMain);
}
}

// Frame message handler:
case WM_MEASUREITEM:
MainOnMeasureItem(*(MEASUREITEMSTRUCT)lParam);

case WM_DRAWITEM:
MainOnDrawItem(*(DRAWITEMSTRUCT)lParam);

sub MainOnMeasureItem(MEASUREITEMSTRUCT *mis)
{
switch (mis->CtlType)
{
case ODT_MENU:
if (IsWindow(mis->itemData))
{
mis->itemWidth = 22;
mis->itemHeight = 16;
}
}
}

sub MainOnDrawItem(DRAWITEMSTRUCT *dis)
{
switch (dis->CtlType)
{
case ODT_MENU:
if (IsWindow(dis->itemData))
{
// the icon assigned to current mdi child window
HICON icon = SendMessage(dis->itemData, WM_GETICON, ICON_SMALL, 0);
FillRect(dis->hDC, &dis->rcItem, GetSysColorBrush(COLOR_BTNFACE));
DrawIconEx(dis->hDC, dis->rcItem.left, dis->rcItem.top, icon, 16, 16, 0, 0, DI_NORMAL);
}
}
}

And the image below shows how it is working: left-before, right-after.