00001
00002
00003
00004 #include "odmenu.h"
00005
00006 using namespace std;
00007
00008 ODMenu::ODMenu()
00009 {
00010 m_seqNumber = 0;
00011
00012
00013
00014
00015 m_clrTranparent = RGB(192, 192, 192);
00016
00017 m_clrItemText = GetSysColor(COLOR_MENUTEXT);
00018 m_clrItemBackground = GetSysColor(COLOR_MENU);
00019 if(GetColorIntensity(m_clrItemBackground) < 0.82)
00020 m_clrItemBackground = LightenColor(m_clrItemBackground, 0.27);
00021 else
00022 m_clrItemBackground = DarkenColor(m_clrItemBackground, 0.10);
00023 m_clrHighlightItemText = GetSysColor(COLOR_HIGHLIGHTTEXT);
00024 m_clrHighlightItemBackground = GetSysColor(COLOR_HIGHLIGHT);
00025 m_clrHighlightItemBackground = LightenColor(m_clrHighlightItemBackground, 0.5);
00026 m_clrHighlightItemOutline = GetSysColor(COLOR_HIGHLIGHT);
00027 m_clrSeparator = GetSysColor(COLOR_3DSHADOW);
00028 m_clrIconBar = GetSysColor(COLOR_MENU);
00029 m_clrIconShadow = GetSysColor(COLOR_3DSHADOW);
00030 m_clrCheckMark = GetSysColor(COLOR_MENUTEXT);
00031 m_clrCheckMarkBackground = AverageColor(m_clrIconBar, m_clrHighlightItemBackground, 0.8);
00032 m_clrCheckMarkBackgroundHighlight = AverageColor(m_clrIconBar, m_clrHighlightItemBackground, 0.25);
00033 m_clrCheckMarkBackgroundHighlight = DarkenColor(m_clrHighlightItemBackground, 0.1);
00034
00035
00036 NONCLIENTMETRICS ncms;
00037 ncms.cbSize = sizeof(NONCLIENTMETRICS);
00038 if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncms, 0))
00039 m_hFont = CreateFontIndirect(&ncms.lfMenuFont);
00040
00041
00042 m_iconBarMargin = 3;
00043 m_textLeftMargin = 6;
00044 m_textRightMargin = 3;
00045 m_iconWidth = GetSystemMetrics(SM_CXSMICON);
00046 m_iconHeight = GetSystemMetrics(SM_CYSMICON);
00047 m_verticalSpacing = 6;
00048
00049
00050 m_hItemBackground = CreateSolidBrush(m_clrItemBackground);
00051 m_hIconBarBrush = CreateSolidBrush(m_clrIconBar);
00052 m_hIconShadowBrush = CreateSolidBrush(m_clrIconShadow);
00053 m_hHighlightItemBackgroundBrush = CreateSolidBrush(m_clrHighlightItemBackground);
00054 m_hCheckMarkBackgroundBrush = CreateSolidBrush(m_clrCheckMarkBackground);
00055 m_hCheckMarkBackgroundHighlightBrush = CreateSolidBrush(m_clrCheckMarkBackgroundHighlight);
00056 m_hSelectionOutlinePen = CreatePen(PS_SOLID, 1, m_clrHighlightItemOutline);
00057 m_hSeparatorPen = CreatePen(PS_SOLID, 1, m_clrSeparator);
00058 m_hCheckMarkPen = CreatePen(PS_SOLID, 1, m_clrCheckMark);
00059 }
00060
00061 ODMenu::~ODMenu()
00062 {
00063 if(m_hFont)
00064 DeleteObject(m_hFont);
00065 if(m_hIconBarBrush)
00066 DeleteObject(m_hIconBarBrush);
00067 if(m_hIconShadowBrush)
00068 DeleteObject(m_hIconShadowBrush);
00069 if(m_hCheckMarkBackgroundBrush)
00070 DeleteObject(m_hCheckMarkBackgroundBrush);
00071 if(m_hCheckMarkBackgroundHighlightBrush)
00072 DeleteObject(m_hCheckMarkBackgroundHighlightBrush);
00073 if(m_hSelectionOutlinePen)
00074 DeleteObject(m_hSelectionOutlinePen);
00075 if(m_hSeparatorPen)
00076 DeleteObject(m_hSeparatorPen);
00077 if(m_hCheckMarkPen)
00078 DeleteObject(m_hCheckMarkPen);
00079 if(m_hItemBackground)
00080 DeleteObject(m_hItemBackground);
00081 if(m_hHighlightItemBackgroundBrush)
00082 DeleteObject(m_hHighlightItemBackgroundBrush);
00083 }
00084
00085 bool ODMenu::Init(HWND hOwnerWnd, HMENU hMenu)
00086 {
00087 m_hRootMenu = hMenu;
00088
00089
00090
00091
00092 if(m_seqNumber == 0)
00093 EnumMenuItems(hMenu);
00094
00095 return true;
00096 }
00097
00098 void ODMenu::EnumMenuItems(HMENU hMenu)
00099 {
00100 int i, numItems;
00101 MENUITEMINFO miInfo;
00102
00103 numItems = GetMenuItemCount(hMenu);
00104 if(numItems > 0)
00105 {
00106 miInfo.cbSize = sizeof(MENUITEMINFO);
00107 miInfo.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
00108 miInfo.dwTypeData = m_szItemText;
00109 miInfo.cch = sizeof(m_szItemText);
00110
00111 for(i=0; i<numItems; i++)
00112 {
00113 if(GetMenuItemInfo(hMenu, i, TRUE, &miInfo))
00114 AddItem(hMenu, i, &miInfo);
00115
00116 if(miInfo.hSubMenu)
00117 {
00118
00119 EnumMenuItems(miInfo.hSubMenu);
00120 }
00121
00122 miInfo.cch = sizeof(m_szItemText);
00123 miInfo.dwTypeData = m_szItemText;
00124 }
00125 }
00126 }
00127
00128 void ODMenu::DeleteSubMenu(HMENU hMenu)
00129 {
00130
00131 int i;
00132 MENUITEMINFO miInfo;
00133
00134 i = 0;
00135 miInfo.cbSize = sizeof(MENUITEMINFO);
00136 miInfo.fMask = MIIM_SUBMENU | MIIM_DATA;
00137 while(GetMenuItemInfo(hMenu, i, TRUE, &miInfo))
00138 {
00139
00140 if(miInfo.hSubMenu)
00141 DeleteSubMenu(miInfo.hSubMenu);
00142
00143
00144 m_menuItems.erase(miInfo.dwItemData);
00145
00146 i++;
00147 }
00148 }
00149
00150 void ODMenu::SetMenuItemOwnerDrawn(HMENU hMenu, UINT item, UINT type)
00151 {
00152
00153 MENUITEMINFO miInfo;
00154
00155 miInfo.cbSize = sizeof(MENUITEMINFO);
00156 miInfo.fMask = MIIM_TYPE | MIIM_DATA;
00157 miInfo.fType = type | MFT_OWNERDRAW;
00158 miInfo.dwItemData = m_seqNumber++;
00159
00160 SetMenuItemInfo(hMenu, item, TRUE, &miInfo);
00161 }
00162
00163 void ODMenu::GenerateDisplayText(ODMENUITEM& item)
00164 {
00165 TCHAR* pChr;
00166 int i;
00167
00168 item.displayText = "";
00169 item.rawDisplayText = "";
00170 item.shortcutText = "";
00171
00172
00173 if(pChr = strchr((LPTSTR)item.rawText.c_str(), '\t'))
00174 item.shortcutText = pChr + 1;
00175
00176 i = 0;
00177 pChr = (LPTSTR)item.rawText.c_str();
00178 while(*(pChr + i) != '\t' && *(pChr + i) != '\0')
00179 {
00180 if(*(pChr + i) == '&')
00181 {
00182 item.rawDisplayText.append(pChr + i, 1);
00183 i++;
00184
00185 continue;
00186 }
00187
00188 item.rawDisplayText.append(pChr + i, 1);
00189 item.displayText.append(pChr + i, 1);
00190 i++;
00191 }
00192 }
00193
00194 void ODMenu::DrawItemText(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
00195 {
00196 int x, y;
00197 SIZE size;
00198 RECT rectText;
00199 RECT rectItem;
00200
00201 memcpy(&rectItem, &lpdis->rcItem, sizeof(RECT));
00202
00203
00204 GetTextExtentPoint32(lpdis->hDC, item.displayText.c_str(), item.displayText.length(), &size);
00205
00206
00207 ComputeMenuTextPos(lpdis, item, x, y, size);
00208
00209 rectText.left = x;
00210 rectText.right = lpdis->rcItem.right - m_textRightMargin;
00211 rectText.top = y;
00212 rectText.bottom = lpdis->rcItem.bottom;
00213
00214
00215 if(!item.topMost)
00216 {
00217 rectItem.left += (m_iconWidth + 2*m_iconBarMargin);
00218 }
00219
00220
00221 ExtTextOut(lpdis->hDC, x, y, ETO_OPAQUE, &rectItem, "", 0, NULL);
00222
00223
00224 DrawText(lpdis->hDC, item.rawDisplayText.c_str(), item.rawDisplayText.length(),
00225 &rectText, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
00226 DrawText(lpdis->hDC, item.shortcutText.c_str(), item.shortcutText.length(),
00227 &rectText, DT_RIGHT | DT_SINGLELINE | DT_VCENTER);
00228 }
00229
00230 void ODMenu::DrawIconBar(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item)
00231 {
00232 RECT rectBar;
00233 memcpy(&rectBar, &lpdis->rcItem, sizeof(RECT));
00234
00235
00236 if(!item.topMost)
00237 {
00238 rectBar.right = rectBar.left + m_iconWidth + 2*m_iconBarMargin + 1;
00239 if(lpdis->itemState & ODS_SELECTED &&
00240 !(lpdis->itemState & ODS_DISABLED || lpdis->itemState & ODS_GRAYED))
00241 {
00242 FillRect(lpdis->hDC, &rectBar, m_hHighlightItemBackgroundBrush);
00243 }
00244 else
00245 {
00246 FillRect(lpdis->hDC, &rectBar, m_hIconBarBrush);
00247 }
00248
00249 }
00250
00251 int x, y;
00252
00253
00254 if(item.hBitmap)
00255 {
00256 x = m_iconBarMargin;
00257 y = rectBar.top + ((rectBar.bottom - rectBar.top - 16) / 2);
00258
00259 if(lpdis->itemState & ODS_DISABLED || lpdis->itemState & ODS_GRAYED)
00260 {
00261
00262 DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x, y, m_clrTranparent, eDisabled);
00263 }
00264 else if(lpdis->itemState & ODS_SELECTED)
00265 {
00266
00267
00268 DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x+1, y+1, m_clrTranparent, eShadow);
00269
00270
00271 DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x-1, y-1, m_clrTranparent);
00272 }
00273 else
00274 {
00275
00276 DrawTransparentBitmap(lpdis->hDC, item.hBitmap, x, y, m_clrTranparent, eFaded);
00277 }
00278 }
00279 else if(lpdis->itemState & ODS_CHECKED)
00280 {
00281 HBRUSH hPrevBrush;
00282 HPEN hPrevPen;
00283 RECT rect;
00284
00285
00286 if(lpdis->itemState & ODS_SELECTED)
00287 hPrevBrush = (HBRUSH)SelectObject(lpdis->hDC, m_hCheckMarkBackgroundHighlightBrush);
00288 else
00289 hPrevBrush = (HBRUSH)SelectObject(lpdis->hDC, m_hCheckMarkBackgroundBrush);
00290 hPrevPen = (HPEN)SelectObject(lpdis->hDC, m_hSelectionOutlinePen);
00291 rect.left = m_iconBarMargin;
00292 rect.right = m_iconBarMargin + m_iconWidth;
00293 rect.top = rectBar.top + (rectBar.bottom - rectBar.top - m_iconHeight) / 2;
00294 rect.bottom = rect.top + m_iconHeight;
00295 Rectangle(lpdis->hDC, rect.left, rect.top, rect.right, rect.bottom);
00296 SelectObject(lpdis->hDC, hPrevBrush);
00297 SelectObject(lpdis->hDC, hPrevPen);
00298
00299
00300 x = (m_iconWidth + 2*m_iconBarMargin - 6) / 2;
00301 y = rectBar.top + ((rectBar.bottom - rectBar.top - 7) / 2) + 1;
00302 DrawCheckMark(lpdis->hDC, x, y, true);
00303 }
00304 }
00305
00306 void ODMenu::ComputeMenuTextPos(DRAWITEMSTRUCT* lpdis, ODMENUITEM& item, int& x, int& y, SIZE& size)
00307 {
00308 x = lpdis->rcItem.left;
00309 y = lpdis->rcItem.top;
00310
00311
00312 if(!item.topMost)
00313 {
00314
00315 x += (m_iconWidth + 2*m_iconBarMargin + m_textLeftMargin);
00316 }
00317 else
00318 {
00319
00320 x += ((lpdis->rcItem.right - lpdis->rcItem.left - size.cx) / 2);
00321 }
00322 }
00323
00324 void ODMenu::DrawTransparentBitmap(HDC hDC, HBITMAP hBitmap, short xStart,
00325 short yStart, COLORREF cTransparentColor,
00326 bitmapType eType)
00327 {
00328 BITMAP bm;
00329 COLORREF cColor;
00330 HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
00331 HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
00332 HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
00333 POINT ptSize;
00334 HBRUSH hOldBrush;
00335
00336 BOOL bRC;
00337
00338 hdcTemp = CreateCompatibleDC(hDC);
00339 SelectObject(hdcTemp, hBitmap);
00340
00341 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
00342 ptSize.x = bm.bmWidth;
00343 ptSize.y = bm.bmHeight;
00344 DPtoLP(hdcTemp, &ptSize, 1);
00345
00346
00347
00348 hdcBack = CreateCompatibleDC(hDC);
00349 hdcObject = CreateCompatibleDC(hDC);
00350 hdcMem = CreateCompatibleDC(hDC);
00351 hdcSave = CreateCompatibleDC(hDC);
00352
00353
00354
00355
00356
00357 bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
00358
00359
00360 bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
00361
00362 bmAndMem = CreateCompatibleBitmap(hDC, ptSize.x, ptSize.y);
00363 bmSave = CreateCompatibleBitmap(hDC, ptSize.x, ptSize.y);
00364
00365
00366 bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack);
00367 bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);
00368 bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem);
00369 bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave);
00370
00371
00372 SetMapMode(hdcTemp, GetMapMode(hDC));
00373
00374
00375 bRC = BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
00376
00377
00378
00379
00380
00381
00382 cColor = SetBkColor(hdcTemp, cTransparentColor);
00383
00384
00385
00386 bRC = BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
00387
00388
00389 SetBkColor(hdcTemp, cColor);
00390
00391
00392 bRC = BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY);
00393
00394
00395 bRC = BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hDC, xStart, yStart, SRCCOPY);
00396
00397
00398
00399
00400 bRC = BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
00401
00402 if(eType == eNormal)
00403 {
00404
00405
00406 BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
00407
00408
00409
00410 BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
00411 }
00412 else if(eType == eShadow)
00413 {
00414
00415 hOldBrush = (HBRUSH)SelectObject(hdcTemp, m_hIconShadowBrush);
00416
00417
00418 bRC = BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, MERGECOPY);
00419
00420
00421
00422 bRC = BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
00423
00424
00425 SelectObject(hdcTemp, hOldBrush);
00426 }
00427 else if(eType == eFaded)
00428 {
00429 COLORREF col;
00430 int x, y;
00431
00432
00433 for(x=0; x<ptSize.x; x++)
00434 {
00435 for(y=0; y<ptSize.y; y++)
00436 {
00437 col = GetPixel(hdcTemp, x, y);
00438 col = LightenColor(col, 0.3);
00439 SetPixel(hdcTemp, x, y, col);
00440 }
00441 }
00442
00443
00444
00445 BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
00446
00447
00448
00449 BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
00450 }
00451 else if(eType == eDisabled)
00452 {
00453 COLORREF discol, col;
00454 BYTE r, g, b;
00455 int x, y;
00456 int avgcol;
00457 double factor;
00458
00459
00460
00461 discol = GetSysColor(COLOR_BTNSHADOW);
00462 for(x=0; x<ptSize.x; x++)
00463 {
00464 for(y=0; y<ptSize.y; y++)
00465 {
00466 col = GetPixel(hdcTemp, x, y);
00467 r = GetRValue(col);
00468 g = GetGValue(col);
00469 b = GetBValue(col);
00470 avgcol = (r + g + b) / 3;
00471 factor = avgcol / 255.0;
00472 SetPixel(hdcTemp, x, y, LightenColor(discol, factor));
00473 }
00474 }
00475
00476
00477
00478 BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
00479
00480
00481
00482 BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
00483 }
00484
00485
00486 bRC = BitBlt(hDC, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY);
00487
00488
00489 bRC = BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
00490
00491
00492 DeleteObject(SelectObject(hdcBack, bmBackOld));
00493 DeleteObject(SelectObject(hdcObject, bmObjectOld));
00494 DeleteObject(SelectObject(hdcMem, bmMemOld));
00495 DeleteObject(SelectObject(hdcSave, bmSaveOld));
00496
00497
00498 DeleteDC(hdcMem);
00499 DeleteDC(hdcBack);
00500 DeleteDC(hdcObject);
00501 DeleteDC(hdcSave);
00502 DeleteDC(hdcTemp);
00503 }
00504
00505 void ODMenu::DrawCheckMark(HDC hDC, short x, short y, bool bNarrow)
00506 {
00507 HPEN hOldPen;
00508 int dp = 0;
00509
00510 if(bNarrow)
00511 dp = 1;
00512
00513
00514 hOldPen = (HPEN)SelectObject(hDC, m_hCheckMarkPen);
00515
00516
00517 MoveToEx(hDC, x, y + 2, NULL);
00518 LineTo(hDC, x, y + 5 - dp);
00519
00520 MoveToEx(hDC, x + 1, y + 3, NULL);
00521 LineTo(hDC, x + 1, y + 6 - dp);
00522
00523 MoveToEx(hDC, x + 2, y + 4, NULL);
00524 LineTo(hDC, x + 2, y + 7 - dp);
00525
00526 MoveToEx(hDC, x + 3, y + 3, NULL);
00527 LineTo(hDC, x + 3, y + 6 - dp);
00528
00529 MoveToEx(hDC, x + 4, y + 2, NULL);
00530 LineTo(hDC, x + 4, y + 5 - dp);
00531
00532 MoveToEx(hDC, x + 5, y + 1, NULL);
00533 LineTo(hDC, x + 5, y + 4 - dp);
00534
00535 MoveToEx(hDC, x + 6, y, NULL);
00536 LineTo(hDC, x + 6, y + 3 - dp);
00537
00538
00539 SelectObject(hDC, hOldPen);
00540 }
00541
00542 COLORREF ODMenu::LightenColor(COLORREF col, double factor)
00543 {
00544 if(factor > 0.0 && factor <= 1.0)
00545 {
00546 BYTE red, green, blue, lightred, lightgreen, lightblue;
00547 red = GetRValue(col);
00548 green = GetGValue(col);
00549 blue = GetBValue(col);
00550 lightred = (BYTE)((factor*(255 - red)) + red);
00551 lightgreen = (BYTE)((factor*(255 - green)) + green);
00552 lightblue = (BYTE)((factor*(255 - blue)) + blue);
00553 col = RGB(lightred, lightgreen, lightblue);
00554 }
00555
00556 return col;
00557 }
00558
00559 COLORREF ODMenu::DarkenColor(COLORREF col, double factor)
00560 {
00561 if(factor > 0.0 && factor <= 1.0)
00562 {
00563 BYTE red, green, blue, lightred, lightgreen, lightblue;
00564 red = GetRValue(col);
00565 green = GetGValue(col);
00566 blue = GetBValue(col);
00567 lightred = (BYTE)(red - (factor*red));
00568 lightgreen = (BYTE)(green - (factor*green));
00569 lightblue = (BYTE)(blue - (factor*blue));
00570 col = RGB(lightred, lightgreen, lightblue);
00571 }
00572 return col;
00573 }
00574
00575 COLORREF ODMenu::AverageColor(COLORREF col1, COLORREF col2, double weight)
00576 {
00577 BYTE avgRed, avgGreen, avgBlue;
00578
00579 if (weight <= 0.0)
00580 return col1;
00581 else if (weight > 1.0)
00582 return col2;
00583
00584 avgRed = (BYTE) (GetRValue(col1) * weight + GetRValue(col2) * (1.0 - weight));
00585 avgGreen = (BYTE) (GetGValue(col1) * weight + GetGValue(col2) * (1.0 - weight));
00586 avgBlue = (BYTE) (GetBValue(col1) * weight + GetBValue(col2) * (1.0 - weight));
00587
00588 return RGB(avgRed, avgGreen, avgBlue);
00589 }
00590
00591 double ODMenu::GetColorIntensity(COLORREF col)
00592 {
00593 BYTE red, green, blue;
00594
00595 red = GetRValue(col);
00596 green = GetGValue(col);
00597 blue = GetBValue(col);
00598
00599
00600 return (double)red/765.0 + (double)green/765.0 + (double)blue/765.0;
00601 }
00602
00603 void ODMenu::MeasureItem(HWND hWnd, LPARAM lParam)
00604 {
00605 MEASUREITEMSTRUCT* lpmis = (MEASUREITEMSTRUCT*)lParam;
00606 ODMENUITEMS::iterator it;
00607 ODMENUITEM item;
00608 HDC hDC;
00609 HFONT hfntOld;
00610 RECT rect;
00611
00612 it = m_menuItems.find(lpmis->itemData);
00613 if(it == m_menuItems.end())
00614 return;
00615
00616 hDC = GetDC(hWnd);
00617 hfntOld = (HFONT)SelectObject(hDC, m_hFont);
00618
00619 item = it->second;
00620 if(item.displayText.length() > 0)
00621 {
00622 DrawText(hDC, item.rawText.c_str(), item.rawText.length(), &rect,
00623 DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
00624 lpmis->itemWidth = rect.right - rect.left;
00625
00626 if(!item.topMost)
00627 {
00628
00629 lpmis->itemWidth += (m_iconWidth + 2*m_iconBarMargin + m_textLeftMargin + m_textRightMargin);
00630 lpmis->itemHeight += m_verticalSpacing;
00631 }
00632 }
00633 else if(item.dwType & MFT_SEPARATOR)
00634 {
00635
00636 if(!item.topMost)
00637 {
00638 lpmis->itemWidth += (m_iconWidth + 2*m_iconBarMargin + m_textLeftMargin + m_textRightMargin);
00639 lpmis->itemHeight = 3;
00640 }
00641 }
00642
00643 SelectObject(hDC, hfntOld);
00644 ReleaseDC(hWnd, hDC);
00645 }
00646
00647 void ODMenu::DrawItem(HWND hWnd, LPARAM lParam)
00648 {
00649 DRAWITEMSTRUCT* lpdis = (DRAWITEMSTRUCT*)lParam;
00650 ODMENUITEMS::iterator it;
00651 ODMENUITEM item;
00652 COLORREF clrPrevText, clrPrevBkgnd;
00653 HFONT hPrevFnt;
00654 HPEN hPrevPen;
00655 HBRUSH hPrevBrush;
00656
00657 it = m_menuItems.find(lpdis->itemData);
00658 if(it == m_menuItems.end())
00659 return;
00660
00661 item = it->second;
00662
00663
00664 if(item.displayText.length() > 0)
00665 {
00666
00667 if(item.topMost)
00668 {
00669 if(lpdis->itemState & ODS_SELECTED)
00670 {
00671 clrPrevText = SetTextColor(lpdis->hDC, m_clrHighlightItemText);
00672 clrPrevBkgnd = SetBkColor(lpdis->hDC, m_clrHighlightItemBackground);
00673 }
00674 else
00675 {
00676 clrPrevText = SetTextColor(lpdis->hDC, m_clrItemText);
00677 clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor(COLOR_MENU));
00678 }
00679 }
00680 else
00681 {
00682 if(lpdis->itemState & ODS_GRAYED || lpdis->itemState & ODS_DISABLED)
00683 {
00684 clrPrevText = SetTextColor(lpdis->hDC, GetSysColor(COLOR_3DSHADOW));
00685 clrPrevBkgnd = SetBkColor(lpdis->hDC, m_clrItemBackground);
00686 }
00687 else if(lpdis->itemState & ODS_SELECTED)
00688 {
00689 clrPrevText = SetTextColor(lpdis->hDC, m_clrHighlightItemText);
00690 clrPrevBkgnd = SetBkColor(lpdis->hDC, m_clrHighlightItemBackground);
00691 }
00692 else
00693 {
00694 clrPrevText = SetTextColor(lpdis->hDC, m_clrItemText);
00695 clrPrevBkgnd = SetBkColor(lpdis->hDC, m_clrItemBackground);
00696 }
00697 }
00698
00699
00700 hPrevFnt = (HFONT)SelectObject(lpdis->hDC, m_hFont);
00701
00702
00703 DrawItemText(lpdis, item);
00704
00705
00706 SelectObject(lpdis->hDC, hPrevFnt);
00707
00708 SetTextColor(lpdis->hDC, clrPrevText);
00709 SetBkColor(lpdis->hDC, clrPrevBkgnd);
00710 }
00711 else if(item.dwType & MFT_SEPARATOR)
00712 {
00713
00714 RECT rect;
00715 memcpy(&rect, &lpdis->rcItem, sizeof(RECT));
00716 rect.left += (m_iconWidth + 2*m_iconBarMargin);
00717 FillRect(lpdis->hDC, &rect, m_hItemBackground);
00718
00719
00720 hPrevPen = (HPEN)SelectObject(lpdis->hDC, m_hSeparatorPen);
00721 MoveToEx(lpdis->hDC, lpdis->rcItem.left + m_iconWidth + 2*m_iconBarMargin + m_textLeftMargin,
00722 lpdis->rcItem.top+1, NULL);
00723 LineTo(lpdis->hDC, lpdis->rcItem.right, lpdis->rcItem.top+1);
00724
00725
00726 SelectObject(lpdis->hDC, hPrevPen);
00727 }
00728
00729
00730 DrawIconBar(lpdis, item);
00731
00732
00733 if(lpdis->itemState & ODS_SELECTED && !(lpdis->itemState & ODS_GRAYED || lpdis->itemState & ODS_DISABLED))
00734 {
00735 hPrevBrush = (HBRUSH)SelectObject(lpdis->hDC, (HBRUSH)GetStockObject(NULL_BRUSH));
00736 hPrevPen = (HPEN)SelectObject(lpdis->hDC, m_hSelectionOutlinePen);
00737 Rectangle(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top,
00738 lpdis->rcItem.right, lpdis->rcItem.bottom);
00739
00740
00741 SelectObject(lpdis->hDC, hPrevBrush);
00742 SelectObject(lpdis->hDC, hPrevPen);
00743 }
00744 }
00745
00746 void ODMenu::OnDestroy()
00747 {
00748 }
00749
00750 bool ODMenu::GetItem(UINT id, ODMENUITEM** ppItem)
00751 {
00752 bool bRC = true;
00753
00754 if(!ppItem)
00755 return false;
00756
00757 ODMENUITEMS::iterator it = m_menuItems.find(id);
00758 if(it != m_menuItems.end())
00759 *ppItem = &it->second;
00760
00761 return bRC;
00762 }
00763
00764 void ODMenu::SetItemImage(HINSTANCE hInst, UINT wID, UINT idBitmap)
00765 {
00766
00767 ODMENUITEMS::iterator it;
00768 HBITMAP hBitmap;
00769
00770
00771 hBitmap = (HBITMAP) LoadImage(hInst,
00772 MAKEINTRESOURCE(idBitmap),
00773 IMAGE_BITMAP, 0, 0, LR_SHARED);
00774 if (hBitmap)
00775 {
00776
00777 it = m_menuItems.begin();
00778 while(it != m_menuItems.end())
00779 {
00780 if(it->second.wID == wID)
00781 {
00782 it->second.hBitmap = hBitmap;
00783 break;
00784 }
00785
00786 it++;
00787 }
00788 }
00789 else
00790 {
00791 DWORD dwErr = GetLastError();
00792 dwErr = 0;
00793 }
00794 }
00795
00796 void ODMenu::AddItem(HMENU hMenu, int index, MENUITEMINFO* pItemInfo)
00797 {
00798 MENUITEMINFO miInfo;
00799 ODMENUITEM odInfo;
00800
00801
00802 if(!pItemInfo)
00803 {
00804 miInfo.cbSize = sizeof(MENUITEMINFO);
00805 miInfo.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;
00806 miInfo.dwTypeData = m_szItemText;
00807 miInfo.cch = sizeof(m_szItemText);
00808
00809 if(GetMenuItemInfo(hMenu, index, TRUE, &miInfo))
00810 pItemInfo = &miInfo;
00811 }
00812
00813
00814 if(pItemInfo)
00815 {
00816 if(pItemInfo->hSubMenu != NULL && hMenu == m_hRootMenu)
00817 odInfo.topMost = true;
00818 else
00819 odInfo.topMost = false;
00820 if(pItemInfo->fType == MFT_STRING)
00821 {
00822 odInfo.rawText = pItemInfo->dwTypeData;
00823 GenerateDisplayText(odInfo);
00824 }
00825 else
00826 {
00827 odInfo.rawText = "";
00828 odInfo.displayText = "";
00829 }
00830 odInfo.dwType = pItemInfo->fType;
00831 odInfo.wID = pItemInfo->wID;
00832 odInfo.hBitmap = NULL;
00833 m_menuItems[m_seqNumber] = odInfo;
00834 SetMenuItemOwnerDrawn(hMenu, index, pItemInfo->fType);
00835 }
00836 }
00837
00838 void ODMenu::DeleteItem(HMENU hMenu, int index)
00839 {
00840
00841 MENUITEMINFO miInfo;
00842
00843 miInfo.cbSize = sizeof(MENUITEMINFO);
00844 miInfo.fMask = MIIM_SUBMENU | MIIM_DATA;
00845 if(GetMenuItemInfo(hMenu, index, TRUE, &miInfo))
00846 {
00847 if(miInfo.hSubMenu)
00848 DeleteSubMenu(miInfo.hSubMenu);
00849
00850
00851 m_menuItems.erase(miInfo.dwItemData);
00852 }
00853 }