EZMenu.cpp
上传用户:sui0427
上传日期:2007-01-02
资源大小:27k
文件大小:8k
源码类别:

菜单

开发平台:

Visual C++

  1. //////
  2. // EZMenu - Owner drawn menu with Icons & progressbars
  3. // Copyright V.Lakshmi Narasimhan,ezlux@Yahoo.com.
  4. // Feel free to use,modify,twist,turn or even 
  5. // digest the code for any non commercial purposes.
  6. // I would appreciate constructive suggestions & bug reports.
  7. // Please dont delete the above lines.
  8. ///////
  9. //Implementation file for owner drawn menu EZMenu
  10. #include "stdafx.h" 
  11. #include "EZMenu.h"
  12. #include "resource.h"
  13. CEZMenu::CEZMenu()
  14. {
  15. m_bLargeIcons=FALSE;
  16. m_szBitmapSize=CSize(20,60);
  17. m_nCount=m_nItems=0;
  18. m_nAveHeight=16;
  19. m_clrExtend=RGB(0,0,255);
  20. CMenu::CMenu();
  21. }
  22. void CEZMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  23. {
  24. m_nCount++;
  25. LPEZMENUITEMDATA lpez=(LPEZMENUITEMDATA)lpDrawItemStruct->itemData;
  26. CDC* pdc=CDC::FromHandle(lpDrawItemStruct->hDC);
  27.     if(lpez->bSeperator)
  28. {
  29. int nWidth=0;
  30. if(m_bitmap.m_hObject)
  31. nWidth+=(m_szBitmapSize.cx+lpDrawItemStruct->rcItem.left);
  32.     CRect rcSep(lpDrawItemStruct->rcItem);
  33. rcSep.left+=nWidth;
  34. pdc->DrawEdge(&rcSep,EDGE_ETCHED,BF_TOP);
  35. return;
  36. }
  37. // Rects Definition
  38. CRect rect(lpDrawItemStruct->rcItem);//general
  39. CRect rcBmp(rect);
  40. CRect rcIcon(rect);//Icon rect
  41. CRect rcProgress(rect);//Progress bar rect
  42. CRect rcText(rect);//Text rect;
  43. //Rects Initialization
  44.    
  45. rcBmp.right=rcBmp.left+m_szBitmapSize.cx;
  46. rcIcon.left=rcBmp.right+2;
  47. rcIcon.right=rcIcon.left+(m_bLargeIcons?32:16);
  48. rcProgress.left=rcIcon.right+2;
  49. rcProgress.right=rcIcon.right+(lpez->bProgress?100:0);
  50. rcProgress.top+=4;
  51. rcProgress.bottom-=4;
  52. rcText.left=rcProgress.right+2;
  53. //Drawing code
  54. HICON hItemIcon=(m_bLargeIcons?lpez->hItemIconLarge:lpez->hItemIconSmall);
  55. CSize szIcon=(m_bLargeIcons?CSize(32,32):CSize(16,16));
  56. //Draws the whole thing
  57. if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE)
  58. {
  59. //Draw the Icon
  60.  int nOldMap=pdc->SetMapMode(MM_TEXT);
  61.  if(hItemIcon)
  62.     pdc->DrawState(rcIcon.TopLeft(),szIcon,hItemIcon,DST_ICON|DSS_NORMAL,(CBrush*)NULL);
  63.  else if(lpez->bChecked)
  64. {
  65.    
  66.    HICON hCheck=(HICON)::LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(m_bLargeIcons?IDI_CHECK_LARGE:IDI_CHECK_SMALL),IMAGE_ICON,szIcon.cx,szIcon.cy,LR_DEFAULTCOLOR);
  67.    pdc->DrawState(rcIcon.TopLeft(),szIcon,hCheck,DST_ICON|DSS_NORMAL,(CBrush*)NULL);
  68.    
  69. }
  70. //Draw the Progress Bar
  71. if(lpez->bProgress)
  72. {
  73. pdc->Draw3dRect(&rcProgress,::GetSysColor(COLOR_HIGHLIGHT),::GetSysColor(COLOR_HIGHLIGHT));
  74. CRect rectProgress(rcProgress);
  75. rectProgress.DeflateRect(CSize(1,1));
  76. CBrush *pBrush=new CBrush(::GetSysColor(COLOR_BTNFACE));
  77.     pdc->FillRect(rectProgress,pBrush);
  78.     delete pBrush;
  79. pBrush=new CBrush(::GetSysColor(COLOR_HIGHLIGHT)); 
  80. rectProgress.right-=lpez->nProgress;
  81. pdc->FillRect(&rectProgress,pBrush);
  82. delete pBrush;
  83. }
  84. //Finally draw the text
  85. pdc->SetMapMode(nOldMap);
  86. CBrush *pBrush=new CBrush(::GetSysColor(COLOR_BTNFACE));
  87. pdc->FillRect(rcText,pBrush);
  88. delete pBrush;
  89. pdc->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
  90. pdc->SetBkColor(::GetSysColor(COLOR_BTNFACE));
  91. pdc->DrawText(lpez->strItemText,&rcText,DT_LEFT|DT_NOCLIP|DT_SINGLELINE|DT_VCENTER);
  92. //Draw the bitmap at the end
  93. if(m_nCount==m_nItems)
  94. {
  95. m_nCount=0;
  96. if(m_bitmap.m_hObject)
  97. {
  98. CDC memdc;
  99. memdc.CreateCompatibleDC(pdc);
  100. memdc.SelectObject(m_bitmap);
  101. if(m_nAveHeight>m_szBitmapSize.cy)
  102. {
  103. int nTop=rect.bottom-m_szBitmapSize.cy;
  104. pdc->BitBlt(rect.left,nTop,m_szBitmapSize.cx,m_szBitmapSize.cy,&memdc,0,0,SRCCOPY);    
  105. pdc->FillSolidRect(rect.left,rect.bottom-m_nAveHeight,m_szBitmapSize.cx,m_nAveHeight-m_szBitmapSize.cy,m_clrExtend);
  106. }
  107. else
  108. pdc->BitBlt(rect.left,rect.bottom-m_nAveHeight,m_szBitmapSize.cx,m_nAveHeight,&memdc,0,0,SRCCOPY);    
  109. }
  110. }
  111. }
  112. //Draws the selected item
  113. if ((lpDrawItemStruct->itemState & ODS_SELECTED) &&
  114. (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
  115. {
  116. if(hItemIcon)
  117. {
  118. CRect rcIconHilite(rcIcon);
  119. rcIconHilite.left-=1;
  120. rcIconHilite.top-=1;
  121. //rcIconHilite.bottom+=1;
  122. rcIconHilite.right+=1;
  123. pdc->Draw3dRect(&rcIconHilite,::GetSysColor(COLOR_3DHILIGHT),::GetSysColor(COLOR_3DDKSHADOW));
  124. }
  125.          //Progress
  126. if(lpez->bProgress)
  127. {
  128. pdc->Draw3dRect(&rcProgress,::GetSysColor(COLOR_3DHILIGHT),::GetSysColor(COLOR_3DDKSHADOW));
  129. }
  130.         //Text
  131. CRect textrect(rcText);
  132.         
  133. COLORREF crOld=pdc->SetTextColor(::GetSysColor(COLOR_HIGHLIGHT));
  134. COLORREF crBgOld=pdc->SetBkColor(::GetSysColor(COLOR_BTNFACE));
  135. CFont* pFont=pdc->GetCurrentFont();
  136. LOGFONT* pLf=new LOGFONT;
  137. pFont->GetLogFont(pLf);
  138. pLf->lfWeight=FW_SEMIBOLD;
  139. CFont* pNewFont=new CFont;
  140. pNewFont->CreateFontIndirect(pLf);
  141. pFont=pdc->SelectObject(pNewFont);
  142. pdc->DrawText(lpez->strItemText,&textrect,DT_LEFT|DT_NOCLIP|DT_SINGLELINE|DT_VCENTER);
  143. pdc->SetTextColor(crOld);
  144. pdc->SetBkColor(crBgOld);
  145. delete pdc->SelectObject(pFont);
  146. delete pLf;
  147. textrect.top+=2;
  148. textrect.bottom-=2;
  149.         textrect.left-=1;  
  150. pdc->Draw3dRect(&textrect,::GetSysColor(COLOR_3DHILIGHT),::GetSysColor(COLOR_3DDKSHADOW));
  151.         
  152. }
  153. //Draws the deselected item
  154. if (!(lpDrawItemStruct->itemState & ODS_SELECTED) &&
  155. (lpDrawItemStruct->itemAction & ODA_SELECT))
  156. {
  157. if(hItemIcon)
  158. {
  159. CRect rcIconHilite(rcIcon);
  160. rcIconHilite.left-=1;
  161. rcIconHilite.top-=1;
  162. //rcIconHilite.bottom+=1;
  163. rcIconHilite.right+=1;
  164. pdc->Draw3dRect(&rcIconHilite,::GetSysColor(COLOR_BTNFACE),::GetSysColor(COLOR_BTNFACE));
  165. }
  166. if(lpez->bProgress)
  167. {
  168. pdc->Draw3dRect(&rcProgress,::GetSysColor(COLOR_HIGHLIGHT),::GetSysColor(COLOR_HIGHLIGHT));
  169. }
  170. pdc->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
  171. pdc->SetBkColor(::GetSysColor(COLOR_BTNFACE));
  172. CRect textrect(rcText);
  173.         CBrush *pBrush=new CBrush(::GetSysColor(COLOR_BTNFACE));
  174. pdc->FillRect(&textrect,pBrush);
  175. delete pBrush;
  176. pdc->DrawText(lpez->strItemText,&textrect,DT_LEFT|DT_NOCLIP|DT_SINGLELINE|DT_VCENTER);
  177. textrect.top+=2;
  178. textrect.bottom-=2;
  179.         textrect.left-=1;  
  180. pdc->Draw3dRect(&textrect,::GetSysColor(COLOR_BTNFACE),::GetSysColor(COLOR_BTNFACE));
  181. }   
  182.     
  183. }
  184. void CEZMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
  185. {
  186. LPEZMENUITEMDATA  lpez=(LPEZMENUITEMDATA  )lpMeasureItemStruct->itemData;
  187. if(lpez->bSeperator) 
  188. {
  189. lpMeasureItemStruct->itemHeight=5;
  190. return;
  191. }
  192. CDC* pdc=new CDC;
  193. pdc->Attach(::GetDC(AfxGetMainWnd()->m_hWnd));
  194.     CSize szText=pdc->GetTextExtent(lpez->strItemText);  
  195. ::ReleaseDC(AfxGetMainWnd()->m_hWnd,pdc->m_hDC);
  196. delete pdc;
  197. if(lpez->bProgress) szText.cx+=100;
  198. lpMeasureItemStruct->itemWidth=szText.cx+(m_bLargeIcons?32:16)+m_szBitmapSize.cx+8;
  199. lpMeasureItemStruct->itemHeight=__max(m_bLargeIcons?32:16,szText.cy)+3;
  200.     m_nAveHeight=m_nItems*lpMeasureItemStruct->itemHeight;
  201.       
  202. }
  203. CEZMenu::~CEZMenu()
  204. {
  205. DestroyMenu();
  206. CMenu::~CMenu();
  207. }
  208. void CEZMenu::SetMenuBitmap(HBITMAP hBitmap)
  209. {
  210. m_bitmap.Attach(hBitmap);
  211. }
  212. void CEZMenu::SetLargeIcon(BOOL bLarge)
  213. {
  214. m_bLargeIcons=bLarge;
  215. }
  216. void CEZMenu::AppendOwnerDrawnItem(UINT nID, LPEZMENUITEMDATA lpez)
  217. {
  218. VERIFY(AppendMenu(MF_ENABLED | MF_OWNERDRAW, nID,(LPCTSTR)lpez));
  219. }
  220. void CEZMenu::SetBitmapDimension(CSize sz)
  221. {
  222. m_szBitmapSize=sz;
  223. }
  224. void CEZMenu::InsertOwnerDrawnMenuItem(UINT nID, LPEZMENUITEMDATA lpez,int nPos)
  225. {
  226. VERIFY(InsertMenu(nPos,MF_BYPOSITION|MF_ENABLED | MF_OWNERDRAW, nID,(LPCTSTR)lpez));
  227. }
  228. void CEZMenu::SetExtensionColor(COLORREF clrExtend)
  229. {
  230. m_clrExtend=clrExtend; 
  231. }
  232. void CEZMenu::SetTotalItems(int nItems)
  233. {
  234. m_nItems=nItems;
  235. }
  236. CEZMenuItemData::CEZMenuItemData()
  237. {
  238. bChecked=FALSE;
  239. bProgress=FALSE;
  240.     bSeperator=FALSE;
  241. hItemIconLarge=hItemIconSmall=NULL;
  242. nProgress=0;
  243. strItemText.Empty();
  244. }
  245. void CEZMenu::ModifyOwnerDrawnMenuItem(int nPos, UINT nID, int nTotalCheck,LPEZMENUITEMDATA lpez)
  246. {
  247.     //Iam not sure how to implement this.Suggestions are welcome.    
  248. //if(GetMenuItemCount()>(UINT)nTotalCheck)?
  249. VERIFY(ModifyMenu(nPos,MF_BYPOSITION|MF_OWNERDRAW,nID,(LPCTSTR)lpez));
  250. //else
  251. // InsertOwnerDrawnMenuItem(nID,lpez,nPos);
  252. }