FreeMenu.cpp
上传用户:wgl7269
上传日期:2007-01-02
资源大小:35k
文件大小:13k
源码类别:

菜单

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "MenuItemWnd.h"
  3. #include "FreeMenu.h"
  4. CFreeMenu::CFreeMenu(UINT ID,
  5.       CPoint beginP,
  6.   CWnd *ParentWnd,
  7.   COLORREF BackGroundColor,
  8.   COLORREF EdgeLUColor,
  9.   COLORREF EdgeRDColor,
  10.   COLORREF TextColor,
  11.   CFont *font,
  12.   int pflags,
  13.   CFreeMenu *parentMenu
  14. )
  15. {
  16. int count;
  17. m_parentMenu = parentMenu;
  18. m_Menu = new CMenu;
  19. m_Menu->LoadMenu(ID);
  20. count = m_Menu->GetMenuItemCount();
  21. m_selfWnd = new CMenuItemWnd;
  22. m_selfWnd->freeMenu = this;
  23. m_IsVisible = FALSE;
  24. m_ParentWnd = ParentWnd;
  25. m_BackGroundColor = BackGroundColor;
  26. m_EdgeLUColor = EdgeLUColor;
  27. m_EdgeRDColor = EdgeRDColor;
  28. m_TextColor = TextColor;
  29. m_font = font;
  30. MenuBeginPoint = beginP;
  31. flags = pflags;
  32. m_goby = -1;
  33. m_selected = -1;
  34. for(int i=0;i<count;i++)
  35. {
  36. CMenu *menu = m_Menu->GetSubMenu(i);
  37. if(menu)
  38. {
  39. CRect rect = GetItemRect(m_Menu,i);
  40. CPoint p;
  41. if(flags == 1)
  42. {
  43. p.x = rect.left;
  44. p.y = rect.bottom+1;
  45. }
  46. else
  47. {
  48. p.x = rect.right + 1;
  49. p.y = rect.top;
  50. }
  51. p.Offset(beginP);
  52. CFreeMenu *submenu = new CFreeMenu(menu,p,ParentWnd,
  53. BackGroundColor,EdgeLUColor,EdgeRDColor,TextColor,font,0,this);
  54. SubMenu.Add(submenu);
  55. }
  56. else
  57.  SubMenu.Add(NULL);
  58. }
  59. DrawMenu();
  60. }
  61. CFreeMenu::CFreeMenu(CMenu *menu,
  62.       CPoint beginP,
  63.   CWnd *ParentWnd,
  64.   COLORREF BackGroundColor,
  65.   COLORREF EdgeLUColor,
  66.   COLORREF EdgeRDColor,
  67.   COLORREF TextColor,
  68.   CFont *font,
  69.   int pflags,
  70.   CFreeMenu *parentMenu
  71. )
  72. {
  73. m_parentMenu = parentMenu;
  74. m_Menu = menu;
  75. m_ParentWnd = ParentWnd;
  76. m_BackGroundColor = BackGroundColor;
  77. m_EdgeLUColor = EdgeLUColor;
  78. m_EdgeRDColor = EdgeRDColor;
  79. m_TextColor = TextColor;
  80. m_font = font;
  81. m_goby = -1;
  82. m_selected = -1;
  83. MenuBeginPoint = beginP;
  84. flags = pflags;
  85. m_selfWnd = new CMenuItemWnd;
  86. m_selfWnd->freeMenu = this;
  87. m_IsVisible = FALSE;
  88. int count = m_Menu->GetMenuItemCount();
  89. for(int i=0;i<count;i++)
  90. {
  91. CMenu *menu = m_Menu->GetSubMenu(i);
  92. if(menu)
  93. {
  94. CRect rect = GetItemRect(m_Menu,i);
  95. CPoint p;
  96. if(flags == 1)
  97. {
  98. p.x = rect.left;
  99. p.y = rect.bottom+1;
  100. }
  101. else
  102. {
  103. p.x = rect.right + 1;
  104. p.y = rect.top;
  105. }
  106. p.Offset(beginP);
  107. CFreeMenu *submenu = new CFreeMenu(menu,p,ParentWnd,
  108. BackGroundColor,EdgeLUColor,EdgeRDColor,TextColor,font,0,this);
  109. SubMenu.Add(submenu);
  110. }
  111. else
  112. SubMenu.Add(NULL);
  113. }
  114. }
  115. void CFreeMenu::DrawMenu()
  116. {
  117. //flags---0 竖排    1横排
  118. //state---0 普通    1选中
  119. //selected 当前选中项
  120. //CDC *pDC = m_ParentWnd->GetDC();
  121. //Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, 
  122. //const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
  123. CMenu *menu = m_Menu;
  124. CWnd *wndtemp = CWnd::GetDesktopWindow();
  125. CDC *ppDC = wndtemp->GetDC();
  126. CPoint point = MenuBeginPoint;
  127. int count;
  128. CSize textSizeMax(0,0);
  129. CRect boardRect;
  130. CString st;
  131. count = menu->GetMenuItemCount();
  132. int curWidth = 0;
  133. CSize size(0,0);
  134. CFont *oldFont;
  135. oldFont = ppDC->SelectObject(m_font);
  136. CBrush *brush,*oldBrush;
  137. brush = new CBrush(m_BackGroundColor);
  138. oldBrush = ppDC->SelectObject(brush);
  139. for(int i=0;i<count;i++)
  140. {
  141. menu->GetMenuString(i,st,MF_BYPOSITION);
  142. size = ppDC-> GetTextExtent(st);
  143. if(size.cx>textSizeMax.cx) textSizeMax.cx = size.cx;
  144. if(size.cy>textSizeMax.cy) textSizeMax.cy = size.cy;
  145. }
  146. size = textSizeMax;
  147. size.cx+=size.cx/2;
  148. size.cy+=size.cy/2;
  149. if(flags==1)
  150. {
  151. CRect rect;
  152. boardRect = CRect(0,0,0,0);
  153. boardRect.right = count*size.cx+2;
  154. boardRect.bottom = size.cy+2;
  155. rect = boardRect;
  156. boardRect.OffsetRect(point);
  157. point.Offset(1,1);
  158. if(!m_IsVisible)
  159. {
  160. m_selfWnd->Create(AfxRegisterWndClass(CS_CLASSDC),"",WS_CHILD,boardRect,m_ParentWnd,1888);
  161. m_selfWnd->BringWindowToTop();
  162. m_IsVisible = TRUE;
  163. }
  164. CDC *pDC = m_selfWnd->GetDC();
  165. oldFont = pDC->SelectObject(m_font);
  166. CBrush *brush,*oldBrush;
  167. brush = new CBrush(m_BackGroundColor);
  168. oldBrush = pDC->SelectObject(brush);
  169. pDC->FillRect(rect,brush);
  170. pDC->Draw3dRect(rect,m_EdgeLUColor,m_EdgeRDColor);
  171. for(int i=0;i<count;i++)
  172. {
  173. boardRect = CRect(0,0,0,0);
  174. boardRect.left = i*size.cx;
  175. boardRect.right = (i+1)*size.cx;
  176. boardRect.bottom = size.cy;
  177. boardRect.OffsetRect(CPoint(1,1));
  178. COLORREF LUColor,RDColor;
  179. if(m_goby == i)
  180. {
  181. LUColor = m_EdgeLUColor;
  182. RDColor = m_EdgeRDColor;
  183. }
  184. else
  185. if(m_selected==i)
  186. {
  187. LUColor = m_EdgeRDColor;
  188. RDColor = m_EdgeLUColor;
  189. }
  190. else
  191. {
  192. LUColor = m_BackGroundColor;
  193. RDColor = m_BackGroundColor;
  194. }
  195. pDC->FillRect(boardRect,brush);
  196. pDC->Draw3dRect(boardRect,LUColor,RDColor);
  197. menu->GetMenuString(i,st,MF_BYPOSITION);
  198. pDC->SetTextColor(m_TextColor);
  199. pDC->SetBkColor(m_BackGroundColor);
  200. pDC->DrawText(st,boardRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  201. }
  202. delete brush;
  203. }
  204. else
  205. {
  206. CRect rect;
  207. boardRect = CRect(0,0,0,0);
  208. boardRect.right = size.cx+2;
  209. boardRect.bottom = count*size.cy+2;
  210. rect = boardRect;
  211. boardRect.OffsetRect(point);
  212. point.Offset(1,1);
  213. if(!m_IsVisible)
  214. {
  215. m_selfWnd->Create(AfxRegisterWndClass(CS_CLASSDC),"",WS_CHILD,boardRect,m_ParentWnd,1888);
  216. m_selfWnd->BringWindowToTop();
  217. m_IsVisible = TRUE;
  218. }
  219. CDC *pDC = m_selfWnd->GetDC();
  220. oldFont = pDC->SelectObject(m_font);
  221. CBrush *brush,*oldBrush;
  222. brush = new CBrush(m_BackGroundColor);
  223. oldBrush = pDC->SelectObject(brush);
  224. pDC->FillRect(rect,brush);
  225. pDC->Draw3dRect(rect,m_EdgeLUColor,m_EdgeRDColor);
  226. for(int i=0;i<count;i++)
  227. {
  228. boardRect = CRect(0,0,0,0);
  229. boardRect.right = size.cx;
  230. boardRect.bottom = (i+1)*size.cy;
  231. boardRect.top = i*size.cy;
  232. boardRect.OffsetRect(CPoint(1,1));
  233. COLORREF LUColor,RDColor;
  234. if(m_goby == i)
  235. {
  236. LUColor = m_EdgeLUColor;
  237. RDColor = m_EdgeRDColor;
  238. }
  239. else
  240. if(m_selected==i)
  241. {
  242. LUColor = m_EdgeRDColor;
  243. RDColor = m_EdgeLUColor;
  244. }
  245. else
  246. {
  247. LUColor = m_BackGroundColor;
  248. RDColor = m_BackGroundColor;
  249. }
  250. pDC->FillRect(boardRect,brush);
  251. pDC->Draw3dRect(boardRect,LUColor,RDColor);
  252. menu->GetMenuString(i,st,MF_BYPOSITION);
  253. pDC->SetTextColor(m_TextColor);
  254. pDC->SetBkColor(m_BackGroundColor);
  255. pDC->DrawText(st,boardRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  256. }
  257. delete brush;
  258. }
  259. ppDC->SelectObject(oldFont);
  260. ppDC->SelectObject(oldBrush);
  261. for( i=0;i<count;i++)
  262. {
  263. if((SubMenu[i]!=NULL) &&(m_selected==i))
  264. SubMenu[i]->DrawMenu();
  265. }
  266. delete brush;
  267. }
  268. UINT CFreeMenu::MeasureMenuID(CMenu *menu,CPoint CursorPosition)
  269. {
  270. int count;
  271. CSize textSizeMax(0,0);
  272. CRect boardRect;
  273. CString st;
  274. count = menu->GetMenuItemCount();
  275. int curWidth = 0;
  276. CSize size(0,0);
  277. CFont *oldFont;
  278. CDC *pDC = m_ParentWnd->GetDC();
  279. oldFont = pDC->SelectObject(m_font);
  280. for(int i=0;i<count;i++)
  281. {
  282. menu->GetMenuString(i,st,MF_BYPOSITION);
  283. size = pDC-> GetTextExtent(st);
  284. if(size.cx>textSizeMax.cx) textSizeMax.cx = size.cx;
  285. if(size.cy>textSizeMax.cy) textSizeMax.cy = size.cy;
  286. }
  287. pDC->SelectObject(oldFont);
  288. size = textSizeMax;
  289. size.cx+=size.cx/2;
  290. size.cy+=size.cy/2;
  291. CPoint point = MenuBeginPoint;
  292. point.Offset(1,1);
  293. if(flags==1)
  294. {
  295. for(int i=0;i<count;i++)
  296. {
  297. boardRect = CRect(0,0,0,0);
  298. boardRect.left = i*size.cx;
  299. boardRect.right = (i+1)*size.cx;
  300. boardRect.bottom = size.cy;
  301. // boardRect.OffsetRect(point);
  302. if(boardRect.PtInRect(CursorPosition)) 
  303. return menu->GetMenuItemID(i);
  304. }
  305. }
  306. else
  307. {
  308. for(int i=0;i<count;i++)
  309. {
  310. boardRect = CRect(0,0,0,0);
  311. boardRect.right = size.cx;
  312. boardRect.bottom = (i+1)*size.cy;
  313. boardRect.top = i*size.cy;
  314. // boardRect.OffsetRect(point);
  315. if(boardRect.PtInRect(CursorPosition)) 
  316. return menu->GetMenuItemID(i);
  317. }
  318. }
  319. return -1;
  320. }
  321. int CFreeMenu::MeasureMenuNo(CMenu *menu,CPoint CursorPosition)
  322. {
  323. int count;
  324. CSize textSizeMax(0,0);
  325. CRect boardRect;
  326. CString st;
  327. count = menu->GetMenuItemCount();
  328. int curWidth = 0;
  329. CSize size(0,0);
  330. CFont *oldFont;
  331. CDC *pDC = m_ParentWnd->GetDC();
  332. oldFont = pDC->SelectObject(m_font);
  333. CPoint point = MenuBeginPoint ;
  334. //point.Offset(1,1);
  335. for(int i=0;i<count;i++)
  336. {
  337. menu->GetMenuString(i,st,MF_BYPOSITION);
  338. size = pDC-> GetTextExtent(st);
  339. if(size.cx>textSizeMax.cx) textSizeMax.cx = size.cx;
  340. if(size.cy>textSizeMax.cy) textSizeMax.cy = size.cy;
  341. }
  342. pDC->SelectObject(oldFont);
  343. size = textSizeMax;
  344. size.cx+=size.cx/2+2;
  345. size.cy+=size.cy/2+2;
  346. if(flags==1)
  347. {
  348. for(int i=0;i<count;i++)
  349. {
  350. boardRect = CRect(0,0,0,0);
  351. boardRect.left = i*size.cx;
  352. boardRect.right = (i+1)*size.cx;
  353. boardRect.bottom = size.cy;
  354. // boardRect.OffsetRect(point);
  355. if(boardRect.PtInRect(CursorPosition)) 
  356. return i;
  357. }
  358. }
  359. else
  360. {
  361. for(int i=0;i<count;i++)
  362. {
  363. boardRect = CRect(0,0,0,0);
  364. boardRect.right = size.cx;
  365. boardRect.bottom = (i+1)*size.cy;
  366. boardRect.top = i*size.cy;
  367. // boardRect.OffsetRect(point);
  368. if(boardRect.PtInRect(CursorPosition)) 
  369. return i;
  370. }
  371. }
  372. return -1;
  373. }
  374. CRect CFreeMenu::GetItemRect(CMenu *menu,int item)
  375. {
  376. int count;
  377. CSize textSizeMax(0,0);
  378. CRect boardRect;
  379. CString st;
  380. count = menu->GetMenuItemCount();
  381. int curWidth = 0;
  382. CSize size(0,0);
  383. CFont *oldFont;
  384. CDC *pDC = m_ParentWnd->GetDC();
  385. oldFont = pDC->SelectObject(m_font);
  386. for(int i=0;i<count;i++)
  387. {
  388. menu->GetMenuString(i,st,MF_BYPOSITION);
  389. size = pDC-> GetTextExtent(st);
  390. if(size.cx>textSizeMax.cx) textSizeMax.cx = size.cx;
  391. if(size.cy>textSizeMax.cy) textSizeMax.cy = size.cy;
  392. }
  393. pDC->SelectObject(oldFont);
  394. size = textSizeMax;
  395. size.cx+=size.cx/2;
  396. size.cy+=size.cy/2;
  397. CPoint point;
  398. point  = MenuBeginPoint;
  399. point.Offset(1,1);
  400. if(flags==1)
  401. {
  402. if(item<count)
  403. {
  404. boardRect = CRect(0,0,0,0);
  405. boardRect.left = item*size.cx;
  406. boardRect.right = (item+1)*size.cx;
  407. boardRect.bottom = size.cy;
  408. //boardRect.OffsetRect(point);
  409. return boardRect;
  410. }
  411. }
  412. else
  413. {
  414. if(item<count)
  415. {
  416. boardRect = CRect(0,0,0,0);
  417. boardRect.right = size.cx;
  418. boardRect.bottom = (item+1)*size.cy;
  419. boardRect.top = item*size.cy;
  420. // boardRect.OffsetRect(point);
  421. return boardRect;
  422. }
  423. }
  424. return CRect(-1,-1,-1,-1);
  425. }
  426. LRESULT CFreeMenu::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  427. {   
  428. if(!m_IsVisible) return 0;
  429. switch(message)
  430. {
  431. case WM_LBUTTONDOWN:
  432. {
  433. CPoint p;
  434. p.x = LOWORD(lParam);  // horizontal position of cursor 
  435. p.y = HIWORD(lParam); 
  436. int selected = MeasureMenuNo(m_Menu,p);
  437. if(selected!=-1)
  438. {
  439. if(selected!=m_selected)
  440. {    
  441. if((m_selected!=-1) && (SubMenu[m_selected]))
  442. SubMenu[m_selected]->Disable();
  443. m_goby = -1;
  444. m_selected = selected;
  445. DrawMenu();
  446. if(!m_Menu->GetSubMenu(selected))
  447. {
  448. m_ParentWnd->PostMessage(m_Menu-> GetMenuItemID(selected));
  449. m_selfWnd->BringWindowToTop();
  450. ClearParent();
  451. m_selected = -1;
  452. m_goby = -1;
  453. }
  454. }
  455. else
  456. {
  457. if(SubMenu[m_selected])
  458. SubMenu[m_selected]->Disable();
  459. m_selected = -1;
  460. DrawMenu();
  461. }
  462. }
  463. else
  464. {
  465. int count = m_Menu->GetMenuItemCount();
  466. for(int i=0;i<count;i++)
  467. if(SubMenu[i])
  468. SubMenu[i]->WindowProc(message, wParam,lParam) ;
  469. }
  470. }
  471. break;
  472. case WM_MOUSEMOVE:
  473. {
  474. int count = m_Menu->GetMenuItemCount();
  475. CPoint p;
  476. p.x = LOWORD(lParam);  // horizontal position of cursor 
  477. p.y = HIWORD(lParam); 
  478. int Goby =  MeasureMenuNo(m_Menu,p);
  479. if(Goby!=-1)
  480. {
  481. if(m_selected!=-1)
  482. {
  483. if(m_selected!=Goby)
  484. {
  485. if(SubMenu[m_selected])
  486. SubMenu[m_selected]->Disable();
  487. m_selected = Goby;
  488. DrawMenu();
  489. return 2;
  490. }
  491. }
  492. else
  493. if(Goby!=m_goby)
  494. {
  495. m_goby = Goby;
  496. DrawMenu();
  497. return 2;
  498. }
  499. }
  500. else
  501. {
  502. if((m_goby != -1)||(m_selected != -1))
  503. {
  504. LRESULT ff = 0;
  505. for(int i=0;i<count;i++)
  506. {
  507. if((SubMenu[i]!=NULL) &&(m_selected==i) && (ff==0))
  508. ff = SubMenu[i]->WindowProc(message, wParam,lParam) ;
  509. }
  510. if(ff ==1)
  511. {
  512. m_goby = -1;
  513. m_selected = -1;
  514. delete m_selfWnd;
  515. m_selfWnd = new CMenuItemWnd;
  516. m_IsVisible = FALSE;
  517. return 1;
  518. }
  519. }
  520. }
  521. }
  522. break;
  523. }
  524. return 0;
  525. }
  526. void CFreeMenu::Disable()
  527. {
  528. if(m_IsVisible)
  529. {
  530. DrawMenu();
  531. m_IsVisible = FALSE;
  532. m_selfWnd->DestroyWindow();
  533. }
  534. }
  535. void CFreeMenu::ClearParent()
  536. {
  537. if(m_parentMenu)
  538. {
  539. m_parentMenu->DrawMenu();
  540. m_parentMenu->ClearParent();
  541. Disable();
  542. }
  543. m_selected = -1;
  544. }
  545. CFreeMenu::~CFreeMenu()
  546. {
  547. for(int i=0;i<SubMenu.GetSize();i++)
  548. {
  549. if(SubMenu[i]) delete SubMenu[i];
  550. }
  551. if(m_parentMenu==NULL) delete m_Menu;
  552. if(m_selfWnd) delete m_selfWnd;