MenuSpawn.cpp
上传用户:pasef_zww
上传日期:2007-01-02
资源大小:109k
文件大小:18k
源码类别:

菜单

开发平台:

Visual C++

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