PeeperMenu.cpp
上传用户:xztxsm
上传日期:2007-02-12
资源大小:150k
文件大小:14k
源码类别:

远程控制编程

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // 远程控制软件-偷窥者  菜单类                                               //
  3. // 日期:2001/10/02                                                           //
  4. // 作者:刘东发                                                               //
  5. // Email:dongfa@yeah.net                                                     //
  6. // http://dongfa.yeah.net                                                    //
  7. // OICQ:5584173  阿东                                                        //
  8. // 作者声明:                                                                 //
  9. //     此部分代码全是作者所写,可以随便传播,但要保持文件的完整性,有问题     //
  10. // 或者意见请来信,谢谢!                                                      //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include "stdafx.h"
  13. #include "PeeperMenu.h"
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[]=__FILE__;
  17. #define new DEBUG_NEW
  18. #endif
  19. #define MEMU_SYSCOLOR GetSysColor(COLOR_MENU)
  20. #define TOP_COLOR RGB(128, 128, 128)
  21. #define BOTTOM_COLOR RGB(255, 255, 255)
  22. CPeeperMenu::CPeeperMenu()
  23. {
  24. m_nMenuHeight = 24;
  25. m_nMenuWidth = 48;
  26. m_nSepHeight = 12;
  27. m_nSpace = 4;
  28. m_ilImageList.DeleteImageList();
  29. m_uIDArray.RemoveAll();
  30. m_uBackBmpID = 0;
  31. m_szMenuBk = CSize(0, 0);
  32. m_szMenuIcon = CSize(0, 0);
  33. }
  34. CPeeperMenu::~CPeeperMenu()
  35. {
  36. ClearMemory();
  37. }
  38. void CPeeperMenu::ClearMemory()
  39. {
  40. POSITION pos = m_obMenuList.GetHeadPosition();
  41. while(pos)
  42. {
  43. LPPEEPERMENU lpMenu = (LPPEEPERMENU)m_obMenuList.GetNext(pos);
  44. if(lpMenu)
  45. {
  46. delete lpMenu;
  47. lpMenu = NULL;
  48. }
  49. }
  50. m_obMenuList.RemoveAll();
  51. m_ilImageList.DeleteImageList();
  52. m_uIDArray.RemoveAll();
  53. }
  54. BOOL CPeeperMenu::ChangeStyle(HMENU hMenu, BOOL bTop)
  55. {
  56. CMenu *pMenu = CMenu::FromHandle(hMenu);
  57. if(pMenu != NULL)
  58. {
  59. for(UINT i = 0; i < pMenu->GetMenuItemCount(); i ++)
  60. {
  61. LPPEEPERMENU lpMenu = new PEEPERMENU;
  62. lpMenu->nMenuID = pMenu->GetMenuItemID(i);
  63. if(lpMenu->nMenuID < 0 && bTop)
  64. {
  65. lpMenu->nMenuID = -2;
  66. }
  67. pMenu->GetMenuString(i, lpMenu->strText, MF_BYPOSITION);
  68. pMenu->ModifyMenu(i, MF_BYPOSITION | MF_OWNERDRAW,
  69. lpMenu->nMenuID, LPCTSTR(lpMenu));
  70. CMenu *pSubMenu = pMenu->GetSubMenu(i);
  71. if(pSubMenu && lpMenu->nMenuID != -2 && !bTop)
  72. {
  73. lpMenu->nMenuID = -1;
  74. }
  75. m_obMenuList.AddTail((CObject *)lpMenu);
  76. if(pSubMenu)
  77. {
  78. ChangeStyle(pSubMenu->GetSafeHmenu());
  79. }
  80. }
  81. }
  82. return TRUE;
  83. }
  84. BOOL CPeeperMenu::LoadMenu(UINT uMenuID, UINT uToolBarID, CSize sz)
  85. {
  86. BOOL bRet = CMenu::LoadMenu(uMenuID);
  87. ChangeStyle(GetSafeHmenu(), TRUE);
  88. return bRet;
  89. }
  90. BOOL CPeeperMenu::AttachMenu(HMENU hMenu, UINT uToolBarID, CSize sz)
  91. {
  92. ClearMemory();
  93. Attach(hMenu);
  94. ChangeStyle(GetSafeHmenu(), TRUE);
  95. m_szMenuIcon = sz;
  96. int nRet = GetImageFromToolBar(uToolBarID, sz, &m_ilImageList, &m_uIDArray);
  97. return TRUE;
  98. }
  99. BOOL CPeeperMenu::DetachMenu()
  100. {
  101. ClearMemory();
  102. Detach();
  103. return TRUE;
  104. }
  105. void CPeeperMenu::AppendMenu(UINT uID, CString strText)
  106. {
  107. }
  108. void CPeeperMenu::SetBkImage(UINT uID)
  109. {
  110. m_uBackBmpID = uID;
  111. CBitmap bmp;
  112. bmp.LoadBitmap(m_uBackBmpID);
  113. if(bmp.GetSafeHandle() != NULL)
  114. {
  115. BITMAP bm;
  116. bmp.GetBitmap(&bm);
  117. m_szMenuBk.cx = bm.bmWidth;
  118. m_szMenuBk.cy = bm.bmHeight;
  119. }
  120. else
  121. {
  122. m_szMenuBk = CSize(0, 0);
  123. }
  124. }
  125. int CPeeperMenu::GetIndexByID(UINT uID)
  126. {
  127. for(int i = 0; i < m_uIDArray.GetSize(); i ++)
  128. {
  129. if(uID == m_uIDArray[i])
  130. {
  131. ASSERT(i < m_ilImageList.GetImageCount());
  132. return i;
  133. }
  134. }
  135. return -1;
  136. }
  137. int CPeeperMenu::AddToolBar(UINT uToolBarID, CSize sz)
  138. {
  139. CImageList ilImage;
  140. CUIntArray uIDArray;
  141. int nRet = GetImageFromToolBar(uToolBarID, sz, &ilImage, &uIDArray);
  142. if(nRet > 0)
  143. {
  144. for(int i = 0; i < ilImage.GetImageCount(); i ++)
  145. {
  146. HICON hIcon = ilImage.ExtractIcon(i);
  147. if(hIcon != NULL)
  148. {
  149. m_ilImageList.Add(hIcon);
  150. m_uIDArray.Add(uIDArray[i]);
  151. }
  152. }
  153. }
  154. return nRet;
  155. }
  156. int CPeeperMenu::GetImageFromToolBar(UINT uToolBarID, CSize sz, CImageList *pImageList, 
  157.  CUIntArray *uIDArray)
  158. {
  159. if(uToolBarID <= 0 || pImageList == NULL || uIDArray == NULL)
  160. return -1;
  161. CToolBar wndToolBar;
  162. if(!wndToolBar.Create(AfxGetMainWnd()) || !wndToolBar.LoadToolBar(uToolBarID))
  163. {
  164. return -1;
  165. }
  166. int nCount = wndToolBar.GetCount();
  167. if(nCount <= 0)
  168. {
  169. return -1;
  170. }
  171. pImageList->Create(uToolBarID, sz.cx, sz.cy, MEMU_SYSCOLOR);
  172. int nImageCount = pImageList->GetImageCount();
  173. for(int i = 0; i < nCount; i ++)
  174. {
  175. UINT uID = wndToolBar.GetItemID(i);
  176. if(uID != ID_SEPARATOR)
  177. {
  178. uIDArray->Add(uID);
  179. }
  180. }
  181. int nSize = uIDArray->GetSize();
  182. ASSERT(nSize == nImageCount);
  183. return nSize;
  184. }
  185. int CPeeperMenu::DrawBmp(CDC *pDC, UINT uID, CRect rect, BOOL bStretch)
  186. {
  187. HRSRC hSrc = FindResource(NULL, MAKEINTRESOURCE(uID), RT_BITMAP);
  188. if(hSrc)
  189. {
  190. CBitmap bmp;
  191. bmp.LoadBitmap(uID);
  192. if(bmp.GetSafeHandle() != NULL)
  193. {
  194. BITMAP bm;
  195. bmp.GetBitmap(&bm);
  196. CDC memDC;
  197. memDC.CreateCompatibleDC(pDC);
  198. CBitmap *pOldBmp = memDC.SelectObject(&bmp);
  199. if(bStretch)
  200. {
  201. pDC->SetStretchBltMode(COLORONCOLOR);
  202. pDC->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(),
  203. &memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
  204. }
  205. else
  206. {
  207. pDC->BitBlt(rect.left, rect.top, bm.bmWidth, bm.bmHeight,
  208. &memDC, 0, 0, SRCCOPY);
  209. }
  210. memDC.SelectObject(&pOldBmp);
  211. memDC.DeleteDC();
  212. }
  213. }
  214. return 0;
  215. }
  216. void CPeeperMenu::DrawGradRect(CDC *pDC, CRect rect, COLORREF cr1, 
  217.    COLORREF cr2, BOOL bHor)
  218. {
  219. int r1 = GetRValue(cr1);
  220. int g1 = GetGValue(cr1);
  221. int b1 = GetBValue(cr1);
  222. int r2 = GetRValue(cr2);
  223. int g2 = GetGValue(cr2);
  224. int b2 = GetBValue(cr2);
  225. if(bHor)
  226. {
  227. float dr = ((float)(r2 - r1))/(float)(rect.Width());
  228. float dg = ((float)(g2 - g1))/(float)(rect.Width());
  229. float db = ((float)(b2 - b1))/(float)(rect.Width());
  230. for(int i = rect.left; i < rect.right; i ++)
  231. {
  232. int r = r1 + (int)(dr*((float)(i - rect.left)));
  233. int g = g1 + (int)(dg*((float)(i - rect.left)));
  234. int b = b1 + (int)(db*((float)(i - rect.left)));
  235. CPen pen(PS_SOLID, 1, RGB(r, g, b));
  236. CPen *old = pDC->SelectObject(&pen);
  237. pDC->MoveTo(i, rect.top);
  238. pDC->LineTo(i, rect.bottom);
  239. pDC->SelectObject(old);
  240. }
  241. }
  242. else
  243. {
  244. float dr = ((float)(r2 - r1))/(float)(rect.Height());
  245. float dg = ((float)(g2 - g1))/(float)(rect.Height());
  246. float db = ((float)(b2 - b1))/(float)(rect.Height());
  247. for(int i = rect.top; i < rect.bottom; i ++)
  248. {
  249. int r = r1 + (int)(dr*((float)(i - rect.top)));
  250. int g = g1 + (int)(dg*((float)(i - rect.top)));
  251. int b = b1 + (int)(db*((float)(i - rect.top)));
  252. CPen pen(PS_SOLID, 1, RGB(r, g, b));
  253. CPen *old = pDC->SelectObject(&pen);
  254. pDC->MoveTo(rect.left, i);
  255. pDC->LineTo(rect.right, i);
  256. pDC->SelectObject(old);
  257. }
  258. }
  259. }
  260. void CPeeperMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  261. {
  262. LPPEEPERMENU lpMenu = (LPPEEPERMENU)(lpDIS->itemData);
  263. if(!AfxIsValidAddress(lpMenu, sizeof(PEEPERMENU)))
  264. return ;
  265. CDC *pDC = CDC::FromHandle(lpDIS->hDC);
  266. const CRect rect = lpDIS->rcItem;
  267. BOOL bIsSelected = FALSE;
  268. BOOL bIsChecked  = FALSE;
  269. BOOL bIsGrayed   = FALSE;
  270. BOOL bHasImage   = FALSE;
  271. //取得菜单状态
  272. bIsSelected = (lpDIS->itemState & ODS_SELECTED);
  273. bIsChecked  = (lpDIS->itemState & ODS_CHECKED);
  274. bIsGrayed   = (lpDIS->itemState & ODS_GRAYED);
  275. CRect rc = rect;
  276. pDC->SetBkMode(TRANSPARENT);
  277. pDC->SelectStockObject(NULL_BRUSH);
  278. if(lpMenu->nMenuID == 0)// 分隔条
  279. {
  280. CRect rc = rect;
  281. rc.top = rect.Height()/2 + rect.top;
  282. rc.bottom = rc.top + 2;
  283. rc.left += (m_szMenuBk.cx + m_nSpace);
  284. pDC->Draw3dRect(rc, TOP_COLOR, BOTTOM_COLOR);
  285. }
  286. else // 显示文字或者图标
  287. {
  288. //先画图标
  289. int nIndex = GetIndexByID(lpMenu->nMenuID);
  290. if(nIndex >= 0) // 如果有图片标
  291. {
  292. bHasImage = TRUE; //设置有图像标志
  293. rc = rect;
  294. rc.left += (m_szMenuBk.cx + m_nSpace);
  295. int n = (rect.Height() - m_szMenuIcon.cy)/2;
  296. rc.top += (n + 1);
  297. m_ilImageList.Draw(pDC, nIndex, CPoint(rc.left, rc.top), ILD_TRANSPARENT);
  298. CRect rc1 = CRect(rc.left, rc.top, rc.left + m_szMenuIcon.cx, 
  299. rc.top + m_szMenuIcon.cy);
  300. rc = rc1;
  301. rc.InflateRect(m_nSpace/2, m_nSpace/2);
  302. if(bIsChecked) //如果有图像并且是Check状态
  303. {
  304. pDC->Draw3dRect(rc, TOP_COLOR, BOTTOM_COLOR);
  305. }
  306. else // 没有Check但是有图像
  307. {
  308. rc.InflateRect(1, 1);
  309. if(bIsSelected)
  310. {
  311. pDC->Draw3dRect(rc, BOTTOM_COLOR, TOP_COLOR);
  312. }
  313. else
  314. {
  315. pDC->Draw3dRect(rc, MEMU_SYSCOLOR, MEMU_SYSCOLOR);
  316. }
  317. }
  318. }
  319. else // 如果没有使用缺省的
  320. {
  321. bHasImage = FALSE; //设置无图像标志
  322. if(bIsChecked)
  323. {
  324. bHasImage = TRUE; //设置有图像标志
  325. rc = rect;
  326. rc.left += (m_szMenuBk.cx + m_nSpace);
  327. int n = (rect.Height() - m_szMenuIcon.cy)/2;
  328. rc.top += (n + 1);
  329. CRect rc1 = CRect(rc.left, rc.top, rc.left + m_szMenuIcon.cx, 
  330. rc.top + m_szMenuIcon.cy);
  331. pDC->SetTextColor(RGB(0, 64, 255));
  332. pDC->DrawText(_T("√"), &rc1, DT_EXPANDTABS | DT_VCENTER |
  333. DT_SINGLELINE | DT_CENTER);
  334. rc = rc1;
  335. rc.left += 1;
  336. rc.top += 1;
  337. pDC->DrawText(_T("√"), &rc, DT_EXPANDTABS | DT_VCENTER |
  338. DT_SINGLELINE | DT_CENTER);
  339. rc1.InflateRect(m_nSpace/2, m_nSpace/2);
  340. pDC->Draw3dRect(rc1, TOP_COLOR, BOTTOM_COLOR);
  341. }
  342. }
  343. //显示菜单文字
  344. if(bIsGrayed) // 是禁止菜单
  345. {
  346. rc = rect;
  347. rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*2);
  348. rc.DeflateRect(0, m_nSpace/2, 0, m_nSpace/2 - 1);
  349. if(bIsSelected) // 如果是禁止菜单,并且是被选择
  350. {
  351. CRect rc1 = rc;
  352. if(!bHasImage)
  353. {
  354. rc1.left -= (m_szMenuIcon.cx + m_nSpace);
  355. }
  356. DrawGradRect(pDC, rc1, RGB(64, 0, 255), RGB(192, 192, 192));
  357. if(lpMenu->strText.GetLength() > 0)
  358. {
  359. rc = rect;
  360. rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*3);
  361. pDC->SetTextColor(TOP_COLOR);
  362. pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
  363. }
  364. }
  365. else // 如果是禁止菜单但没有被选择
  366. {
  367. CRect rc1 = rc;
  368. if(!bHasImage)
  369. {
  370. rc1.left -= (m_szMenuIcon.cx + m_nSpace);
  371. }
  372. pDC->FillSolidRect(rc1, MEMU_SYSCOLOR);
  373. if(lpMenu->strText.GetLength() > 0)
  374. {
  375. rc = rect;
  376. rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*3);
  377. pDC->SetTextColor(BOTTOM_COLOR);
  378. pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
  379. pDC->SetTextColor(TOP_COLOR);
  380. rc.left -= 1;
  381. rc.top -= 1;
  382. pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
  383. }
  384. }
  385. }
  386. else // 不是禁止菜单
  387. {
  388. if(lpMenu->nMenuID == -2) // 顶层菜单
  389. {
  390. rc = rect;
  391. rc.left += m_nSpace*2;
  392. if(bIsSelected) // 是选择状态
  393. {
  394. pDC->Draw3dRect(rc, TOP_COLOR, BOTTOM_COLOR);
  395. pDC->SetTextColor(RGB(0, 0, 128));
  396. }
  397. else // 不是选择状态
  398. {
  399. pDC->Draw3dRect(rc, MEMU_SYSCOLOR, MEMU_SYSCOLOR);
  400. pDC->SetTextColor(RGB(64, 0, 128));
  401. }
  402. rc.left += m_nSpace;
  403. if(lpMenu->strText.GetLength() > 0)
  404. {
  405. pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | 
  406. DT_VCENTER | DT_SINGLELINE);
  407. }
  408. }
  409. else // 不是顶层菜单,是弹出菜单或者一个菜单项目
  410. {
  411. rc = rect;
  412. rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*2);
  413. rc.DeflateRect(0, m_nSpace/2, 0, m_nSpace/2 - 1);
  414. if(bIsSelected)
  415. {
  416. CRect rc1 = rc;
  417. if(!bHasImage)
  418. {
  419. rc1.left -= (m_szMenuIcon.cx + m_nSpace);
  420. }
  421. DrawGradRect(pDC, rc1, RGB(64, 0, 255), RGB(192, 192, 192));
  422. pDC->SetTextColor(BOTTOM_COLOR);
  423. }
  424. else
  425. {
  426. CRect rc1 = rc;
  427. if(!bHasImage)
  428. {
  429. rc1.left -= (m_szMenuIcon.cx + m_nSpace);
  430. }
  431. pDC->FillSolidRect(rc1, MEMU_SYSCOLOR);
  432. pDC->SetTextColor(RGB(64, 0, 128));
  433. }
  434. if(lpMenu->strText.GetLength() > 0)
  435. {
  436. rc = rect;
  437. rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*3);
  438. pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS |
  439. DT_VCENTER | DT_SINGLELINE);
  440. }
  441. }
  442. }
  443. }
  444. if((lpDIS->itemAction & ODA_DRAWENTIRE) && lpMenu->nMenuID != -2)
  445. {
  446. // DrawBmp(pDC, m_uBackBmpID, CRect(1, 1, -1, -1), FALSE);
  447. DrawGradRect(pDC, CRect(0, 0, m_szMenuBk.cx, rect.bottom), 
  448. RGB(0, 0, 0), RGB(0, 0, 255), FALSE);
  449. }
  450. }
  451. void CPeeperMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
  452. {
  453. LPPEEPERMENU lpMenu = (LPPEEPERMENU)(lpMIS->itemData);
  454. if(lpMenu->nMenuID == 0)
  455. {
  456. lpMIS->itemHeight = m_nSepHeight;
  457. lpMIS->itemWidth = 100;
  458. }
  459. else
  460. {
  461. lpMIS->itemWidth = m_nMenuWidth; // default
  462. CString strText = lpMenu->strText;
  463. int nLen = strText.GetLength();
  464. if(nLen > 0)
  465. {
  466. CFont fontMenu;
  467. LOGFONT lf;
  468. ZeroMemory(&lf, sizeof(LOGFONT));
  469. NONCLIENTMETRICS nm;
  470. nm.cbSize = sizeof(NONCLIENTMETRICS);
  471. VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
  472. nm.cbSize, &nm, 0)); 
  473. lf = nm.lfMenuFont;
  474. fontMenu.CreateFontIndirect(&lf);
  475. SIZE sz;
  476. CDC *pDC = AfxGetMainWnd()->GetDC();
  477. CFont *old = pDC->SelectObject(&fontMenu);
  478. ::GetTextExtentPoint32(pDC->GetSafeHdc(), strText, strText.GetLength(), &sz);
  479. if(lpMenu->nMenuID == -2)
  480. {
  481. lpMIS->itemWidth = sz.cx + m_nSpace;
  482. }
  483. else
  484. {
  485. lpMIS->itemWidth = sz.cx + m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*4;
  486. }
  487. pDC->SelectObject(&old);
  488.     AfxGetMainWnd()->ReleaseDC(pDC);
  489. fontMenu.DeleteObject();
  490. }
  491. lpMIS->itemHeight = m_nMenuHeight;
  492. }
  493. }