GfxPopupMenu.cpp
上传用户:zslianheng
上传日期:2013-04-03
资源大小:946k
文件大小:19k
源码类别:

Linux/Unix编程

开发平台:

Visual C++

  1. // GfxPopupMenu.cpp: implementation of the CGfxPopupMenu class.
  2. //
  3. // Modified a lot by Zhang Yong
  4. //////////////////////////////////////////////////////////////////////
  5. #include "stdafx.h"
  6. #include "GfxPopupMenu.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. CGfxPopupMenu::CGfxPopupMenu()
  16. {
  17. crMenuText = GetSysColor(COLOR_MENUTEXT);
  18. crMenuTextSel = GetSysColor(COLOR_HIGHLIGHTTEXT);
  19. cr3dFace = GetSysColor(COLOR_3DFACE);
  20. crMenu = GetSysColor(COLOR_MENU);
  21. crHighlight = GetSysColor(COLOR_HIGHLIGHT);
  22. cr3dHilight = GetSysColor(COLOR_3DHILIGHT);
  23. cr3dShadow = GetSysColor(COLOR_3DSHADOW);
  24. crGrayText = GetSysColor(COLOR_GRAYTEXT);
  25. m_clrBtnFace = GetSysColor(COLOR_BTNFACE);
  26. m_clrBtnHilight = GetSysColor(COLOR_BTNHILIGHT);
  27. m_clrBtnShadow = GetSysColor(COLOR_BTNSHADOW);
  28. iSpawnItem = 0;
  29. pSpawnItem = NULL;
  30. iImageItem = 0;
  31. pImageItem = NULL;
  32. hMenuFont = NULL;
  33. /* COLORMAP cMap[3] = { 
  34. { RGB(128,128,128), cr3dShadow }, 
  35. { RGB(192,192,192), cr3dFace }, 
  36. { RGB(255,255,255), cr3dHilight }
  37. };
  38. CBitmap bmp;
  39. bmp.LoadMappedBitmap(IDB_MENUCHK, 0, cMap, 3);
  40. ilOther.Create(19, 19, ILC_COLOR4|ILC_MASK, 1, 0);
  41. ilOther.Add(&bmp, cr3dFace);
  42. bmp.DeleteObject();
  43. */
  44. NONCLIENTMETRICS ncm;
  45. memset(&ncm, 0, sizeof(ncm));
  46. ncm.cbSize = sizeof(ncm);
  47. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0);
  48. hGuiFont = ::CreateFontIndirect(&ncm.lfMenuFont);
  49. // David 08/04/98 - start - bold font handling
  50. hMenuBoldFont = NULL;
  51. CreateBoldFont();
  52. // David 08/04/98 - end - bold font handling
  53. ilList.Create(16, 16, ILC_MASK | ILC_COLOR8, 5, 15);
  54. szImage = CSize(16, 16);
  55. // @@
  56. vertDrawn = FALSE;
  57. }
  58. CGfxPopupMenu::~CGfxPopupMenu()
  59. {
  60. if (iSpawnItem > 0)
  61. {
  62. for (int t = 0; t < iSpawnItem; t++)
  63. if (pSpawnItem[t]) delete pSpawnItem[t];
  64. GlobalFree((HGLOBAL) pSpawnItem);
  65. }
  66. if (iImageItem > 0)
  67. {
  68. GlobalFree((HGLOBAL) pImageItem);
  69. }
  70. if (hMenuFont) ::DeleteObject((HGDIOBJ)hMenuFont);
  71. if (hMenuBoldFont) ::DeleteObject((HGDIOBJ)hMenuBoldFont);
  72. }
  73. void CGfxPopupMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  74. {
  75. // CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  76. // CRect rcItem(lpDrawItemStruct->rcItem);
  77. // pDC->FillSolidRect(rcItem, RGB(255,0,0));
  78. if (lpDrawItemStruct->CtlType == ODT_MENU)
  79. {
  80. UINT id = lpDrawItemStruct->itemID;
  81. UINT state = lpDrawItemStruct->itemState;
  82. bool bEnab = !(state & ODS_DISABLED);
  83. bool bSelect = (state & ODS_SELECTED) ? true : false;
  84. bool bChecked = (state & ODS_CHECKED) ? true : false;
  85. // David 08/04/98 - start - bold font handling
  86. bool bBold = (state & ODS_DEFAULT) ? true : false;
  87. // David 08/04/98 - end - bold font handling
  88. SpawnItem * pItem = (SpawnItem *) lpDrawItemStruct->itemData;
  89. if (pItem)
  90. {
  91. CDC * pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  92. CFont * pft;
  93. // David 08/04/98 - start - bold font handling
  94. if (!bBold) pft = CFont::FromHandle((HFONT) hMenuFont ? hMenuFont : hGuiFont);
  95. else pft = CFont::FromHandle((HFONT) hMenuBoldFont ? hMenuBoldFont : hGuiFont);
  96. // David 08/04/98 - end - bold font handling
  97. CFont * of = pDC->SelectObject(pft);
  98. CRect rc(lpDrawItemStruct->rcItem);
  99. // @@
  100. if (bmVert.m_hObject) {
  101. BITMAP bm;
  102. bmVert.GetBitmap(&bm);
  103. if ((lpDrawItemStruct->itemAction & ODA_DRAWENTIRE) && !vertDrawn) {
  104. vertDrawn = TRUE;
  105. CDC dcMem;
  106. dcMem.CreateCompatibleDC(pDC);
  107. CBitmap *bmOld = dcMem.SelectObject(&bmVert);
  108. pDC->SelectClipRgn(NULL);
  109. CRect rcWhole;
  110. pDC->GetClipBox(rcWhole);
  111. pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem,
  112. 0, bm.bmHeight - rcWhole.Height(), SRCCOPY);
  113. }
  114. rc.left += bm.bmWidth;
  115. }
  116. CRect rcImage(rc), rcText(rc);
  117. rcImage.right = rcImage.left + rc.Height();
  118. rcImage.bottom = rc.bottom;
  119. if (pItem->iCmd == -3) // is a separator
  120. {
  121. CPen pnDk(PS_SOLID,1,cr3dShadow);
  122. CPen pnLt(PS_SOLID,1,cr3dHilight);
  123. CPen * opn = pDC->SelectObject(&pnDk);
  124. pDC->MoveTo(rc.left + 2, rc.top + 2);
  125. pDC->LineTo(rc.right - 2, rc.top + 2);
  126. pDC->SelectObject(&pnLt);
  127. pDC->MoveTo(rc.left + 2, rc.top + 3);
  128. pDC->LineTo(rc.right - 2, rc.top + 3);
  129. pDC->SelectObject(opn);
  130. }
  131. /* else if (pItem->iCmd == -4) // is a title item
  132. {
  133. CString cs(pItem->cText), cs1;
  134. CRect rcBdr(rcText);
  135. if (bSelect && bEnab)
  136. {
  137. rcText.top ++;
  138. rcText.left += 2;
  139. }
  140. pDC->FillSolidRect(rcText, crMenu);
  141. pDC->DrawText(cs, rcText, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
  142. if (bSelect && bEnab) pDC->Draw3dRect(rcBdr,cr3dShadow,cr3dHilight);
  143. }*/
  144. else
  145. {
  146. rcText.left = rcImage.right + 1;
  147. int obk = pDC->SetBkMode(TRANSPARENT);
  148. COLORREF ocr;
  149. if (bSelect)
  150. {
  151. if (pItem->iImageIdx >= 0 || (state & ODS_CHECKED))
  152. //pDC->FillSolidRect(rcText, crHighlight);
  153. pDC->Draw3dRect(rcText, cr3dShadow, cr3dHilight); // @@
  154. else
  155. //pDC->FillSolidRect(rc, crHighlight);
  156. pDC->Draw3dRect(rc, cr3dShadow, cr3dHilight); // @@
  157. //ocr = pDC->SetTextColor(crMenuTextSel);
  158. ocr = pDC->SetTextColor(crHighlight); // @@
  159. }
  160. else
  161. {
  162. if (pItem->iImageIdx >= 0 || (state & ODS_CHECKED))
  163. pDC->FillSolidRect(rcText, crMenu);
  164. else
  165. pDC->FillSolidRect(rc/*rcText*/, crMenu);
  166. ocr = pDC->SetTextColor(crMenuText);
  167. }
  168. if (pItem->iImageIdx >= 0)
  169. {
  170. int ay = (rcImage.Height() - szImage.cy) / 2;
  171. int ax = (rcImage.Width()  - szImage.cx) / 2;
  172. if (bSelect && bEnab)
  173. pDC->Draw3dRect(rcImage,cr3dHilight,cr3dShadow);
  174. else
  175. {
  176. pDC->Draw3dRect(rcImage,crMenu,crMenu);
  177. }
  178. if (bEnab)
  179. {
  180. ilList.Draw(pDC, pItem->iImageIdx, CPoint(rcImage.left + ax, rcImage.top +ay), ILD_NORMAL);
  181. }
  182. else
  183. {
  184. HICON hIcon = ilList.ExtractIcon( pItem->iImageIdx );
  185. pDC->DrawState( CPoint(rcImage.left + ax, rcImage.top + ay ), szImage, (HICON)hIcon, DST_ICON | DSS_DISABLED, (CBrush *)NULL );
  186. }
  187. }
  188. else
  189. {
  190. if (bChecked)
  191. {
  192. int ay = (rcImage.Height() - szImage.cy) / 2;
  193. int ax = (rcImage.Width()  - szImage.cx) / 2;
  194. ilOther.Draw(pDC, 0, CPoint(rcImage.left + ax, rcImage.top + ay - 2), ILD_NORMAL);
  195. }
  196. }
  197. CString cs(pItem->cText), cs1;
  198. if (cs.Compare("dummy") == 0)
  199. pItem = pItem;
  200. CSize sz;
  201. sz = pDC->GetTextExtent(cs);
  202. int ay1 = (rcText.Height() - sz.cy) / 2;
  203. rcText.top += ay1;
  204. rcText.left += 2;
  205. rcText.right -= 15;
  206. int tf = cs.Find('t');
  207. if (tf >= 0)
  208. {
  209. cs1 = cs.Right(cs.GetLength() - tf - 1);
  210. cs = cs.Left(tf);
  211. if (!bEnab)
  212. {
  213. if (!bSelect)
  214. {
  215. CRect rcText1(rcText);
  216. rcText1.InflateRect(-1,-1);
  217. pDC->SetTextColor(cr3dHilight);
  218. pDC->DrawText(cs, rcText1, DT_VCENTER|DT_LEFT);
  219. pDC->DrawText(cs1, rcText1, DT_VCENTER|DT_RIGHT);
  220. pDC->SetTextColor(crGrayText);
  221. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT);
  222. pDC->DrawText(cs1, rcText, DT_VCENTER|DT_RIGHT);
  223. }
  224. else
  225. {
  226. pDC->SetTextColor(crMenu);
  227. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT);
  228. pDC->DrawText(cs1, rcText, DT_VCENTER|DT_RIGHT);
  229. }
  230. }
  231. else
  232. {
  233. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT);
  234. pDC->DrawText(cs1, rcText, DT_VCENTER|DT_RIGHT);
  235. }
  236. }
  237. else 
  238. {
  239. if (!bEnab)
  240. {
  241. // if (!bSelect) // @@
  242. {
  243. CRect rcText1(rcText);
  244. rcText1.InflateRect(-1,-1);
  245. pDC->SetTextColor(cr3dHilight);
  246. pDC->DrawText(cs, rcText1, DT_VCENTER|DT_LEFT|DT_EXPANDTABS);
  247. pDC->SetTextColor(crGrayText);
  248. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT|DT_EXPANDTABS);
  249. }
  250. /* else
  251. {
  252. pDC->SetTextColor(crMenu);
  253. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT|DT_EXPANDTABS);
  254. }*/
  255. }
  256. else
  257. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT|DT_EXPANDTABS);
  258. }
  259. pDC->SetTextColor(ocr);
  260. pDC->SetBkMode(obk);
  261. }
  262. pDC->SelectObject(of);
  263. }
  264. }
  265. }
  266. void CGfxPopupMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
  267. {
  268. // lpMeasureItemStruct->itemWidth = 200;
  269. // lpMeasureItemStruct->itemHeight = 25;
  270. bool res = false;
  271. if (lpMeasureItemStruct->CtlType == ODT_MENU)
  272. {
  273. UINT id = lpMeasureItemStruct->itemID;
  274. SpawnItem * pItem = (SpawnItem *) lpMeasureItemStruct->itemData;
  275. if (pItem)
  276. {
  277. if (pItem->iCmd == -3) // is a separator
  278. {
  279. lpMeasureItemStruct->itemWidth  = 10;
  280. lpMeasureItemStruct->itemHeight = 6;
  281. }
  282. else
  283. {
  284. CString cs(pItem->cText);
  285. if (!cs.IsEmpty())
  286. {
  287. CClientDC dc(AfxGetMainWnd());
  288. CFont * pft = CFont::FromHandle(hMenuFont ? hMenuFont : hGuiFont);
  289. CFont * of = dc.SelectObject(pft);
  290. CSize osz = dc.GetOutputTabbedTextExtent(cs,0,NULL);
  291. // @@
  292. /*if (pItem->iCmd == -4)
  293. {
  294. CRect rci(0,0,0,0);
  295. dc.DrawText(cs, rci, DT_CALCRECT|DT_TOP|DT_VCENTER|DT_SINGLELINE);
  296. lpMeasureItemStruct->itemHeight = rci.Height();
  297. lpMeasureItemStruct->itemWidth = rci.Width();
  298. }
  299. else*/
  300. {
  301. lpMeasureItemStruct->itemHeight = szImage.cy + 5;
  302. if (osz.cy > (int) lpMeasureItemStruct->itemHeight) lpMeasureItemStruct->itemHeight = (int) osz.cy;
  303. lpMeasureItemStruct->itemWidth  = osz.cx + 2 + 15;
  304. lpMeasureItemStruct->itemWidth += lpMeasureItemStruct->itemHeight > (UINT) szImage.cx ? (UINT) lpMeasureItemStruct->itemHeight : (UINT) szImage.cx;
  305. }
  306. dc.SelectObject(of);
  307. }
  308. else
  309. {
  310. lpMeasureItemStruct->itemHeight = szImage.cy + 5;
  311. lpMeasureItemStruct->itemWidth  = 100;
  312. }
  313. }
  314. if (bmVert.m_hObject) {
  315. BITMAP bm;
  316. bmVert.GetBitmap(&bm);
  317. lpMeasureItemStruct->itemWidth += bm.bmWidth;
  318. }
  319. }
  320. }
  321. }
  322. bool CGfxPopupMenu::CreateBoldFont()
  323. {
  324. if (hMenuBoldFont) 
  325. ::DeleteObject((HGDIOBJ)hMenuBoldFont);
  326. LOGFONT lgFont;
  327. ::GetObject (hMenuFont ? hMenuFont : hGuiFont, sizeof (lgFont), &lgFont);
  328. lgFont.lfWeight = FW_BOLD;
  329. hMenuBoldFont = CreateFontIndirect (&lgFont);
  330. return !!hMenuBoldFont;
  331. }
  332. bool CGfxPopupMenu::AddToolBarResource(unsigned int resId)
  333. {
  334. // David 08/04/98 - start - put CMenuSpawn in DLL
  335. HINSTANCE hInst = AfxFindResourceHandle (MAKEINTRESOURCE(resId), RT_TOOLBAR);
  336. if (!hInst)
  337. return false;
  338. // David 08/04/98 - end - put CMenuSpawn in DLL
  339. HRSRC hRsrc = ::FindResource(/*AfxGetResourceHandle()*/hInst, MAKEINTRESOURCE(resId), RT_TOOLBAR);
  340. if (hRsrc == NULL) return false;
  341. HGLOBAL hGlb = ::LoadResource(/*AfxGetResourceHandle()*/hInst, hRsrc);
  342. if (hGlb == NULL) return false;
  343. ToolBarData* pTBData = (ToolBarData*) ::LockResource(hGlb);
  344. if (pTBData == NULL) return false;
  345. ASSERT(pTBData->wVersion == 1);
  346. CBitmap bmp;
  347. bmp.LoadBitmap(resId);
  348. int nBmpItems = ilList.Add(&bmp, RGB(192,192,192));
  349. bmp.DeleteObject();
  350. WORD* pItem = (WORD*)(pTBData+1);
  351. for(int i=0; i<pTBData->wItemCount; i++, pItem++)
  352. {
  353. if(*pItem != ID_SEPARATOR)
  354. AddImageItem(nBmpItems++, (WORD) *pItem);
  355. }
  356. // ** it seem that Windows doesn't free these resource (from Heitor Tome)
  357.     ::UnlockResource(hGlb);
  358.     ::FreeResource(hGlb);
  359. // **
  360. return true;
  361. }
  362. bool CGfxPopupMenu::LoadToolBarResource(unsigned int resId)
  363. {
  364. //David 08/04/98 - start - put CMenuSpawn in DLL
  365. HINSTANCE hInst = AfxFindResourceHandle (MAKEINTRESOURCE(resId), RT_TOOLBAR);
  366. if (!hInst)
  367. return false;
  368. //David 08/04/98 - end - put CMenuSpawn in DLL
  369. HRSRC hRsrc = ::FindResource(/*AfxGetResourceHandle()*/hInst, MAKEINTRESOURCE(resId), RT_TOOLBAR);
  370. if (hRsrc == NULL) return false;
  371. HGLOBAL hGlb = ::LoadResource(/*AfxGetResourceHandle()*/hInst, hRsrc);
  372. if (hGlb == NULL) return false;
  373. ToolBarData* pTBData = (ToolBarData*) ::LockResource(hGlb);
  374. if (pTBData == NULL) return false;
  375. ASSERT(pTBData->wVersion == 1);
  376. szImage.cx = (int) pTBData->wWidth;
  377. szImage.cy = (int) pTBData->wHeight;
  378. if (ilList.Create(szImage.cx, szImage.cy, ILC_COLOR4|ILC_MASK, pTBData->wItemCount, 0) == false)
  379. return false;
  380. ilList.SetBkColor(cr3dFace);
  381. CBitmap bmp;
  382. bmp.LoadBitmap(resId);
  383. ilList.Add(&bmp, RGB(192,192,192));
  384. bmp.DeleteObject();
  385. WORD* pItem = (WORD*)(pTBData+1);
  386. int nBmpItems = 0;
  387. for(int i=0; i<pTBData->wItemCount; i++, pItem++)
  388. {
  389. if(*pItem != ID_SEPARATOR)
  390. AddImageItem(nBmpItems++, (WORD) *pItem);
  391. }
  392. // ** it seem that Windows doesn't free these resource (from Heitor Tome)
  393.     ::UnlockResource(hGlb);
  394.     ::FreeResource(hGlb);
  395. // **
  396. return true;
  397. }
  398. void CGfxPopupMenu::AddImageItem(const int idx, WORD cmd)
  399. {
  400. if (iImageItem == 0)
  401. pImageItem = (ImageItem *) GlobalAlloc(GPTR, sizeof(ImageItem));
  402. else
  403. pImageItem = (ImageItem *) GlobalReAlloc((HGLOBAL) pImageItem, sizeof(ImageItem) * (iImageItem + 1), GMEM_MOVEABLE|GMEM_ZEROINIT);
  404. ASSERT(pImageItem);
  405. pImageItem[iImageItem].iCmd = (int) cmd;
  406. pImageItem[iImageItem].iImageIdx = idx;
  407. iImageItem ++;
  408. }
  409. void CGfxPopupMenu::RemapMenu(CMenu * pMenu)
  410. {
  411. static int iRecurse = 0;
  412. iRecurse ++;
  413. ASSERT(pMenu);
  414. int nItem = pMenu->GetMenuItemCount();
  415. while ((--nItem)>=0)
  416. {
  417. UINT itemId = pMenu->GetMenuItemID(nItem);
  418. if (itemId == (UINT) -1)
  419. {
  420. CMenu *pops = pMenu->GetSubMenu(nItem);
  421. if (pops)
  422. RemapMenu(pops);
  423. if (iRecurse > 0)
  424. {
  425. CString cs;
  426. pMenu->GetMenuString(nItem, cs, MF_BYPOSITION);
  427. if (cs != "")
  428. {
  429. SpawnItem * sp = AddSpawnItem(cs, (iRecurse == 1) ? -4 : -2);
  430. pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW, (UINT) -1, (LPCTSTR)sp);
  431. }
  432. }
  433. }
  434. else
  435. {
  436. if (itemId != 0)
  437. {
  438. UINT oldState = pMenu->GetMenuState(nItem,MF_BYPOSITION);
  439. if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
  440. {
  441. ASSERT(oldState != (UINT)-1);
  442. CString cs;
  443. pMenu->GetMenuString(nItem, cs, MF_BYPOSITION);
  444. SpawnItem * sp = AddSpawnItem(cs, itemId);
  445. pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
  446. }
  447. }
  448. else
  449. {
  450. UINT oldState = pMenu->GetMenuState(nItem,MF_BYPOSITION);
  451. if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
  452. {
  453. ASSERT(oldState != (UINT)-1);
  454. SpawnItem * sp = AddSpawnItem("--", -3);
  455. pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
  456. }
  457. }
  458. }
  459. }
  460. iRecurse --;
  461. }
  462. CGfxPopupMenu::SpawnItem * CGfxPopupMenu::AddSpawnItem(const char * txt, const int cmd)
  463. {
  464. if (iSpawnItem == 0)
  465. pSpawnItem = (SpawnItem **) GlobalAlloc(GPTR, sizeof(SpawnItem));
  466. else
  467. pSpawnItem = (SpawnItem **) GlobalReAlloc((HGLOBAL) pSpawnItem, sizeof(SpawnItem) * (iSpawnItem + 1), GMEM_MOVEABLE|GMEM_ZEROINIT);
  468. ASSERT(pSpawnItem);
  469. SpawnItem * p = new SpawnItem;
  470. ASSERT(p);
  471. pSpawnItem[iSpawnItem] = p;
  472. lstrcpy(p->cText, txt);
  473. p->iCmd = cmd;
  474. if (cmd >= 0) p->iImageIdx = FindImageItem(cmd);
  475. else p->iImageIdx = cmd;
  476. iSpawnItem ++;
  477. return p;
  478. }
  479. int CGfxPopupMenu::FindImageItem(const int cmd)
  480. {
  481. for (int t = 0; t < iImageItem; t++)
  482. if (pImageItem[t].iCmd == cmd) return pImageItem[t].iImageIdx;
  483. return -1;
  484. }
  485. void CGfxPopupMenu::EnableMenuItems(CMenu * pMenu, CWnd * pParent)
  486. {
  487. ASSERT(pMenu);
  488. ASSERT(pParent);
  489. int nItem = pMenu->GetMenuItemCount();
  490. CCmdUI state;
  491. state.m_pMenu = pMenu;
  492. state.m_nIndex = nItem-1;
  493. state.m_nIndexMax = nItem;
  494. while ((--nItem)>=0)
  495. {
  496. UINT itemId = pMenu->GetMenuItemID(nItem);
  497. if (itemId == (UINT) -1)
  498. {
  499. CMenu *pops = pMenu->GetSubMenu(nItem);
  500. if (pops) EnableMenuItems(pops, pParent);
  501. }
  502. else
  503. {
  504. if (itemId != 0)
  505. {
  506. state.m_nID = itemId;
  507. pParent->OnCmdMsg(itemId, CN_UPDATE_COMMAND_UI, &state, NULL);
  508. state.DoUpdate(pParent, true);
  509. }
  510. }
  511. state.m_nIndex = nItem-1;
  512. }
  513. }
  514. void CGfxPopupMenu::modifyMenu(UINT itemId, UINT bitmap, BOOL byCmd)
  515. {
  516. int index;
  517. if (!imageHash.Lookup(bitmap, index)) {
  518. CBitmap bm;
  519. bm.LoadBitmap(bitmap);
  520. index = ilList.Add(&bm, RGB(192, 192, 192));
  521. imageHash.SetAt(bitmap, index);
  522. }
  523. modifyMenuInternal(itemId, index, byCmd);
  524. }
  525. void CGfxPopupMenu::modifyMenu(UINT itemId, HICON icon)
  526. {
  527. int index;
  528. if (!bitmapHash.Lookup(icon, index)) {
  529. index = ilList.Add(icon);
  530. bitmapHash.SetAt(icon, index);
  531. }
  532. modifyMenuInternal(itemId, index, TRUE);
  533. }
  534. void CGfxPopupMenu::modifyMenuInternal(UINT itemId, int imageIndex, BOOL byCmd)
  535. {
  536. if (byCmd) {
  537. UINT oldState = GetMenuState(itemId,MF_BYCOMMAND);
  538. if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
  539. {
  540. ASSERT(oldState != (UINT)-1);
  541. CString cs;
  542. GetMenuString(itemId, cs, MF_BYCOMMAND);
  543. SpawnItem * sp = AddSpawnItem(cs, itemId);
  544. sp->iImageIdx = imageIndex;
  545. ModifyMenu(itemId,MF_BYCOMMAND|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
  546. }
  547. } else {
  548. UINT nItem = itemId;
  549. itemId = GetMenuItemID(nItem);
  550. if (itemId == (UINT) -1)
  551. {
  552. CString cs;
  553. GetMenuString(nItem, cs, MF_BYPOSITION);
  554. if (cs != "")
  555. {
  556. SpawnItem * sp = AddSpawnItem(cs, -4);
  557. sp->iImageIdx = imageIndex;
  558. ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW, (UINT) -1, (LPCTSTR)sp);
  559. }
  560. }
  561. else
  562. {
  563. if (itemId != 0)
  564. {
  565. UINT oldState = GetMenuState(nItem,MF_BYPOSITION);
  566. if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
  567. {
  568. ASSERT(oldState != (UINT)-1);
  569. CString cs;
  570. GetMenuString(nItem, cs, MF_BYPOSITION);
  571. SpawnItem * sp = AddSpawnItem(cs, itemId);
  572. sp->iImageIdx = imageIndex;
  573. ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
  574. }
  575. }
  576. else
  577. {
  578. UINT oldState = GetMenuState(nItem,MF_BYPOSITION);
  579. if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
  580. {
  581. ASSERT(oldState != (UINT)-1);
  582. SpawnItem * sp = AddSpawnItem("--", -3);
  583. ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
  584. }
  585. }
  586. }
  587. }
  588. }
  589. void CGfxPopupMenu::appendMenu(UINT id, UINT bitmap, LPCTSTR str)
  590. {
  591. AppendMenu(MF_BYCOMMAND, id, str);
  592. modifyMenu(id, bitmap);
  593. }
  594. void CGfxPopupMenu::appendMenu(UINT id, UINT bitmap, UINT strID)
  595. {
  596. CString str;
  597. str.LoadString(strID);
  598. appendMenu(id, bitmap, str);
  599. }
  600. void CGfxPopupMenu::setVertBitmap(UINT bitmap)
  601. {
  602. for (int i = GetMenuItemCount() - 1; i >= 0; i--) {
  603. if (GetMenuItemID(i) == 0) {
  604. SpawnItem * sp = AddSpawnItem("--", -3);
  605. ModifyMenu(i, MF_BYPOSITION | MF_OWNERDRAW | MF_SEPARATOR, 0, (LPCTSTR) sp);
  606. }
  607. }
  608. bmVert.LoadBitmap(bitmap);
  609. }