MyMenu.cpp
上传用户:jzscgs158
上传日期:2022-05-25
资源大小:8709k
文件大小:14k
源码类别:

百货/超市行业

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "MyMenu.h"
  3. #ifdef _DEBUG
  4. #undef THIS_FILE
  5. static char THIS_FILE[]=__FILE__;
  6. #define new DEBUG_NEW
  7. #endif
  8. CMyMenu::CMyMenu()
  9. {
  10. //构造
  11. m_topStyle=1;
  12. m_clrSelectLeft=RGB(97,244,78);
  13. m_clrSelectRight=RGB(52,148,39);
  14. m_clrTop=RGB(161,192,245);
  15. m_clrText=RGB(0,0,0);
  16. }
  17. CMyMenu::~CMyMenu()
  18. {
  19. //析构
  20. }
  21. /**********************************************************
  22. 函  数  名:GetImageFromToolBar
  23. 作      用:从工具栏中取出图片
  24. 形  参  数:UINT uToolBarID, CSize sz, CImageList *pImageList,  CUIntArray *uIDArray
  25. 返 回  值:返回 ImageCount
  26. ***********************************************************/
  27. int CMyMenu::GetImageFromToolBar(UINT uToolBarID, CSize sz, CImageList *pImageList,  CUIntArray *uIDArray)
  28. {
  29. if(uToolBarID <= 0 || pImageList == NULL || uIDArray == NULL)
  30. return -1;
  31. CToolBar wndToolBar;
  32. if(!wndToolBar.Create(AfxGetMainWnd()) || !wndToolBar.LoadToolBar(uToolBarID))
  33. {
  34. return -1;
  35. }
  36. int nCount = wndToolBar.GetCount();
  37. if(nCount <= 0)
  38. {
  39. return -1;
  40. }
  41. COLORREF Maskcol=RGB(192,192,192);
  42. pImageList->Create(uToolBarID, sz.cx, sz.cy, Maskcol);
  43. int nImageCount = pImageList->GetImageCount();
  44. for(int i = 0; i < nCount; i ++)
  45. {
  46. UINT uID = wndToolBar.GetItemID(i);
  47. if(uID != ID_SEPARATOR)
  48. {
  49. uIDArray->Add(uID);
  50. }
  51. }
  52. int nSize = uIDArray->GetSize();
  53. ASSERT(nSize == nImageCount);
  54. return nSize;
  55. }
  56. /**********************************************************
  57. 函  数  名:GetIconIndexByID
  58. 作      用:从ImageList 中取出图标的索引
  59. 形  参  数:UINT uID
  60. 返 回  值:成功时返回索引,否则返回-1
  61. ***********************************************************/
  62. int CMyMenu::GetIconIndexByID(UINT uID)
  63. {
  64. for(int i = 0; i < m_menuIDs.GetSize(); i ++)
  65. {
  66. if(uID == m_menuIDs[i])
  67. {
  68. ASSERT(i < m_ImageList.GetImageCount());
  69. return i;
  70. }
  71. }
  72. return -1;
  73. }
  74. /**********************************************************
  75. 函  数  名:ChangeMenuStyle
  76. 作      用:改变主菜单的风格
  77. 形  参  数:HMENU hMenu, BOOL bTop
  78. 返 回  值:BOOL,dndn成功时返回真,失败时出错
  79. ***********************************************************/
  80. BOOL CMyMenu::ChangeMenuStyle(HMENU hMenu, BOOL bTop = FALSE)
  81. {
  82. CMenu *pMenu = CMenu::FromHandle(hMenu);
  83. if(pMenu != NULL)
  84. {
  85. for(UINT i = 0; i < pMenu->GetMenuItemCount(); i ++)
  86. {
  87. CMenuItemContext *lpMenu = new CMenuItemContext;
  88. lpMenu->nMenuID = pMenu->GetMenuItemID(i);
  89. if(lpMenu->nMenuID < 0 && bTop)
  90. {
  91. lpMenu->nMenuID = -2;
  92. }
  93. pMenu->GetMenuString(i, lpMenu->strText, MF_BYPOSITION);
  94. pMenu->ModifyMenu(i, MF_BYPOSITION | MF_OWNERDRAW,
  95. lpMenu->nMenuID, LPCTSTR(lpMenu));
  96. CMenu *pSubMenu = pMenu->GetSubMenu(i);
  97. if(pSubMenu && lpMenu->nMenuID != -2 && !bTop)
  98. {
  99. lpMenu->nMenuID = -1;
  100. }
  101. if(pSubMenu)
  102. {
  103. ChangeMenuStyle(pSubMenu->GetSafeHmenu());
  104. }
  105. }
  106. }
  107. return TRUE;
  108. }
  109. /**********************************************************
  110. 函  数  名:AttachMenu
  111. 作      用:将当前窗口的菜单与我的菜单关联
  112. 形  参  数:HMENU hMenu,UINT uToolBarID,CSize sz
  113. 返 回  值:BOOL,dndn成功时返回真,失败时出错
  114. ***********************************************************/
  115. BOOL CMyMenu::AttachMenu(HMENU hMenu,UINT uToolBarID,CSize sz)
  116. {
  117. Attach(hMenu);
  118. ChangeMenuStyle(GetSafeHmenu(), TRUE);
  119. if(uToolBarID!=0)
  120. GetImageFromToolBar(uToolBarID, sz, &m_ImageList, &m_menuIDs);
  121. return TRUE;
  122. }
  123. void CMyMenu::LoadMenu(UINT nIDResource)
  124. {
  125. ChangeMenuStyle(GetSafeHmenu(), TRUE);
  126. CMenu::LoadMenu(nIDResource);
  127. }
  128. /**********************************************************
  129. 函  数  名:AddToolBar
  130. 作      用:向列表添加
  131. 形  参  数:UINT uToolBarID, CSize sz
  132. 返 回  值:返回添加的个数
  133. ***********************************************************/
  134. UINT CMyMenu::AddToolBar(UINT uToolBarID, CSize sz=CSize(16,15))
  135. {
  136. CImageList Image;
  137. CUIntArray IDArray;
  138. int nRet = GetImageFromToolBar(uToolBarID, sz, &Image, &IDArray);
  139. if(nRet > 0)
  140. {
  141. for(int i = 0; i < Image.GetImageCount(); i ++)
  142. {
  143. HICON hIcon = Image.ExtractIcon(i);
  144. if(hIcon != NULL)
  145. {
  146. m_ImageList.Add(hIcon);
  147. m_menuIDs.Add(IDArray[i]);
  148. }
  149. }
  150. }
  151. return nRet;
  152. }
  153. /**********************************************************
  154. 函  数  名:DrawBestRect
  155. 作      用:画出最炫丽的效果来
  156. 形  参  数:CDC *pDC, CRect rect, COLORREF cr1,COLORREF cr2, BOOL bHor
  157. 返 回  值:NULL
  158. ***********************************************************/
  159. void CMyMenu::DrawBestRect(CDC *pDC, CRect rect, COLORREF cr1,COLORREF cr2, BOOL bHor)
  160. {
  161. int r1 = GetRValue(cr1);//Red color1
  162. int g1 = GetGValue(cr1);//Green color1
  163. int b1 = GetBValue(cr1);//blue color1
  164. int r2 = GetRValue(cr2);//red color2
  165. int g2 = GetGValue(cr2);//green color2
  166. int b2 = GetBValue(cr2);//blue color2
  167. if(bHor)
  168. {
  169. float dr = ((float)(r2 - r1))/(float)(rect.Width());
  170. float dg = ((float)(g2 - g1))/(float)(rect.Width());
  171. float db = ((float)(b2 - b1))/(float)(rect.Width());
  172. for(int i = rect.left; i < rect.right; i ++)
  173. {
  174. int r = r1 + (int)(dr*((float)(i - rect.left)));
  175. int g = g1 + (int)(dg*((float)(i - rect.left)));
  176. int b = b1 + (int)(db*((float)(i - rect.left)));
  177. CPen pen(PS_SOLID, 1, RGB(r, g, b));
  178. CPen *old = pDC->SelectObject(&pen);
  179. pDC->MoveTo(i, rect.top);
  180. pDC->LineTo(i, rect.bottom);
  181. pDC->SelectObject(old);
  182. }
  183. }
  184. else
  185. {
  186. float dr = ((float)(r2 - r1))/(float)(rect.Height());
  187. float dg = ((float)(g2 - g1))/(float)(rect.Height());
  188. float db = ((float)(b2 - b1))/(float)(rect.Height());
  189. for(int i = rect.top; i < rect.bottom; i ++)
  190. {
  191. int r = r1 + (int)(dr*((float)(i - rect.top)));
  192. int g = g1 + (int)(dg*((float)(i - rect.top)));
  193. int b = b1 + (int)(db*((float)(i - rect.top)));
  194. CPen pen(PS_SOLID, 1, RGB(r, g, b));
  195. CPen *old = pDC->SelectObject(&pen);
  196. pDC->MoveTo(rect.left, i);
  197. pDC->LineTo(rect.right, i);
  198. pDC->SelectObject(old);
  199. }
  200. }
  201. }
  202. /**********************************************************
  203. 函  数  名:DrawTop
  204. 作      用:画最顶端菜单
  205. 形  参  数:CDC *pDC,CRect rect,BOOL bSelected
  206. 返 回  值:NULL
  207. ***********************************************************/
  208. void CMyMenu::DrawTop(CDC *pDC,CRect rect,BOOL bSelected)
  209. {
  210. rcMain.top=rect.top;
  211. rcMain.bottom=rect.bottom;
  212. DrawTopBack(pDC);
  213. if(bSelected)
  214. {
  215. DrawBGColor(pDC,rect,TRUE);
  216. }
  217. else
  218. {
  219. DrawTopBack(pDC,rect);
  220. }
  221. }
  222. /**********************************************************
  223. 函  数  名:DrawBGColor
  224. 作      用:菜单项的背景由它来完成
  225. 形  参  数:CDC* pDC, CRect rect, BOOL bSelected
  226. 返 回  值:NULL
  227. ***********************************************************/
  228. void CMyMenu::DrawBGColor(CDC* pDC, CRect rect, BOOL bSelected)
  229. {
  230. if(bSelected)
  231. {
  232. pDC->SelectStockObject(NULL_BRUSH);
  233. pDC->SelectStockObject(BLACK_PEN);
  234. pDC->Rectangle(&rect);
  235. rect.DeflateRect(1, 1);
  236. DrawBestRect(pDC,rect,m_clrSelectLeft,m_clrSelectRight,TRUE);
  237. }
  238. else
  239. {
  240. CRect rcGray(rect);
  241. rcGray.right = rcGray.left + Public_Area;
  242. int r1=GetRValue(m_clrTop);
  243. int g1=GetGValue(m_clrTop);
  244. int b1=GetBValue(m_clrTop);
  245. for(int i=rcGray.Width()/2;i>=0;i--)
  246. {
  247. r1=(r1+5)>255?255:(r1+5);
  248. g1=(g1+5)>255?255:(g1+5);
  249. b1=(b1+5)>255?255:(b1+5);
  250. CPen pen(PS_SOLID, 1, RGB(r1, g1, b1));
  251. CPen *old = pDC->SelectObject(&pen);
  252. pDC->MoveTo(rcGray.left+i,rcGray.top);
  253. pDC->LineTo(rcGray.left+i,rcGray.bottom);
  254. pDC->MoveTo(rcGray.right-i,rcGray.top);
  255. pDC->LineTo(rcGray.right-i,rcGray.bottom);
  256. pDC->SelectObject(old);
  257. }
  258. CRect rcWhite(rect);
  259. rcWhite.left = rcGray.right;
  260. pDC->FillSolidRect(&rcWhite,RGB(0x000000F9, 0x000000F8, 0x000000F7));
  261. }
  262. }
  263. /**********************************************************
  264. 函  数  名:DrawIcon
  265. 作      用:画出图标
  266. 形  参  数:CDC* pDC, CRect rect, UINT uIndex, BOOL IsEnabled
  267. 返 回  值:NULL
  268. ***********************************************************/
  269. void CMyMenu::DrawIcon(CDC* pDC, CRect rect, UINT uIndex, BOOL IsEnabled)
  270. {
  271. rect.DeflateRect(3, 3, 3, 3);
  272. UINT uStyle =ILD_TRANSPARENT; //CImageList::Draw()绘制位图的风格
  273. if(IsEnabled)
  274. {
  275. uStyle |=ILD_BLEND50;//菜单无效所以位图也要经过处理
  276. }
  277. else
  278. {
  279. uStyle |=ILD_BLEND25 ;
  280. }
  281. m_ImageList.Draw(pDC, uIndex, CPoint(rect.left, rect.top), uStyle);
  282. // HICON hIcon = m_ImageList.ExtractIcon(uIndex);
  283. }
  284. /**********************************************************
  285. 函  数  名:DrawText
  286. 作      用:画出菜单项的文本
  287. 形  参  数:CDC* pDC, CRect rect, CString sText
  288. 返 回  值:NULL
  289. ***********************************************************/
  290. void CMyMenu::DrawText(CDC* pDC, CRect rect, CString sText)
  291. {
  292. rect.DeflateRect(4,0,0,0);
  293. pDC->SetTextColor(m_clrText);
  294. pDC->DrawText(sText, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
  295. }
  296. /**********************************************************
  297. 函  数  名:DrawGray
  298. 作      用:输出无效菜单项的文本
  299. 形  参  数:CDC* pDC, CRect rect, CString sText
  300. 返 回  值:NULL
  301. ***********************************************************/
  302. void CMyMenu::DrawGray(CDC* pDC, CRect rect, CString sText)
  303. {
  304. rect.DeflateRect(4, 0, 0, 0);
  305. CRect rt(rect);
  306. int nMode =pDC->SetBkMode(TRANSPARENT);
  307. pDC->SetTextColor(RGB(127,127,127));
  308. pDC->DrawText(sText,&rect,DT_EXPANDTABS|DT_VCENTER|DT_SINGLELINE);
  309. }
  310. /**********************************************************
  311. 函  数  名:DrawItem
  312. 作      用:分开画每一菜单项
  313. 形  参  数:LPDRAWITEMSTRUCT  lpDIS,菜单上下文
  314. 返 回  值:NULL
  315. ***********************************************************/
  316. void CMyMenu::DrawItem(LPDRAWITEMSTRUCT  lpDIS)
  317. {
  318. CDC* pDC = CDC::FromHandle(lpDIS->hDC); // get dc
  319. VERIFY(pDC);pDC->SetBkMode(TRANSPARENT);// get position
  320. CRect rcItem = lpDIS->rcItem;// get states
  321. UINT uState = lpDIS->itemState; // the data of menu item is NULL then return
  322. if(lpDIS->itemData == NULL) return;
  323. CString strText     = ((CMenuItemContext*)(lpDIS->itemData))->strText;
  324. CMenuItemContext *p=((CMenuItemContext*)(lpDIS->itemData));
  325. UINT nMenuID        = ((CMenuItemContext*)(lpDIS->itemData))->nMenuID;
  326. CRect rcIcon(rcItem);
  327. rcIcon.right = rcIcon.left + Public_Area;
  328. CRect rcText(rcItem);
  329. rcText.left  = rcIcon.right;
  330. switch(nMenuID)
  331. {
  332. case -2:// -2:顶层菜单条 
  333. if(uState&ODS_SELECTED)
  334. {
  335. DrawTop(pDC,rcItem,TRUE);
  336. }
  337. else
  338. {
  339. DrawTop(pDC,rcItem,FALSE);
  340. }
  341. DrawText(pDC,rcItem,strText);
  342. break;
  343. case -1://-1:弹出菜单  
  344. strText= "t   "+strText;
  345. if(uState&ODS_SELECTED)//被选择,
  346. {
  347. DrawBestRect(pDC,rcItem,m_clrSelectLeft,m_clrSelectRight,TRUE);
  348. }
  349. else
  350. {
  351. DrawBGColor(pDC,rcItem,FALSE);//
  352. }
  353. //DrawTop(pDC,rcItem,FALSE);
  354. rcText.left=2.5;
  355. DrawText(pDC,rcText,strText);
  356. break;
  357. case 0://0:分隔条  
  358. rcText.top =rcText.Height()/2+rcText.top ;
  359. rcText.bottom =rcText.top +2;
  360. rcText.left +=2;
  361. rcText.right -=2;
  362. DrawBGColor(pDC,rcItem,FALSE);
  363. pDC->Draw3dRect(rcText,RGB(64,0,128),RGB(255,255,255));
  364. break;
  365. default://>0:一般的菜单
  366. if(uState&ODS_SELECTED)//被选择,
  367. {
  368. DrawBGColor(pDC,rcItem,TRUE);
  369. }
  370. else
  371. {
  372. DrawBGColor(pDC,rcItem,FALSE);//
  373. }
  374. int nIndex = GetIconIndexByID(nMenuID);
  375. if(uState&ODS_GRAYED)
  376. {
  377. if(nIndex >= 0) 
  378. {
  379. if(m_ImageList.GetImageCount()>0)
  380. DrawIcon(pDC,rcItem,nIndex,TRUE);
  381. }
  382. DrawGray(pDC,rcText,strText);
  383. break;
  384. }
  385. else
  386. {
  387. if(nIndex >= 0) 
  388. {
  389. if(m_ImageList.GetImageCount()>0)
  390. if(uState&ODS_SELECTED)
  391. {
  392. CRect rcMy(rcItem);
  393. rcMy.left=rcMy.left-2;
  394. rcMy.top=rcMy.top-2;
  395. DrawIcon(pDC,rcMy,nIndex,FALSE);
  396. }
  397. else 
  398. {
  399. DrawIcon(pDC,rcItem,nIndex,FALSE);
  400. }
  401. }
  402. }
  403. if(uState&ODS_CHECKED)//是被check过的,
  404. {
  405. DrawText(pDC,rcItem,"√");
  406. DrawText(pDC,rcText,strText);//当前状态是check!
  407. break;
  408. }
  409. else
  410. {
  411. DrawText(pDC,rcText,strText);//未选取
  412. break;
  413. }
  414. break;
  415. }
  416. }
  417. /**********************************************************
  418. 函  数  名:MeasureItem
  419. 作      用:设置每一项的风格等
  420. 形  参  数:LPMEASUREITEMSTRUCT lpMIS要用到的结构
  421. 返 回  值:NULL
  422. ***********************************************************/
  423. void CMyMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
  424. {
  425. lpMIS->itemWidth = 60;
  426. lpMIS->itemHeight = 24;
  427. UINT nMenuID= ((CMenuItemContext*)(lpMIS->itemData))->nMenuID;
  428. //dc.SelectObject();
  429. //CSize sz=
  430. switch(nMenuID)
  431. {
  432. case -2:// -2:顶层菜单条  
  433. lpMIS->itemWidth =80;
  434. rcMain.left=this->GetMenuItemCount()*(lpMIS->itemWidth+12.8);
  435. break;
  436. case -1://-1:弹出菜单  
  437. lpMIS->itemWidth =((CMenuItemContext*)(lpMIS->itemData))->strText.GetLength()*10;
  438. break;
  439. case 0://0:分隔条
  440. lpMIS->itemHeight =5;
  441. break;
  442. default://>0:一般的菜单
  443. lpMIS->itemWidth =((CMenuItemContext*)(lpMIS->itemData))->strText.GetLength()*10;
  444. break; // lpMIS->itemWidth =30;
  445. }
  446. }
  447. void CMyMenu::SetTopBack(COLORREF clr)
  448. {
  449. m_topStyle=BACK_COLOR;
  450. m_clrTop=clr;
  451. }
  452. void CMyMenu::DrawTopBack(CDC* pDC,CRect rcSourse)
  453. {
  454. pDC->MoveTo(rcSourse.left,rcSourse.top);
  455. pDC->LineTo(rcSourse.right,rcSourse.top);
  456. if(m_topStyle==BACK_COLOR)
  457. {
  458. int r1=GetRValue(m_clrTop);
  459. int g1=GetGValue(m_clrTop);
  460. int b1=GetBValue(m_clrTop);
  461. for(int i=rcSourse.Height()/2;i>0;i--)
  462. {
  463. r1=(r1+4)>255?255:(r1+4);
  464. g1=(g1+4)>255?255:(g1+4);
  465. b1=(b1+4)>255?255:(b1+4);
  466. CPen pen(PS_SOLID, 1, RGB(r1, g1, b1));
  467. CPen *old = pDC->SelectObject(&pen);
  468. pDC->MoveTo(rcSourse.left,rcSourse.top+i);
  469. pDC->LineTo(rcSourse.right,rcSourse.top+i);
  470. pDC->MoveTo(rcSourse.left,rcSourse.bottom-i);
  471. pDC->LineTo(rcSourse.right,rcSourse.bottom-i);
  472. pDC->SelectObject(old);
  473. }
  474. }
  475. else if(m_topStyle==BACK_PICTURE)
  476. {
  477. pDC->FillRect(rcSourse,&m_backbrush);
  478. }
  479. }
  480. void CMyMenu::DrawTopBack(CDC* pDC)
  481. {
  482. if(m_topStyle==BACK_COLOR)
  483. {
  484. DrawTopBack(pDC,rcMain);
  485. }
  486. else if(m_topStyle==BACK_PICTURE)
  487. {
  488. pDC->FillRect(rcMain,&m_backbrush);
  489. }
  490. }
  491. void CMyMenu::SetTopBackImage(UINT nIDResource)
  492. {
  493. CBitmap tmp;
  494. m_topStyle=BACK_PICTURE;
  495. tmp.LoadBitmap(nIDResource);
  496. m_backbrush.DeleteObject();
  497. m_backbrush.CreatePatternBrush(&tmp); 
  498. }