MenuSpawn.cpp
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:23k
源码类别:

P2P编程

开发平台:

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. #define COLOR_MENUBAR 30
  13. #define SPI_GETFLATMENU 0x1022
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. HFONT CMenuSpawn::hMenuFont = NULL;
  18. HFONT CMenuSpawn::hGuiFont = NULL;
  19. COLORREF CMenuSpawn::crMenuText = 0;
  20. COLORREF CMenuSpawn::crMenuTextSel = 0;
  21. COLORREF CMenuSpawn::cr3dFace = 0;
  22. COLORREF CMenuSpawn::crMenu = 0;
  23. COLORREF CMenuSpawn::crHighlight = 0;
  24. COLORREF CMenuSpawn::cr3dHilight = 0;
  25. COLORREF CMenuSpawn::cr3dShadow = 0;
  26. COLORREF CMenuSpawn::crGrayText = 0;
  27. COLORREF CMenuSpawn::crMenuTitle = 0;
  28. COLORREF CMenuSpawn::m_clrBtnFace = 0;
  29. COLORREF CMenuSpawn::m_clrBtnHilight = 0;
  30. COLORREF CMenuSpawn::m_clrBtnShadow = 0;
  31. vector<CImageList*> CMenuSpawn::m_vImageList;
  32. void CMenuSpawn::OnSystemColorChange()
  33. {
  34. if (hMenuFont)
  35. ::DeleteObject((HGDIOBJ)hMenuFont);
  36. if (hGuiFont)
  37. ::DeleteObject((HGDIOBJ)hGuiFont);
  38. //
  39. // decide whether it is flat menu.
  40. //
  41. BOOL bFlat = false;
  42. BOOL bRet = SystemParametersInfo(SPI_GETFLATMENU, 0, &bFlat, 0);
  43. if (!bRet) bFlat = false;
  44. if (bFlat)
  45. crMenuTitle = GetSysColor(COLOR_MENUBAR);
  46. else
  47. crMenuTitle = GetSysColor(COLOR_MENU);
  48. crMenuText = GetSysColor(COLOR_MENUTEXT);
  49. crMenuTextSel = GetSysColor(COLOR_HIGHLIGHTTEXT);
  50. cr3dFace = GetSysColor(COLOR_3DFACE);
  51. crMenu = GetSysColor(COLOR_MENU);
  52. crHighlight = GetSysColor(COLOR_HIGHLIGHT);
  53. cr3dHilight = GetSysColor(COLOR_3DHILIGHT);
  54. cr3dShadow = GetSysColor(COLOR_3DSHADOW);
  55. crGrayText = GetSysColor(COLOR_GRAYTEXT);
  56. m_clrBtnFace = GetSysColor(COLOR_BTNFACE);
  57. m_clrBtnHilight = GetSysColor(COLOR_BTNHILIGHT);
  58. m_clrBtnShadow = GetSysColor(COLOR_BTNSHADOW);
  59. NONCLIENTMETRICS ncm;
  60. memset(&ncm, 0, sizeof(ncm));
  61. ncm.cbSize = sizeof(ncm);
  62. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0);
  63. hGuiFont = ::CreateFontIndirect(&ncm.lfMenuFont);
  64. hMenuFont = NULL;
  65. /*
  66. for (int i=0; i<m_vImageList.size();i++)
  67. {
  68. if (m_vImageList[i]->GetSafeHandle())
  69. {
  70. m_vImageList[i]->SetBkColor(crMenu);
  71. }
  72. }
  73. //*/
  74. }
  75. CMenuSpawn::CMenuSpawn()
  76. {
  77. Init();
  78. m_iNormalImgInx = -1;
  79. }
  80. CMenuSpawn::CMenuSpawn(const bool _IsPopup)
  81. {
  82. Init();
  83. bIsPopup = _IsPopup;
  84. m_vImageList.push_back(&ilList);
  85. m_vImageList.push_back(&ilDisabledList);
  86. }
  87. CMenuSpawn::~CMenuSpawn()
  88. {
  89. vector<CImageList*>::iterator iter = find(m_vImageList.begin(), m_vImageList.end(), &ilList);
  90. if (iter != m_vImageList.end())
  91. m_vImageList.erase(iter);
  92. iter = find(m_vImageList.begin(), m_vImageList.end(), &ilDisabledList);
  93. if (iter != m_vImageList.end())
  94. m_vImageList.erase(iter);
  95. Clear();
  96. // if (hGuiFont) ::DeleteObject((HGDIOBJ)hGuiFont);
  97. }
  98. void CMenuSpawn::Clear()
  99. {
  100. if (iSpawnItem > 0)
  101. {
  102. for (int t = 0; t < iSpawnItem; t++)
  103. if (pSpawnItem[t]) delete pSpawnItem[t];
  104. GlobalFree((HGLOBAL) pSpawnItem);
  105. }
  106. iSpawnItem = 0;
  107. pSpawnItem = NULL;
  108. if (iImageItem > 0)
  109. {
  110. GlobalFree((HGLOBAL) pImageItem);
  111. }
  112. iImageItem = 0;
  113. pImageItem = NULL;
  114. if (hMenuFont)
  115. ::DeleteObject((HGDIOBJ)hMenuFont);
  116. if (ilList)
  117. {
  118. BOOL bRet = ilList.DeleteImageList();
  119. ASSERT(bRet);
  120. }
  121. if (ilDisabledList)
  122. {
  123. BOOL bRet = ilDisabledList.DeleteImageList();
  124. ASSERT(bRet);
  125. }
  126. }
  127. void CMenuSpawn::Init()
  128. {
  129. ASSERT(hGuiFont);
  130. //
  131. // decide whether it is flat menu.
  132. //
  133. /*
  134. BOOL bFlat = false;
  135. BOOL bRet = SystemParametersInfo(SPI_GETFLATMENU, 0, &bFlat, 0);
  136. if (!bRet) bFlat = false;
  137. if (bFlat)
  138. crMenuTitle = GetSysColor(COLOR_MENUBAR);
  139. else
  140. crMenuTitle = GetSysColor(COLOR_MENU);
  141. crMenuText = GetSysColor(COLOR_MENUTEXT);
  142. crMenuTextSel = GetSysColor(COLOR_HIGHLIGHTTEXT);
  143. cr3dFace = GetSysColor(COLOR_3DFACE);
  144. crMenu = GetSysColor(COLOR_MENU);
  145. crHighlight = GetSysColor(COLOR_HIGHLIGHT);
  146. cr3dHilight = GetSysColor(COLOR_3DHILIGHT);
  147. cr3dShadow = GetSysColor(COLOR_3DSHADOW);
  148. crGrayText = GetSysColor(COLOR_GRAYTEXT);
  149. m_clrBtnFace = GetSysColor(COLOR_BTNFACE);
  150. m_clrBtnHilight = GetSysColor(COLOR_BTNHILIGHT);
  151. m_clrBtnShadow = GetSysColor(COLOR_BTNSHADOW);
  152. //*/
  153. iSpawnItem = 0;
  154. pSpawnItem = NULL;
  155. iImageItem = 0;
  156. pImageItem = NULL;
  157. szImage = CSize(20,20);
  158. COLORMAP cMap[3] = { 
  159. { RGB(128,128,128), cr3dShadow }, 
  160. { RGB(192,192,192), cr3dFace }, 
  161. { RGB(255,255,255), cr3dHilight }
  162. };
  163. /*
  164. CBitmap bmp;
  165. bmp.LoadMappedBitmap(IDB_MENUCHK, 0, cMap, 3);
  166. ilOther.Create(19, 19, ILC_COLOR4|ILC_MASK, 1, 0);
  167. ilOther.Add(&bmp, cr3dFace);
  168. bmp.DeleteObject();
  169. //*/
  170. /*
  171. NONCLIENTMETRICS ncm;
  172. memset(&ncm, 0, sizeof(ncm));
  173. ncm.cbSize = sizeof(ncm);
  174. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0);
  175. hGuiFont = ::CreateFontIndirect(&ncm.lfMenuFont);
  176. //*/
  177. bIsPopup = false;
  178. bBackBitmap = false;
  179. m_iNormalImgInx = -1;
  180. }
  181. bool CMenuSpawn::Create(unsigned int bmpId, unsigned int bmpDisabledId, int iCount, ULONG lMenuCmdID[])
  182. {
  183. Clear();
  184. HBITMAP hbm = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
  185. MAKEINTRESOURCE(bmpId),
  186. IMAGE_BITMAP,
  187. 0,0, 
  188. LR_CREATEDIBSECTION);
  189. CBitmap bm;
  190. bm.Attach(hbm);
  191. szImage = CSize(16, 16);
  192. ilList.Create(16, 16, ILC_COLOR8|ILC_MASK, iCount, 4);
  193. // ilList.SetBkColor(RGB(255, 255,255)); 
  194. ilList.SetBkColor(crMenu);
  195. ilList.Add(&bm, (COLORREF)RGB(255,0,255));
  196. HBITMAP hbmDisabled = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
  197. MAKEINTRESOURCE(bmpDisabledId),
  198. IMAGE_BITMAP,
  199. 0,0, 
  200. LR_CREATEDIBSECTION);
  201. CBitmap bmDisabled;
  202. bmDisabled.Attach(hbmDisabled);
  203. ilDisabledList.Create(16, 16, ILC_COLOR8|ILC_MASK, iCount, 4);
  204. ilDisabledList.SetBkColor(crMenu);
  205. ilDisabledList.Add(&bmDisabled, (COLORREF)RGB(255,0,255));
  206. int nBmpItems = 0;
  207. for(int i=0; i<iCount; i++)
  208. {
  209. if(lMenuCmdID[i] == ID_SEPARATOR)
  210. {
  211. ASSERT(FALSE);
  212. return false;
  213. }
  214. if(lMenuCmdID[i] == eUnusedImgCmdID)
  215. {
  216. nBmpItems++;
  217. continue;
  218. }
  219. if(lMenuCmdID[i] == eNormalImgCmdID)
  220. {
  221. m_iNormalImgInx = i;
  222. nBmpItems++;
  223. continue;
  224. }
  225. AddImageItem(nBmpItems++, (WORD)lMenuCmdID[i]);
  226. }
  227. return true;
  228. }
  229. bool CMenuSpawn::AddToolBarResource(unsigned int resId)
  230. {
  231. ASSERT(FALSE);
  232. HRSRC hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resId), RT_TOOLBAR);
  233. if (hRsrc == NULL) return false;
  234. HGLOBAL hGlb = ::LoadResource(AfxGetResourceHandle(), hRsrc);
  235. if (hGlb == NULL) return false;
  236. ToolBarData* pTBData = (ToolBarData*) ::LockResource(hGlb);
  237. if (pTBData == NULL) return false;
  238. ASSERT(pTBData->wVersion == 1);
  239. CBitmap bmp;
  240. bmp.LoadBitmap(resId);
  241. int nBmpItems = ilList.Add(&bmp, RGB(192,192,192));
  242. bmp.DeleteObject();
  243. WORD* pItem = (WORD*)(pTBData+1);
  244. for(int i=0; i<pTBData->wItemCount; i++, pItem++)
  245. {
  246. if(*pItem != ID_SEPARATOR)
  247. AddImageItem(nBmpItems++, (WORD) *pItem);
  248. }
  249. // ** it seem that Windows doesn't free these resource (from Heitor Tome)
  250.     ::UnlockResource(hGlb);
  251.     ::FreeResource(hGlb);
  252. // **
  253. return true;
  254. }
  255. bool CMenuSpawn::LoadToolBarResource(unsigned int resId)
  256. {
  257. ASSERT(FALSE);
  258. HRSRC hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resId), RT_TOOLBAR);
  259. if (hRsrc == NULL) return false;
  260. HGLOBAL hGlb = ::LoadResource(AfxGetResourceHandle(), hRsrc);
  261. if (hGlb == NULL) return false;
  262. ToolBarData* pTBData = (ToolBarData*) ::LockResource(hGlb);
  263. if (pTBData == NULL) return false;
  264. ASSERT(pTBData->wVersion == 1);
  265. szImage.cx = (int) pTBData->wWidth;
  266. szImage.cy = (int) pTBData->wHeight;
  267. if (ilList.Create(szImage.cx, szImage.cy, ILC_COLOR4|ILC_MASK, pTBData->wItemCount, 0) == false)
  268. return false;
  269. ilList.SetBkColor(cr3dFace);
  270. CBitmap bmp;
  271. bmp.LoadBitmap(resId);
  272. ilList.Add(&bmp, RGB(192,192,192));
  273. bmp.DeleteObject();
  274. WORD* pItem = (WORD*)(pTBData+1);
  275. int nBmpItems = 0;
  276. for(int i=0; i<pTBData->wItemCount; i++, pItem++)
  277. {
  278. if(*pItem != ID_SEPARATOR)
  279. AddImageItem(nBmpItems++, (WORD) *pItem);
  280. }
  281. // ** it seem that Windows doesn't free these resource (from Heitor Tome)
  282.     ::UnlockResource(hGlb);
  283.     ::FreeResource(hGlb);
  284. // **
  285. return true;
  286. }
  287. void CMenuSpawn::AddImageItem(const int idx, WORD cmd)
  288. {
  289. if (iImageItem == 0)
  290. pImageItem = (ImageItem *) GlobalAlloc(GPTR, sizeof(ImageItem));
  291. else
  292. pImageItem = (ImageItem *) GlobalReAlloc((HGLOBAL) pImageItem, sizeof(ImageItem) * (iImageItem + 1), GMEM_MOVEABLE|GMEM_ZEROINIT);
  293. ASSERT(pImageItem);
  294. pImageItem[iImageItem].iCmd = (int) cmd;
  295. pImageItem[iImageItem].iImageIdx = idx;
  296. iImageItem ++;
  297. }
  298. void CMenuSpawn::RemapMenuEx(CMenu * pMenu)
  299. {
  300. //
  301. // release spawn items.
  302. //
  303. /*
  304. if (iSpawnItem > 0)
  305. {
  306. for (int t = 0; t < iSpawnItem; t++)
  307. if (pSpawnItem[t]) delete pSpawnItem[t];
  308. GlobalFree((HGLOBAL) pSpawnItem);
  309. }
  310. iSpawnItem = 0;
  311. pSpawnItem = NULL;
  312. //*/
  313. RemapMenu(pMenu);
  314. }
  315. void CMenuSpawn::RemapMenu(CMenu * pMenu)
  316. {
  317. // regen mapitems.
  318. static int iRecurse = 0;
  319. iRecurse ++;
  320. ASSERT(pMenu);
  321. int nItem = pMenu->GetMenuItemCount();
  322. while ((--nItem)>=0)
  323. {
  324. UINT itemId = pMenu->GetMenuItemID(nItem);
  325. if (itemId == (UINT) -1)
  326. {
  327. CMenu *pops = pMenu->GetSubMenu(nItem);
  328. if (pops) RemapMenu(pops);
  329. if (bIsPopup || iRecurse > 0)
  330. {
  331. CString cs;
  332. pMenu->GetMenuString(nItem, cs, MF_BYPOSITION);
  333. if (cs != "")
  334. {
  335. if (bIsPopup)
  336. {
  337. SpawnItem * sp = AddSpawnItem(cs, (!bIsPopup && iRecurse == 1) ? -4 : -2);
  338. pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW, (UINT) -1, (LPCTSTR)sp);
  339. }
  340. }
  341. }
  342. }
  343. else
  344. {
  345. if (itemId != 0)
  346. {
  347. UINT oldState = pMenu->GetMenuState(nItem,MF_BYPOSITION);
  348. if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
  349. {
  350. ASSERT(oldState != (UINT)-1);
  351. CString cs;
  352. pMenu->GetMenuString(nItem, cs, MF_BYPOSITION);
  353. SpawnItem * sp = AddSpawnItem(cs, itemId);
  354. pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
  355. }
  356. }
  357. else
  358. {
  359. UINT oldState = pMenu->GetMenuState(nItem,MF_BYPOSITION);
  360. if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
  361. {
  362. ASSERT(oldState != (UINT)-1);
  363. SpawnItem * sp = AddSpawnItem("--", -3);
  364. pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
  365. }
  366. }
  367. }
  368. }
  369. iRecurse --;
  370. }
  371. CMenuSpawn::SpawnItem * CMenuSpawn::AddSpawnItem(const char * txt, const int cmd)
  372. {
  373. if (iSpawnItem == 0)
  374. pSpawnItem = (SpawnItem **) GlobalAlloc(GPTR, sizeof(SpawnItem));
  375. else
  376. pSpawnItem = (SpawnItem **) GlobalReAlloc((HGLOBAL) pSpawnItem, sizeof(SpawnItem) * (iSpawnItem + 1), GMEM_MOVEABLE|GMEM_ZEROINIT);
  377. ASSERT(pSpawnItem);
  378. SpawnItem * p = new SpawnItem;
  379. ASSERT(p);
  380. pSpawnItem[iSpawnItem] = p;
  381. lstrcpy(p->cText, txt);
  382. p->iCmd = cmd;
  383. if (cmd >= 0) p->iImageIdx = FindImageItem(cmd);
  384. else p->iImageIdx = cmd;
  385. iSpawnItem ++;
  386. return p;
  387. }
  388. int CMenuSpawn::FindImageItem(const int cmd)
  389. {
  390. for (int t = 0; t < iImageItem; t++)
  391. if (pImageItem[t].iCmd == cmd) return pImageItem[t].iImageIdx;
  392. return -1;
  393. }
  394. bool CMenuSpawn::DrawItem(LPDRAWITEMSTRUCT lp)
  395. {
  396. bool res = false;
  397. if (lp->CtlType == ODT_MENU)
  398. {
  399. UINT id = lp->itemID;
  400. UINT state = lp->itemState;
  401. bool bEnab = !(state & ODS_DISABLED);
  402. bool bSelect = (state & ODS_SELECTED) ? true : false;
  403. bool bChecked = (state & ODS_CHECKED) ? true : false;
  404. SpawnItem * pItem = (SpawnItem *) lp->itemData;
  405. if (pItem)
  406. {
  407. CDC * pDC = CDC::FromHandle(lp->hDC);
  408. CFont * pft = CFont::FromHandle((HFONT) hMenuFont ? hMenuFont : hGuiFont);
  409. CFont * of = pDC->SelectObject(pft);
  410. CRect rc(lp->rcItem);
  411. CRect rcImage(rc), rcText(rc);
  412. rcImage.right = rcImage.left + rc.Height();
  413. rcImage.bottom = rc.bottom;
  414. if (bBackBitmap) 
  415. {
  416. CDC tempDC;
  417. tempDC.CreateCompatibleDC(pDC);
  418. tempDC.FillSolidRect(rc, crMenu);
  419. CBitmap * ob = tempDC.SelectObject(&bmpBack);
  420. pDC->FillSolidRect(rc, crMenu);
  421. pDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &tempDC, rc.left, rc.top, SRCCOPY );
  422. }
  423. if (pItem->iCmd == -3) // is a separator
  424. {
  425. CPen pnDk(PS_SOLID,1,cr3dShadow);
  426. CPen pnLt(PS_SOLID,1,cr3dHilight);
  427. CPen * opn = pDC->SelectObject(&pnDk);
  428. pDC->MoveTo(rc.left + 2, rc.top + 2);
  429. pDC->LineTo(rc.right - 2, rc.top + 2);
  430. pDC->SelectObject(&pnLt);
  431. pDC->MoveTo(rc.left + 2, rc.top + 3);
  432. pDC->LineTo(rc.right - 2, rc.top + 3);
  433. pDC->SelectObject(opn);
  434. }
  435. else if (pItem->iCmd == -4) // is a title item
  436. {
  437. CString cs(pItem->cText), cs1;
  438. CRect rcBdr(rcText);
  439. if (bSelect && bEnab)
  440. {
  441. rcText.top ++;
  442. rcText.left += 2;
  443. }
  444. pDC->FillSolidRect(rcText, crMenuTitle);
  445. pDC->DrawText(cs, rcText, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
  446. if (bSelect && bEnab) pDC->Draw3dRect(rcBdr,cr3dShadow,cr3dHilight);
  447. }
  448. else
  449. {
  450. rcText.left += rcImage.right + 1;
  451. int obk = pDC->SetBkMode(TRANSPARENT);
  452. COLORREF ocr;
  453. if (bSelect)
  454. {
  455. //*
  456. if (pItem->iImageIdx >= 0 || (state & ODS_CHECKED))
  457. pDC->FillSolidRect(rcText, crHighlight);
  458. else
  459. pDC->FillSolidRect(rc, crHighlight);
  460. ocr = pDC->SetTextColor(crMenuTextSel);
  461. //*/
  462. }
  463. else
  464. {
  465. if (!bBackBitmap) 
  466. {
  467. if (pItem->iImageIdx >= 0 || (state & ODS_CHECKED))
  468. pDC->FillSolidRect(rcText, crMenu);
  469. else
  470. pDC->FillSolidRect(rc/*rcText*/, crMenu);
  471. }
  472. ocr = pDC->SetTextColor(crMenuText);
  473. }
  474. if (pItem->iImageIdx >= 0)
  475. {
  476. int ay = (rcImage.Height() - szImage.cy) / 2;
  477. int ax = (rcImage.Width()  - szImage.cx) / 2;
  478. /*
  479. if (bSelect && bEnab)
  480. pDC->Draw3dRect(rcImage,cr3dHilight,cr3dShadow);
  481. else
  482. {
  483. if (!bBackBitmap)
  484. pDC->Draw3dRect(rcImage,crMenu,crMenu);
  485. }
  486. //*/
  487. if (bEnab)
  488. {
  489. if (bSelect)
  490. ilList.Draw(pDC, pItem->iImageIdx, CPoint(rcImage.left + ax, rcImage.top +ay), ILD_BLEND25);
  491. else
  492. ilList.Draw(pDC, pItem->iImageIdx, CPoint(rcImage.left + ax, rcImage.top +ay), ILD_NORMAL);
  493. }
  494. else
  495. {
  496. ilDisabledList.Draw(pDC, pItem->iImageIdx, CPoint(rcImage.left + ax, rcImage.top +ay), ILD_NORMAL);
  497. /*
  498. HICON hIcon = ilList.ExtractIcon( pItem->iImageIdx );
  499. pDC->DrawState( CPoint(rcImage.left + ax, rcImage.top + ay ), szImage, (HICON)hIcon, DST_ICON | DSS_DISABLED, (CBrush *)NULL );
  500. //*/
  501. }
  502. }
  503. else
  504. {
  505. if (bChecked)
  506. {
  507. int ay = (rcImage.Height() - szImage.cy) / 2;
  508. int ax = (rcImage.Width()  - szImage.cx) / 2;
  509. if (m_iNormalImgInx >= 0)
  510. {
  511. if (bSelect)
  512. ilList.Draw(pDC, m_iNormalImgInx, CPoint(rcImage.left + ax, rcImage.top +ay), ILD_BLEND25);
  513. else
  514. ilList.Draw(pDC, m_iNormalImgInx, CPoint(rcImage.left + ax, rcImage.top +ay), ILD_NORMAL);
  515. }
  516. // ilOther.Draw(pDC, 0, CPoint(rcImage.left + ax, rcImage.top + ay - 2), ILD_NORMAL);
  517. }
  518. }
  519. CString cs(pItem->cText), cs1;
  520. CSize sz;
  521. sz = pDC->GetTextExtent(cs);
  522. int ay1 = (rcText.Height() - sz.cy) / 2;
  523. rcText.top += ay1;
  524. rcText.left += 2;
  525. rcText.right -= 15;
  526. int tf = cs.Find('t');
  527. if (tf >= 0)
  528. {
  529. cs1 = cs.Right(cs.GetLength() - tf - 1);
  530. cs = cs.Left(tf);
  531. if (!bEnab)
  532. {
  533. if (!bSelect)
  534. {
  535. CRect rcText1(rcText);
  536. rcText1.InflateRect(-1,-1);
  537. pDC->SetTextColor(cr3dHilight);
  538. pDC->DrawText(cs, rcText1, DT_VCENTER|DT_LEFT);
  539. pDC->DrawText(cs1, rcText1, DT_VCENTER|DT_RIGHT);
  540. pDC->SetTextColor(crGrayText);
  541. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT);
  542. pDC->DrawText(cs1, rcText, DT_VCENTER|DT_RIGHT);
  543. }
  544. else
  545. {
  546. pDC->SetTextColor(crMenu);
  547. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT);
  548. pDC->DrawText(cs1, rcText, DT_VCENTER|DT_RIGHT);
  549. }
  550. }
  551. else
  552. {
  553. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT);
  554. pDC->DrawText(cs1, rcText, DT_VCENTER|DT_RIGHT);
  555. }
  556. }
  557. else 
  558. {
  559. if (!bEnab)
  560. {
  561. if (!bSelect)
  562. {
  563. CRect rcText1(rcText);
  564. rcText1.InflateRect(-1,-1);
  565. pDC->SetTextColor(cr3dHilight);
  566. pDC->DrawText(cs, rcText1, DT_VCENTER|DT_LEFT|DT_EXPANDTABS);
  567. pDC->SetTextColor(crGrayText);
  568. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT|DT_EXPANDTABS);
  569. }
  570. else
  571. {
  572. pDC->SetTextColor(crMenu);
  573. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT|DT_EXPANDTABS);
  574. }
  575. }
  576. else
  577. pDC->DrawText(cs, rcText, DT_VCENTER|DT_LEFT|DT_EXPANDTABS);
  578. }
  579. pDC->SetTextColor(ocr);
  580. pDC->SetBkMode(obk);
  581. }
  582. pDC->SelectObject(of);
  583. }
  584. res = true;
  585. }
  586. return res;
  587. }
  588. bool CMenuSpawn::MeasureItem(LPMEASUREITEMSTRUCT lpm)
  589. {
  590. bool res = false;
  591. if (lpm->CtlType == ODT_MENU)
  592. {
  593. UINT id = lpm->itemID;
  594. SpawnItem * pItem = (SpawnItem *) lpm->itemData;
  595. if (pItem)
  596. {
  597. if (pItem->iCmd == -3) // is a separator
  598. {
  599. lpm->itemWidth  = 10;
  600. lpm->itemHeight = 6;
  601. }
  602. else
  603. {
  604. CString cs(pItem->cText);
  605. if (cs != "")
  606. {
  607. CClientDC dc(AfxGetMainWnd());
  608. CFont * pft = CFont::FromHandle(hMenuFont ? hMenuFont : hGuiFont);
  609. CFont * of = dc.SelectObject(pft);
  610. CSize osz = dc.GetOutputTabbedTextExtent(cs,0,NULL);
  611. if (pItem->iCmd == -4)
  612. {
  613. CRect rci(0,0,0,0);
  614. dc.DrawText(cs, rci, DT_CALCRECT|DT_TOP|DT_VCENTER|DT_SINGLELINE);
  615. lpm->itemHeight = rci.Height();
  616. lpm->itemWidth = rci.Width();
  617. }
  618. else
  619. {
  620. lpm->itemHeight = szImage.cy + 2;
  621. if (osz.cy > (int) lpm->itemHeight) lpm->itemHeight = (int) osz.cy;
  622. lpm->itemWidth  = osz.cx + 2 + 15;
  623. lpm->itemWidth += lpm->itemHeight > (UINT) szImage.cx ? (UINT) lpm->itemHeight : (UINT) szImage.cx;
  624. }
  625. dc.SelectObject(of);
  626. }
  627. else
  628. {
  629. lpm->itemHeight = szImage.cy + 5;
  630. lpm->itemWidth  = 100;
  631. }
  632. }
  633. }
  634. res = true;
  635. }
  636. return res;
  637. }
  638. void CMenuSpawn::EnableMenuItems(CMenu * pMenu, CWnd * pParent)
  639. {
  640. ASSERT(pMenu);
  641. ASSERT(pParent);
  642. int nItem = pMenu->GetMenuItemCount();
  643. CCmdUI state;
  644. state.m_pMenu = pMenu;
  645. state.m_nIndex = nItem-1;
  646. state.m_nIndexMax = nItem;
  647. while ((--nItem)>=0)
  648. {
  649. UINT itemId = pMenu->GetMenuItemID(nItem);
  650. if (itemId == (UINT) -1)
  651. {
  652. CMenu *pops = pMenu->GetSubMenu(nItem);
  653. if (pops) EnableMenuItems(pops, pParent);
  654. }
  655. else
  656. {
  657. if (itemId != 0)
  658. {
  659. state.m_nID = itemId;
  660. pParent->OnCmdMsg(itemId, CN_UPDATE_COMMAND_UI, &state, NULL);
  661. state.DoUpdate(pParent, true);
  662. }
  663. }
  664. state.m_nIndex = nItem-1;
  665. }
  666. }
  667. bool CMenuSpawn::SetFont(LOGFONT * lf)
  668. {
  669. ASSERT(lf);
  670. if (hMenuFont) ::DeleteObject((HGDIOBJ)hMenuFont);
  671. hMenuFont = CreateFontIndirect(lf);
  672. return hMenuFont != NULL ? true : false;
  673. }
  674. bool CMenuSpawn::FindKeyboardShortcut(UINT nChar, UINT nFlags, CMenu * pMenu, LRESULT & lRes)
  675. {
  676. ASSERT(pMenu);
  677. int nItem = pMenu->GetMenuItemCount();
  678. CString csChar((CHAR) nChar);
  679. csChar.MakeLower();
  680. while ((--nItem)>=0)
  681. {
  682. UINT itemId = pMenu->GetMenuItemID(nItem);
  683. if (itemId != 0)
  684. {
  685. MENUITEMINFO lpmi;
  686. ZeroMemory(&lpmi, sizeof(MENUITEMINFO));
  687. lpmi.cbSize = sizeof(MENUITEMINFO);
  688. lpmi.fMask = MIIM_DATA|MIIM_TYPE;
  689. ASSERT(pMenu->GetSafeHmenu());
  690. if (GetMenuItemInfo(pMenu->GetSafeHmenu(), nItem, TRUE, &lpmi))
  691. {
  692. if (lpmi.fType&MFT_OWNERDRAW)
  693. {
  694. SpawnItem * si = (SpawnItem *) lpmi.dwItemData;
  695. if (si)
  696. {
  697. CString csItem(si->cText);
  698. csItem.MakeLower();
  699. int iAmperIdx = csItem.Find('&');
  700. if (iAmperIdx >= 0)
  701. {
  702. csItem = csItem.Mid(iAmperIdx + 1, 1);
  703. if (csItem == csChar)
  704. {
  705. lRes = MAKELONG((WORD)nItem, 2);
  706. return true;
  707. }
  708. }
  709. }
  710. }
  711. }
  712. }
  713. }
  714. return false;
  715. }
  716. void CMenuSpawn::SetTextColor(const COLORREF crNormal, const COLORREF crSelected)
  717. {
  718. crMenuText = crNormal;
  719. crMenuTextSel = crSelected;
  720. }
  721. void CMenuSpawn::SetBackBitmap(const int iRes)
  722. {
  723. if (bmpBack.GetSafeHandle()) bmpBack.DeleteObject();
  724. bmpBack.LoadBitmap(iRes);
  725. bBackBitmap = true;
  726. }
  727. void CMenuSpawn::SetBackBitmap(const int iRes, COLORREF crBackColor)
  728. {
  729. if (bmpBack.GetSafeHandle()) bmpBack.DeleteObject();
  730. COLORMAP cMap1 = { crBackColor, cr3dFace };
  731. bmpBack.LoadMappedBitmap(iRes, 0, &cMap1, 1);
  732. bBackBitmap = true;
  733. }
  734. bool CMenuSpawn::GetMenuItemText(CString &csText, CMenu * pMenu, const int cmd, bool bByPos)
  735. {
  736. ASSERT(pMenu);
  737. UINT itemId = bByPos ? pMenu->GetMenuItemID(cmd) : cmd;
  738. if (itemId != 0)
  739. {
  740. MENUITEMINFO lpmi;
  741. ZeroMemory(&lpmi, sizeof(MENUITEMINFO));
  742. lpmi.cbSize = sizeof(MENUITEMINFO);
  743. lpmi.fMask = MIIM_DATA|MIIM_TYPE;
  744. ASSERT(pMenu->GetSafeHmenu());
  745. if (GetMenuItemInfo(pMenu->GetSafeHmenu(), cmd, bByPos, &lpmi))
  746. {
  747. if (lpmi.fType&MFT_OWNERDRAW)
  748. {
  749. SpawnItem * si = (SpawnItem *) lpmi.dwItemData;
  750. if (si)
  751. {
  752. csText = si->cText;
  753. return true;
  754. }
  755. }
  756. else
  757. {
  758. return pMenu->GetMenuString(cmd, csText, bByPos ? MF_BYPOSITION : MF_BYCOMMAND) > 0;
  759. }
  760. }
  761. }
  762. return false;
  763. }
  764. bool CMenuSpawn::IsSpawnMenu(CMenu * pMenu, const int iItem, const bool bByPos)
  765. {
  766. ASSERT(pMenu);
  767. UINT itemId = bByPos ? pMenu->GetMenuItemID(iItem) : iItem;
  768. if (itemId != 0)
  769. {
  770. MENUITEMINFO lpmi;
  771. ZeroMemory(&lpmi, sizeof(MENUITEMINFO));
  772. lpmi.cbSize = sizeof(MENUITEMINFO);
  773. lpmi.fMask = MIIM_DATA|MIIM_TYPE;
  774. ASSERT(pMenu->GetSafeHmenu());
  775. if (GetMenuItemInfo(pMenu->GetSafeHmenu(), iItem, bByPos, &lpmi))
  776. {
  777. if (lpmi.fType&MFT_OWNERDRAW)
  778. {
  779. SpawnItem * si = (SpawnItem *) lpmi.dwItemData;
  780. if (si) return true;
  781. }
  782. }
  783. }
  784. return false;
  785. }
  786. void CMenuSpawn::TransparentBlt(CDC * pDestDc, int x, int y, int w, int h, CBitmap * pBmp, int sx, int sy, COLORREF crTransparent)
  787. {
  788. CDC memDC, maskDC, tempDC;
  789. maskDC.CreateCompatibleDC(pDestDc);
  790. CBitmap maskBitmap;
  791. //add these to store return of SelectObject() calls
  792. CBitmap* pOldMemBmp = NULL;
  793. CBitmap* pOldMaskBmp = NULL;
  794. memDC.CreateCompatibleDC(pDestDc);
  795. tempDC.CreateCompatibleDC(pDestDc);
  796. CBitmap bmpImage;
  797. bmpImage.CreateCompatibleBitmap( pDestDc, w, h);
  798. pOldMemBmp = memDC.SelectObject( &bmpImage );
  799. CBitmap * oldBmp = tempDC.SelectObject(pBmp);
  800. memDC.BitBlt( 0,0,w, h, &tempDC, sx, sy, SRCCOPY );
  801. // Create monochrome bitmap for the mask
  802. maskBitmap.CreateBitmap(w, h, 1, 1, NULL);
  803. pOldMaskBmp = maskDC.SelectObject( &maskBitmap );
  804. memDC.SetBkColor(crTransparent);
  805. // Create the mask from the memory DC
  806. maskDC.BitBlt(0, 0, w, h, &memDC, 0, 0, SRCCOPY);
  807. memDC.SetBkColor(RGB(0,0,0));
  808. memDC.SetTextColor(RGB(255,255,255));
  809. memDC.BitBlt(0, 0, w, h, &maskDC, 0, 0, SRCAND);
  810. // Set the foreground to black. See comment above.
  811. pDestDc->SetBkColor(RGB(255,255,255));
  812. pDestDc->SetTextColor(RGB(0,0,0));
  813. pDestDc->BitBlt(x, y, w, h, &maskDC, 0, 0, SRCAND);
  814. // Combine the foreground with the background
  815. pDestDc->BitBlt(x, y, w, h, &memDC, 0, 0, SRCPAINT);
  816. tempDC.SelectObject(oldBmp);
  817. if (pOldMaskBmp) maskDC.SelectObject( pOldMaskBmp );
  818. if (pOldMemBmp)  memDC.SelectObject( pOldMemBmp );
  819. }