home *** CD-ROM | disk | FTP | other *** search
- // Microworks ObjectMate 2.6
- //
- // Ownerdraw Menu Functions
- //
- // Copyright 1992-94 Microworks Sydney, Australia.
- //
- // SMENU.CPP
-
- /* This file contains the functions necessary to draw ownerdraw menus. The main
- * functions are 'DrawMenuItem' and 'MeasureMenuItem' and should be called from
- * EvDrawItem and EvMeasureItem respecitively. You can specify the menu text font,
- * highlight color and highlight text color as arguments in a call to DrawMenuItem.
- * The default values are zero and specify a fine system font and the standard
- * Windows' highlight and highlight-text colors. The font handle passed as an
- * argument to DrawMenuItem should also be passed to MeasureMenuItem so that each
- * item is measured and drawn using the same font.
- *
- * The other functions 'StripStrLen', 'GetMenuItemPos', 'ProcessSystemChar' and
- * 'Set3DSystemMenu' are accessory functions. GetMenuItemPos returns the zero based
- * position of a menu item. It's used to determine if the next or previous menu
- * item is a separator and if it is, draw its the adjacent 3D part along with the
- * current item. Set3DSystemMenu sets up an ownerdraw system menu and ProcessSystemChar
- * processes its mnemonics. You should call Set3DSystemMenu from somewhere like
- * SetupWindow. It takes a window handle and application name as arguments.
- * ProcessSystemChar must be called from EvMenuChar if the active menu is the system
- * menu. StripStrLen calculates the length of the menu text minus any 'single' or
- * 'first of a pair' ampersands.
- *
- * Since the system menu rarely gets modified the Set3DSystemMenu and
- * ProcessSystemChar functions are provided for convenience.
- *
- * You can enhance your ownerdraw menu's by adding a bitmap or icon glyph to each
- * item. If you do, you will need to pass a pointer to a structure that specifies
- * the menu item text and bitmap or icon handle as its members. This pointer is
- * passed as the itemData member of the DRAWITEMSTRUCT and MEASUREITEMSTRUCT
- * structures. You will need to retrieve the text string and bitmap or icon handle
- * in MeasureMenuItem to calculate the itemWidth and itemHeight, and in DrawMenuItem
- * to draw each item.
- */
- #include <windows.h>
- #include <sfx\sfx200.h>
- #include <sfx\smenu.h>
- #include <string.h>
-
- const COLORREF BLACK = 0;
- const COLORREF LTGRAY = RGB(192, 192, 192);
-
- // StripStrLen - returns the length of string "str" minus any "underline" or
- // "first of a pair" ampersands.
-
- int StripStrLen(char* str)
- {
- int i = strlen(str);
- char* ptr = strchr(str, '&');
- while (ptr)
- {
- i--;
- ptr = strchr(&ptr[2], '&');
- }
- return i;
- }
-
- // DrawMenuItem - draws the ownerdraw menu items. hFont, color and textColor can be zero.
-
- void
- DrawMenuItem(DRAWITEMSTRUCT far& dis, HFONT hFont, COLORREF color, COLORREF textColor)
- {
- BOOL isNext, isPrev;
- HBRUSH grayBrush, whiteBrush;
- HBRUSH brush, oldBrush;
- HFONT oldFont;
- HPEN oldPen, pen;
- int a, b, c;
- UINT count, pos;
- char menuText[144];
-
- if (dis.CtlType == ODT_MENU)
- {
- isNext = FALSE;
- isPrev = FALSE;
- if (GetSystemMetrics(SM_CYSIZE) == 26)
- a = b = 5;
- else
- {
- if (GetSystemMetrics(SM_CXSCREEN) == 640)
- a = 3;
- else
- a = 4;
- b = 3;
- }
- whiteBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
- grayBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
-
- if (dis.itemState & ODS_SELECTED)
- {
- if (!color)
- color = GetSysColor(COLOR_HIGHLIGHT);
- if (!textColor)
- textColor = GetSysColor(COLOR_HIGHLIGHTTEXT);
- }
- else
- {
- color = LTGRAY;
- textColor = BLACK;
- }
-
- brush = CreateSolidBrush(color);
- SetBkColor(dis.hDC, color);
- SetBkMode(dis.hDC, TRANSPARENT);
- if (dis.itemState & ODS_GRAYED)
- {
- if (dis.itemState & ODS_SELECTED)
- {
- if (color == LTGRAY)
- SetTextColor(dis.hDC, RGB(221, 221, 221));
- else
- SetTextColor(dis.hDC, LTGRAY);
- }
- else
- SetTextColor(dis.hDC, GetSysColor(COLOR_GRAYTEXT));
- }
- else
- SetTextColor(dis.hDC, textColor);
-
- count = GetMenuItemCount((HMENU)dis.hwndItem) - 1;
- pos = GetMenuItemPos((HMENU)dis.hwndItem, dis.itemID);
- if (pos <= count && !GetMenuItemID((HMENU)dis.hwndItem, pos + 1))
- {
- dis.rcItem.bottom += a;
- isNext = TRUE;
- }
- if (pos && !GetMenuItemID((HMENU)dis.hwndItem, pos - 1))
- {
- dis.rcItem.top -= b;
- isPrev = TRUE;
- }
-
- oldBrush = (HBRUSH)SelectObject(dis.hDC, whiteBrush);
- PatBlt(dis.hDC, dis.rcItem.left, dis.rcItem.top, 2, dis.rcItem.bottom -
- dis.rcItem.top, PATCOPY);
- SelectObject(dis.hDC, grayBrush);
- PatBlt(dis.hDC, dis.rcItem.right-2, dis.rcItem.top, 2, dis.rcItem.bottom -
- dis.rcItem.top, PATCOPY);
- if (!pos || isPrev)
- {
- SelectObject(dis.hDC, whiteBrush);
- PatBlt(dis.hDC, dis.rcItem.left+2, dis.rcItem.top, dis.rcItem.right -
- dis.rcItem.left-2, 1, PATCOPY);
- PatBlt(dis.hDC, dis.rcItem.left+2, dis.rcItem.top+1, dis.rcItem.right -
- dis.rcItem.left-3, 1, PATCOPY);
- dis.rcItem.top += 2;
- }
- if (pos == count || isNext)
- {
- SelectObject(dis.hDC, grayBrush);
- PatBlt(dis.hDC, dis.rcItem.left+1, dis.rcItem.bottom-1, dis.rcItem.right -
- dis.rcItem.left-2, 1, PATCOPY);
- PatBlt(dis.hDC, dis.rcItem.left+2, dis.rcItem.bottom-2, dis.rcItem.right -
- dis.rcItem.left-4, 1, PATCOPY);
- dis.rcItem.bottom -= 2;
- }
- InflateRect(&dis.rcItem, -2, 0);
- if (dis.itemState & ODS_SELECTED)
- {
- if (isNext)
- {
- dis.rcItem.bottom -= a;
- if (dis.itemState & ODS_SELECTED)
- {
- SelectObject(dis.hDC, GetStockObject(LTGRAY_BRUSH));
- PatBlt(dis.hDC, dis.rcItem.left, dis.rcItem.bottom, dis.rcItem.right -
- dis.rcItem.left, a, PATCOPY);
- }
- }
- if (isPrev)
- {
- dis.rcItem.top += b;
- if (dis.itemState & ODS_SELECTED)
- {
- SelectObject(dis.hDC, GetStockObject(LTGRAY_BRUSH));
- PatBlt(dis.hDC, dis.rcItem.left, dis.rcItem.top -3, dis.rcItem.right -
- dis.rcItem.left, b, PATCOPY);
- }
- }
-
- }
- FillRect(dis.hDC, &dis.rcItem, brush);
- SelectObject(dis.hDC, oldBrush);
-
- if (dis.itemState & ODS_CHECKED)
- {
- pen = CreatePen(PS_SOLID, 1, textColor);
- oldPen = (HPEN)SelectObject(dis.hDC, pen);
- c = dis.rcItem.top + ((dis.rcItem.bottom - dis.rcItem.top - 10)/2);
- MoveTo(dis.hDC, dis.rcItem.left + 3, c + 5);
- LineTo(dis.hDC, dis.rcItem.left + 3, c + 10);
- MoveTo(dis.hDC, dis.rcItem.left + 4, c + 4);
- LineTo(dis.hDC, dis.rcItem.left + 4, c + 10);
- MoveTo(dis.hDC, dis.rcItem.left + 5, c + 7);
- LineTo(dis.hDC, dis.rcItem.left + 12, c + 0);
- MoveTo(dis.hDC, dis.rcItem.left + 5, c + 8);
- LineTo(dis.hDC, dis.rcItem.left + 13, c + 0);
- SelectObject(dis.hDC, oldPen);
- DeleteObject(pen);
- }
-
- strcpy(menuText, (const char*)dis.itemData);
- if (hFont)
- oldFont = (HFONT)SelectObject(dis.hDC, hFont);
- else
- oldFont = (HFONT)SelectObject(dis.hDC, (HFONT)GetSFXObject(SYSTEM_FINE_FONT));
- dis.rcItem.left = 7 + 12;
- if (!dis.itemState & ODS_SELECTED)
- {
- if (isNext)
- dis.rcItem.bottom -= a;
- else
- if (isPrev)
- dis.rcItem.top += b;
- }
- DrawText(dis.hDC, menuText, -1, &dis.rcItem, DT_SINGLELINE + DT_VCENTER + DT_EXPANDTABS);
- if ((dis.itemState & ODS_SELECTED) && color != LTGRAY)
- {
- OffsetRect(&dis.rcItem, 1, 0);
- DrawText(dis.hDC, menuText, -1, &dis.rcItem, DT_SINGLELINE + DT_VCENTER +
- DT_EXPANDTABS);
- }
- SelectObject(dis.hDC, oldFont);
- DeleteObject(brush);
- }
- }
-
- // GetMenuItemPos - returns the zero based position of a menu item
-
- int
- GetMenuItemPos(HMENU hMenu, int itemId)
- {
- int pos = GetMenuItemCount(hMenu) - 1;
- if (IsMenu((HMENU)itemId))
- {
- int item = (int)GetSubMenu(hMenu, pos);
- while (pos && item != itemId)
- {
- pos--;
- item = (int)GetSubMenu(hMenu, pos);
- }
- }
- else
- {
- int item = GetMenuItemID(hMenu, pos);
- while (pos && item != itemId)
- {
- pos--;
- item = GetMenuItemID(hMenu, pos);
- }
- }
- return pos;
- }
-
- // MeasureMenuItem - sets the width and height of ownerdraw menu items. hFont can be zero.
-
- void
- MeasureMenuItem(HWND hWnd, MEASUREITEMSTRUCT far& mis, HFONT hFont)
- {
- HDC dc;
- HFONT menuFont, oldFont;
- SIZE size;
- char menuText[144];
-
- if (mis.CtlType == ODT_MENU)
- {
- dc = GetDC(hWnd);
- if (hFont)
- menuFont = hFont;
- else
- menuFont = (HFONT)GetSFXObject(SYSTEM_FINE_FONT);
- oldFont = (HFONT)SelectObject(dc, menuFont);
- strcpy(menuText, (const char*)mis.itemData);
- GetTextExtentPoint(dc, menuText, StripStrLen((char*)menuText), &size);
- mis.itemWidth = size.cx + 20;
- mis.itemHeight = size.cy + ((size.cy / 5) * 2);
- SelectObject(dc, oldFont);
- ReleaseDC(hWnd, dc);
- }
- }
-
- // ProcessSystemChar - call from EvMenuChar to process the system menu's mnemonics
-
- DWORD
- ProcessSystemChar(UINT nChar)
- {
- switch (nChar)
- {
- case 82:
- case 114:
- return MAKELONG(0, 2);
-
- case 77:
- case 109:
- return MAKELONG(1, 2);
-
- case 83:
- case 115:
- return MAKELONG(2, 2);
-
- case 78:
- case 110:
- return MAKELONG(3, 2);
-
- case 88:
- case 120:
- return MAKELONG(4, 2);
-
- case 67:
- case 99:
- return MAKELONG(6, 2);
-
- default:
- return 0L;
- }
- }
-
- // Set3DSystemMenu - sets up a basic 3D system menu, minus the "Switch To" item.
-
- void
- Set3DSystemMenu(HWND hWnd, const char* name)
- {
- static char textStr[50];
-
- HMENU sysMenu = GetSystemMenu(hWnd, FALSE);
- RemoveMenu(sysMenu, 7, MF_BYPOSITION);
- RemoveMenu(sysMenu, 7, MF_BYPOSITION);
- ModifyMenu(sysMenu, 0, MF_BYPOSITION | MF_OWNERDRAW, SC_RESTORE, "&Restore");
- ModifyMenu(sysMenu, 1, MF_BYPOSITION | MF_OWNERDRAW, SC_MOVE, "&Move");
- ModifyMenu(sysMenu, 2, MF_BYPOSITION | MF_OWNERDRAW, SC_SIZE, "&Size");
- ModifyMenu(sysMenu, 3, MF_BYPOSITION | MF_OWNERDRAW, SC_MINIMIZE, "Mi&nimize");
- ModifyMenu(sysMenu, 4, MF_BYPOSITION | MF_OWNERDRAW, SC_MAXIMIZE, "Ma&ximize");
- wsprintf(textStr, "&Close %s Alt+F4", name);
- ModifyMenu(sysMenu, 6, MF_BYPOSITION | MF_OWNERDRAW, SC_CLOSE, textStr);
- }
-
-
-
-
-
-