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

工具条

开发平台:

Visual C++

  1. // NGenericMenu.cpp: implementation of the CNGenericMenu class.
  2. //
  3. /*
  4. Copyright (C) 1998 Tony Hoyle (tmh@netfusion.co.uk)
  5. This program is free software; you can redistribute it and/or modify it under the terms
  6. of the GNU General Public License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  9. without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License along with this program;
  12. if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  13. */
  14. //////////////////////////////////////////////////////////////////////
  15. #include "stdafx.h"
  16. #include "afxpriv.h"
  17. #include "NGenericMenu.h"
  18. #include "NGenericPopup.h"
  19. #include "NMDIClient.h"
  20. #include "resource.h"
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char THIS_FILE[]=__FILE__;
  24. #define new DEBUG_NEW
  25. #endif
  26. IMPLEMENT_DYNAMIC(CNGenericMenu,CNGenericToolBar)
  27. BEGIN_MESSAGE_MAP(CNGenericMenu,CNGenericToolBar)
  28. //{{AFX_MSG_MAP(CNGenericMenu)
  29. ON_WM_NCPAINT()
  30. ON_WM_SYSCOMMAND()
  31. //}}AFX_MSG_MAP
  32. ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
  33. ON_NOTIFY_REFLECT(TBN_DROPDOWN,OnDropDown)
  34. ON_NOTIFY_REFLECT(TBN_HOTITEMCHANGE,OnHotChange)
  35. ON_UPDATE_COMMAND_UI_RANGE(65000,65100,OnMenuUpdate)
  36. END_MESSAGE_MAP()
  37. //////////////////////////////////////////////////////////////////////
  38. // Construction/Destruction
  39. //////////////////////////////////////////////////////////////////////
  40. CNGenericMenu::CNGenericMenu()
  41. {
  42. m_bHasBitmaps=FALSE;
  43. m_bItemDropped=FALSE;
  44. m_bForceText=TRUE;
  45. m_pParent=NULL;
  46. m_hMenu=NULL;
  47. m_bSysMenuIcon=FALSE;
  48. }
  49. CNGenericMenu::~CNGenericMenu()
  50. {
  51. }
  52. BOOL CNGenericMenu::Create(CFrameWnd* pParent)
  53. {
  54. m_pParent=pParent;
  55. m_hMenu=NULL;
  56. if(!CNGenericToolBar::CreateEx(pParent,TBSTYLE_FLAT|TBSTYLE_LIST|TBSTYLE_AUTOSIZE|TBSTYLE_TRANSPARENT|TBSTYLE_TOOLTIPS)) return FALSE;
  57. CString csMenu;
  58. csMenu.LoadString(IDS_MENU);
  59. SetWindowText(csMenu);
  60. SendMessage(TB_BUTTONSTRUCTSIZE,sizeof(TBBUTTON));
  61. SendMessage(TB_SETBITMAPSIZE,0,MAKELPARAM(0,0));
  62. return TRUE;
  63. }
  64. BOOL CNGenericMenu::DrawMenuBar()
  65. {
  66. return SetMenu(m_hMenu);
  67. }
  68. BOOL CNGenericMenu::SetMenu(HMENU hMenu)
  69. {
  70. m_hMenu=hMenu;
  71. if(!hMenu) return FALSE;
  72. CToolBarCtrl* pCtrl=&GetToolBarCtrl();
  73. CMenu* pMenu=CMenu::FromHandle(hMenu);
  74. int nCount=pMenu->GetMenuItemCount();
  75. int* idString=new int[nCount];
  76. TBBUTTON* pTB=new TBBUTTON[nCount];
  77. int n;
  78. char tmp[65];
  79. LPCTSTR q;
  80. m_accelList.SetSize(0);
  81. CFrameWnd* pChildFrame=m_pParent->GetActiveFrame();
  82. if(pChildFrame && pChildFrame!=m_pParent)
  83. {
  84. m_hSysMenuIcon=(HICON)GetClassLong(*pChildFrame,GCL_HICONSM);
  85. }
  86. for(n=0; n<nCount; n++)
  87. {
  88. pMenu->GetMenuString(n,tmp,64,MF_BYPOSITION);
  89. tmp[strlen(tmp)+1]='';
  90. idString[n]=pCtrl->AddStrings(tmp);
  91. for(q=tmp; *q; q++)
  92. {
  93. if(*q=='&')
  94. {
  95. int s=m_accelList.GetSize();
  96. m_accelList.SetSize(s+1);
  97. m_accelList[s].nKey=toupper(*(q+1));
  98. m_accelList[s].nId=65000+n;
  99. break;
  100. }
  101. }
  102. memset(&pTB[n],0,sizeof(TBBUTTON));
  103. pTB[n].iBitmap=1;
  104. pTB[n].idCommand=65000+n;
  105. pTB[n].fsState=TBSTATE_ENABLED;
  106. pTB[n].fsStyle=TBSTYLE_BUTTON|TBSTYLE_DROPDOWN|TBSTYLE_AUTOSIZE;
  107. pTB[n].iString=idString[n];
  108. }
  109. while(pCtrl->DeleteButton(0))
  110. ;
  111. pCtrl->AddButtons(nCount,pTB);
  112. delete []idString;
  113. delete []pTB;
  114. RecalcSize();
  115. return TRUE;
  116. }
  117. void CNGenericMenu::OnDropDown(NMHDR * pNotifyStruct, LRESULT* result)
  118. {
  119. LPNMTOOLBAR lpnmtb = (LPNMTOOLBAR)pNotifyStruct;
  120. ShowDropDown(FALSE,lpnmtb->iItem);
  121. *result=TBDDRET_DEFAULT;
  122. }
  123. void CNGenericMenu::ShowDropDown(BOOL bFromKey, int iItem)
  124. {
  125. HMENU hPopup;
  126. CRect rect;
  127. CWnd* pParent;
  128. hPopup=*m_pParent->GetActiveFrame()->GetSystemMenu(FALSE);
  129. if(!m_bItemDropped)
  130. {
  131. if(iItem==-1)
  132. m_pParent->GetActiveFrame()->SendMessage(WM_INITMENU,(WPARAM)hPopup);
  133. else
  134. m_pParent->SendMessage(WM_INITMENU,(WPARAM)m_hMenu);
  135. }
  136. else
  137. {
  138. if(m_iItem==-1 && iItem!=-1)
  139. m_pParent->SendMessage(WM_INITMENU,(WPARAM)m_hMenu);
  140. else if(m_iItem!=-1 && iItem==-1)
  141. m_pParent->GetActiveFrame()->SendMessage(WM_INITMENU,(WPARAM)hPopup);
  142. if(m_iItem!=-1) SendMessage(TB_SETSTATE,m_iItem,TBSTATE_ENABLED);
  143. }
  144. if (TRUE == m_bItemDropped)
  145. {
  146. m_popup.HideMenu ();
  147. m_iItem=-1;
  148. m_bItemDropped=FALSE;
  149. }
  150. else
  151. {
  152. m_iItem=iItem;
  153. m_bItemDropped=TRUE;
  154. if(iItem!=-1) SendMessage(TB_SETSTATE,iItem,TBSTATE_ENABLED|TBSTATE_PRESSED);
  155. if(iItem!=-1)
  156. {
  157. hPopup=::GetSubMenu(m_hMenu,iItem-65000);
  158. GetItemRect(iItem-65000,rect);
  159. ClientToScreen(rect);
  160. }
  161. else
  162. {
  163. CRect wr;
  164. GetWindowRect(wr);
  165. rect=m_rectSysMenu;
  166. rect.OffsetRect(wr.left,wr.top);
  167. }
  168. if(iItem!=-1)
  169. {
  170. pParent=m_pParent;
  171. pParent->SendMessage(WM_INITMENUPOPUP,(WPARAM)hPopup,iItem-65000);
  172. }
  173. else
  174. {
  175. pParent=m_pParent->GetActiveFrame();
  176. pParent->SendMessage(WM_INITMENUPOPUP,(WPARAM)hPopup,0);
  177. }
  178. if(m_dwStyle & CBRS_ALIGN_LEFT)
  179. m_popup.ShowMenu(/*POP_MENU_LEFT,*/bFromKey,/*this,*/rect.right+1,rect.top,m_pParent,hPopup);
  180. else if(m_dwStyle & CBRS_ALIGN_RIGHT)
  181. m_popup.ShowMenu(/*POP_MENU_RIGHT,*/bFromKey,/*this,*/rect.left,rect.top,m_pParent,hPopup);
  182. else if(m_dwStyle & CBRS_ALIGN_TOP)
  183. m_popup.ShowMenu(/*POP_MENU_TOP,*/bFromKey,/*this,*/rect.left,rect.bottom+1,m_pParent,hPopup);
  184. else if(m_dwStyle & CBRS_ALIGN_BOTTOM)
  185. m_popup.ShowMenu(/*POP_MENU_BOTTOM,*/bFromKey,/*this,*/rect.left,rect.top,m_pParent,hPopup);
  186. }
  187. }
  188. void CNGenericMenu::OnHotChange(NMHDR * pNotifyStruct, LRESULT* result)
  189. {
  190. LPNMTBHOTITEM lpnmtb = (LPNMTBHOTITEM)pNotifyStruct;
  191. if(m_bItemDropped && lpnmtb->idNew!=m_iItem)
  192. {
  193. if(lpnmtb->idNew)
  194. {
  195. ShowDropDown(FALSE,lpnmtb->idNew);
  196. }
  197. else
  198. {
  199. CPoint pt;
  200. CRect r;
  201. GetCursorPos(&pt);
  202. GetWindowRect(r);
  203. pt.x-=r.left;
  204. pt.y-=r.top;
  205. if(m_bSysMenuIcon && m_rectSysMenu.PtInRect(pt))
  206. {
  207. ShowDropDown(FALSE,-1);
  208. }
  209. }
  210. }
  211. *result=0;
  212. }
  213. void CNGenericMenu::OnOverSysMenu()
  214. {
  215. if(m_bItemDropped && m_iItem!=-1)
  216. ShowDropDown(FALSE,-1);
  217. }
  218. void CNGenericMenu::OnMenuUpdate(CCmdUI* pCmd)
  219. {
  220. if(!m_hMenu) return;
  221. CMenu* pMenu=CMenu::FromHandle(m_hMenu);
  222. if(!pMenu) return;
  223. pCmd->Enable(pMenu->GetMenuState(pCmd->m_nID-65000,MF_DISABLED));
  224. }
  225. BOOL CNGenericMenu::TranslateMenuChar(UINT nChar)
  226. {
  227. for(int n=0; n<m_accelList.GetSize(); n++)
  228. {
  229. if(m_accelList[n].nKey==(UINT)toupper(nChar))
  230. {
  231. ShowDropDown(TRUE,m_accelList[n].nId);
  232. return TRUE;
  233. }
  234. }
  235. return FALSE;
  236. }
  237. BOOL CNGenericMenu::KeyboardFilter(UINT nChar, UINT nRepCnt, UINT nFlags)
  238. {
  239. if(m_bItemDropped)
  240. {
  241. if(nChar==VK_LEFT)
  242. {
  243. if(m_iItem>65000)
  244. ShowDropDown(TRUE,m_iItem-1);
  245. else if(m_iItem==-1)
  246. ShowDropDown(TRUE,65000+GetToolBarCtrl().GetButtonCount()-1);
  247. else
  248. ShowDropDown(TRUE,m_bSysMenuIcon?-1:65000+GetToolBarCtrl().GetButtonCount()-1);
  249. }
  250. if(nChar==VK_RIGHT)
  251. {
  252. if(m_iItem==-1)
  253. ShowDropDown(TRUE,65000);
  254. else if(m_iItem<65000+GetToolBarCtrl().GetButtonCount()-1)
  255. ShowDropDown(TRUE,m_iItem+1);
  256. else
  257. ShowDropDown(TRUE,m_bSysMenuIcon?-1:65000);
  258. }
  259. }
  260. return FALSE;
  261. }
  262. CSize CNGenericMenu::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  263. {
  264. DWORD dwMode = LM_STRETCH;
  265. dwMode |= bHorz ? LM_HORZ : 0;
  266. return CalcLayout(dwMode);
  267. }
  268. void CNGenericMenu::OnNcPaint() 
  269. {
  270. EraseNonClient(TRUE);
  271. }
  272. void CNGenericMenu::OnSysCommand(UINT nID, LPARAM lParam) 
  273. {
  274. if(m_bSysMenuIcon)
  275. {
  276. switch(nID&0xfff0)
  277. {
  278. case SC_KEYMENU:
  279. ShowDropDown(TRUE,-1);
  280. break;
  281. case SC_MOUSEMENU:
  282. ShowDropDown(FALSE,-1);
  283. break;
  284. }
  285. m_pParent->GetActiveFrame()->PostMessage(WM_SYSCOMMAND,nID,lParam);
  286. }
  287. }
  288. void CNGenericMenu::OnIdleUpdateCmdUI()
  289. {
  290. BOOL bSysMenuIcon=(m_pParent->GetActiveFrame()!=m_pParent && m_pParent->GetActiveFrame()->IsZoomed())?TRUE:FALSE;
  291. if(bSysMenuIcon!=m_bSysMenuIcon)
  292. {
  293. m_bSysMenuIcon=bSysMenuIcon;
  294. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);
  295. }
  296. CNGenericToolBar::OnIdleUpdateCmdUI(0,0);
  297. }