MenuBar.cpp
上传用户:wlkj888
上传日期:2022-08-01
资源大小:806k
文件大小:89k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. /****************************************************************************
  2.  * *  
  3.  * GuiToolKit   *
  4.  *  (MFC extension) *  
  5.  * Created by Francisco Campos G. www.beyondata.com fcampos@beyondata.com *
  6.  *--------------------------------------------------------------------------*    
  7.  * *
  8.  * This program is free software;so you are free to use it any of your *
  9.  * applications (Freeware, Shareware, Commercial),but leave this header *
  10.  * intact. *
  11.  * *
  12.  * These files are provided "as is" without warranty of any kind. *
  13.  * *
  14.  *        GuiToolKit is forever FREE CODE !!!!! *
  15.  * *
  16.  *--------------------------------------------------------------------------*
  17.  * *
  18.  * Bug Fixes and improvements : (Add your name) *
  19.  * -Francisco Campos *
  20.  * -igor1960 *
  21.  ****************************************************************************/
  22. //
  23. // Class :  CMenuBar
  24. // 
  25. // Version : 1.0
  26. // 
  27. // Created : Jan 14, 2001        
  28. //
  29. // Last Modified: Francisco Campos. 
  30. //
  31. // CMenuBar class version 2.12
  32. // simulates a Dev Studio style dockable menu bar.
  33. // based on PixieLib written by Paul DiLascia<www.dilascia.com>
  34. //
  35. // version history
  36. // 2.12 : support OLE menu carelessly.
  37. // 2.11 : WindowMenu fixed by VORGA.
  38. // 2.10 : CMenuDockBar's problem fixed again and again.
  39. // 2.08 : give up precise ComputeMenuTrackPoint
  40. // 2.07 : Sychronizing with frame activation problem fixed
  41. // 2.06 : CMenuItem::ComputeMenuTrackPoint fixed a little
  42. // 2.05 : CMenuDockBar fixed
  43. //  : Inactive state problem fixed
  44. // 2.04 : bug with ::TrackPopupEx carelessly fixed 
  45. //           : synchronizing TrackPopup animation with win98 effect
  46. //
  47. // written by MB <mb2@geocities.co.jp> 1999.11.27
  48. //
  49. //
  50. //
  51. // CMenuBar version 2.13
  52. #include "stdafx.h"
  53. #include "MenuBar.h"
  54. #include "resource.h"
  55. #include "GuiDockContext.h"
  56. #include <afxole.h>
  57. #include "Menubar.h"
  58. #ifdef _DEBUG
  59. #define new DEBUG_NEW
  60. #undef THIS_FILE
  61. static char THIS_FILE[] = __FILE__;
  62. #endif
  63. #ifdef _DEBUG
  64. const BOOL bTraceOn = FALSE;
  65. #define LTRACE if (bTraceOn) TRACE
  66. const BOOL bTraceOn2 = TRUE;
  67. #define LTRACE2 if (bTraceOn2) TRACE
  68. #else
  69. #define LTRACE
  70. #define LTRACE2
  71. #endif
  72. BOOL bActivSystemMenu;
  73. //////////////////////////////////////////////////////////////////////
  74. // I've found string resource of "More windows" in "user.exe".
  75. // But I can't load it, so please replace a following with your language.
  76. static const TCHAR _szMoreWindows[] = _T("&More windows...");
  77. //////////////////////////////////////////////////////////////////////
  78. // used for OLE menu (easy fix)
  79. static BOOL _bWindowMenuSendCmd = FALSE;
  80. static int _nPrevIndexForCmd = -1;
  81. //////////////////////////////////////////////////////////////////////
  82. // hook
  83. static CMenuBar* g_pMenuBar = NULL;
  84. static HHOOK  g_hMsgHook = NULL;
  85. // message
  86. const UINT CMenuBar::WM_GETMENU = ::RegisterWindowMessage(_T("CMenuBar::WM_GETMENU"));
  87. const UINT MB_SET_MENU_NULL = ::RegisterWindowMessage(_T("CMenuBar::MB_SET_MENU_NULL"));
  88. const int cxBorder2 = ::GetSystemMetrics(SM_CXBORDER)*2;
  89. const int cyBorder2 = ::GetSystemMetrics(SM_CYBORDER)*2;
  90. // common resources
  91. static CFont _fontHorzMenu, _fontVertMenu;
  92. static int _cyHorzFont, _cyMenuOnBar, _cyTextMargin;
  93. const int CXTEXTMARGIN = 5;
  94. DWORD dSt;
  95. COLORREF   m_clrFace;
  96. int gbintHorz; //Horz=0, Vert=1
  97. CRect rcMenu; //CRect of button
  98. static BOOL _InitCommonResources(BOOL bForce = FALSE)
  99. {
  100. if (bForce == FALSE && _fontHorzMenu.m_hObject != NULL)
  101. return TRUE;// no need to reinitialize
  102. // clean up
  103. _fontHorzMenu.DeleteObject();
  104. _fontVertMenu.DeleteObject();
  105. // create fonts
  106. NONCLIENTMETRICS info; info.cbSize = sizeof(info);
  107. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
  108. if (!_fontHorzMenu.CreateFontIndirect(&info.lfMenuFont))
  109. return FALSE;
  110. // create vertical font
  111. info.lfMenuFont.lfEscapement = -900;
  112. info.lfMenuFont.lfOrientation = -900;
  113. strcpy(info.lfMenuFont.lfFaceName,"verdana");
  114. if (!_fontVertMenu.CreateFontIndirect(&info.lfMenuFont))
  115. return FALSE;
  116. // get font height
  117. _cyHorzFont = abs(info.lfMenuFont.lfHeight);
  118. // calc Y text margin
  119. _cyMenuOnBar = info.iMenuHeight;
  120. _cyMenuOnBar = max(_cyMenuOnBar, ::GetSystemMetrics(SM_CYSMICON));
  121. _cyTextMargin = (_cyMenuOnBar - _cyHorzFont) / 2;
  122. return TRUE;
  123. }
  124. // I wanted to control popup point, but I've fount we can never get popupmenu rect before popup.
  125. // even if not owner draw menu...
  126. static CPoint _ComputeMenuTrackPoint(const CRect& rcItem, DWORD dwStyle, UINT& fuFlags, TPMPARAMS& tpm)
  127. {
  128. fuFlags = TPM_LEFTBUTTON | TPM_LEFTALIGN | TPM_HORIZONTAL;
  129. tpm.cbSize = sizeof(tpm);
  130. CPoint pt;
  131. CRect& rcExclude = (CRect&)tpm.rcExclude;
  132. CWnd::GetDesktopWindow()->GetWindowRect(&rcExclude);
  133. CRect rcFrame;
  134. AfxGetMainWnd()->GetWindowRect(&rcFrame);
  135. switch (dwStyle & CBRS_ALIGN_ANY) {
  136. case CBRS_ALIGN_RIGHT:
  137. case CBRS_ALIGN_LEFT:
  138. pt = CPoint(rcItem.right+1, rcItem.top-1);
  139. // to avoid strange menu flip, won't do : [rcExclude.right = rcItem.right+1;]
  140. // I want to use : fuFlags |= TPM_HORNEGANIMATION;
  141. break;
  142. default: // case CBRS_ALIGN_TOP:
  143. // changed by Manfred Drasch - start
  144. CRect rcTmpItem;
  145. rcTmpItem = rcItem;
  146. if(rcTmpItem.left < 0)
  147. {
  148. rcTmpItem.right = rcTmpItem.Width();
  149. rcTmpItem.left = 0;
  150. }
  151. if(rcTmpItem.left > rcExclude.right)
  152. {
  153. rcTmpItem.right = rcExclude.right; 
  154. rcTmpItem.left = rcTmpItem.right-rcTmpItem.Width();
  155. }
  156. pt = CPoint(rcTmpItem.left-1, rcTmpItem.bottom);
  157. rcExclude.bottom = rcTmpItem.bottom+1;// <- insead of [fuFlags |= TPM_VERPOSANIMATION;]
  158. // changed by Manfred Drasch - end
  159. break;
  160. }
  161. return pt;
  162. }
  163. //******************************************************************
  164. static int _CalcTextWidth(const CString& strText)
  165. {
  166. CWindowDC dc(NULL);
  167. CRect rcText(0, 0, 0, 0);
  168. CFont* pOldFont = dc.SelectObject(&_fontHorzMenu);
  169. dc.DrawText(strText, &rcText, DT_SINGLELINE | DT_CALCRECT);
  170. dc.SelectObject(pOldFont);
  171. return rcText.Width();
  172. }
  173. //******************************************************************
  174. // grippers pasted from MFC6
  175. #define CX_GRIPPER  3
  176. #define CY_GRIPPER  3
  177. #define CX_BORDER_GRIPPER 2
  178. #define CY_BORDER_GRIPPER 2
  179. #define CX_GRIPPER_ALL CX_GRIPPER + CX_BORDER_GRIPPER*2
  180. #define CY_GRIPPER_ALL CY_GRIPPER + CY_BORDER_GRIPPER*2
  181. /////////////////////////////////////////////////////////////////////////////
  182. // CMenuBar
  183. BEGIN_MESSAGE_MAP(CMenuBar, CControlBar)
  184. //{{AFX_MSG_MAP(CMenuBar)
  185. ON_WM_LBUTTONDOWN()
  186. ON_WM_RBUTTONDOWN()
  187. ON_WM_MOUSEMOVE()
  188. ON_WM_CREATE()
  189. ON_WM_LBUTTONUP()
  190. ON_WM_LBUTTONDBLCLK()
  191. ON_WM_TIMER()
  192. ON_WM_DESTROY()
  193. ON_WM_NCCALCSIZE()
  194. ON_WM_NCPAINT()
  195. ON_WM_NCHITTEST()
  196. ON_WM_SIZE()
  197. ON_WM_SETCURSOR()
  198. ON_WM_SYSCOLORCHANGE()
  199. //}}AFX_MSG_MAP
  200. ON_REGISTERED_MESSAGE(MB_SET_MENU_NULL, OnSetMenuNull)
  201. ON_WM_PAINT()
  202. END_MESSAGE_MAP()
  203. IMPLEMENT_DYNAMIC(CMenuBar, CControlBar)
  204. /////////////////////////////////////////////////////////////////////////////
  205. // CMenuBar Construction
  206. CMenuBar::CMenuBar()
  207. {
  208. m_nCurIndex  = -1;
  209. m_nTrackingState = none;
  210. m_bProcessRightArrow = m_bProcessLeftArrow = TRUE;
  211. m_bIgnoreAlt = FALSE;
  212. m_hMenu = NULL;
  213. m_nIDEvent = NULL;
  214. szNameHistory.Empty();
  215. bSaveHistory=FALSE;
  216. m_bChangeState=FALSE;
  217. m_bMDIMaximized = FALSE;
  218. m_hWndMDIClient = NULL;
  219. m_hWndActiveChild = NULL;
  220. m_pMenuIcon = NULL;
  221. m_pMenuControl = NULL;
  222. m_bDelayedButtonLayout = TRUE;
  223. m_dwExStyle = 0;
  224. m_bFrameActive = FALSE;
  225. m_bMDIApp = FALSE;
  226. m_bXP=FALSE;
  227. cmb=NULL;
  228. m_bCombo=FALSE;//combobox by default
  229. bIsTabbed=FALSE;
  230. m_MenuContext=NULL;
  231. m_StyleDisplay=GUISTYLE_XP;
  232. }
  233. //******************************************************************
  234. BOOL CMenuBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
  235. {
  236. return CreateEx(pParentWnd, dwStyle,
  237. CRect(m_cxLeftBorder, m_cyTopBorder, m_cxRightBorder, m_cyBottomBorder), nID);
  238. }
  239. //******************************************************************
  240. BOOL CMenuBar::CreateEx(CWnd* pParentWnd, DWORD dwStyle, CRect rcBorders, UINT nID)
  241. {
  242. ASSERT_VALID(pParentWnd);// must have a parent
  243. ASSERT (!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)));
  244. SetBorders(rcBorders);
  245. // save the original style
  246. m_dwExStyle = dwStyle;
  247. // save the style
  248. m_dwStyle = (dwStyle & CBRS_ALL);// ******fixed by Mark Gentry, thanx!******
  249. dwStyle &= ~CBRS_ALL;
  250. dwStyle|=WS_CLIPCHILDREN | CCS_NOPARENTALIGN | CCS_NOMOVEY | CCS_NORESIZE;
  251. CString strClass = AfxRegisterWndClass(
  252. /*CS_HREDRAW | CS_VREDRAW |*/
  253. CS_DBLCLKS,// don't forget!
  254. AfxGetApp()->LoadStandardCursor(IDC_ARROW),
  255. (HBRUSH)NULL);
  256. m_clrFace=GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style);
  257. return CWnd::Create(strClass, _T("MenuBar"), dwStyle, CRect(), pParentWnd, nID);
  258. }
  259. void CMenuBar::SetSaveHistory(CString sNameHistory,BOOL bsaveHistory)
  260. {
  261. szNameHistory=sNameHistory;
  262. bSaveHistory=bsaveHistory;
  263. }
  264. //******************************************************************
  265. int CMenuBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  266. {
  267. if (CControlBar::OnCreate(lpCreateStruct) == -1)
  268. return -1;
  269. CWnd* pFrame = GetOwner();
  270. ASSERT_VALID(pFrame);
  271. // hook frame window to trap WM_MENUSELECT
  272. //m_hookFrame.Install(this, pFrame->GetSafeHwnd());
  273. // If this is an MDI app, hook client window to trap WM_MDISETMENU
  274. if (pFrame->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))) {
  275. m_bMDIApp = TRUE;
  276. m_hWndMDIClient = ((CMDIFrameWnd*)pFrame)->m_hWndMDIClient;
  277. ASSERT(::IsWindow(m_hWndMDIClient));
  278. m_hookMDIClient.Install(this, m_hWndMDIClient);
  279. }
  280. if (m_pDockContext==NULL)
  281. m_pDockContext=new CGuiDockContext(this);
  282. ASSERT(m_pDockContext);
  283. if (!_InitCommonResources()) {
  284. TRACE(_T("Failed to create menubar resourcen"));
  285. return FALSE;
  286. }
  287. return 0;
  288. }
  289. void CMenuBar::OnSysColorChange( )
  290. {
  291. CClientDC dc(this);
  292. m_clrFace=GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style);
  293. for (int i = 0; i < m_arrItem.GetSize(); ++i)
  294. m_arrItem[i]->UpdateClr();
  295. CWnd::OnSysColorChange( );
  296. /*if(m_pMenuControl != NULL) 
  297. m_pMenuControl->SetColorButton(GuiDrawLayer::GetRGBColorFace());
  298. if(m_pMenuIcon != NULL) 
  299. {
  300. m_pMenuIcon->OnActivateChildWnd();
  301. m_pMenuIcon->Update(&dc);
  302. }*/
  303. }
  304. //******************************************************************
  305. BOOL CMenuBar::CreateCombo(CComboBox* pControl,UINT nID,int iSize,DWORD dwStyle)
  306. {
  307. CFont m_Font;
  308. m_Font.CreateStockObject (DEFAULT_GUI_FONT);
  309. if(!pControl->Create(dwStyle, CRect(1,1,iSize,100), this, nID))
  310. {
  311. TRACE(_T("Failed to create combo-boxn"));
  312. m_bCombo=FALSE;
  313. return FALSE;
  314. }
  315. m_bCombo=TRUE;
  316. cmb=(CGuiComboBoxExt*)pControl;
  317. cmb->ActiveHistory(TRUE);
  318. cmb->LoadHistory(szNameHistory,bSaveHistory);
  319. return TRUE;
  320. }
  321. //******************************************************************
  322. void CMenuBar::OnSize(UINT nType, int cx, int cy) 
  323. {
  324. RefreshBar();
  325. if (m_bCombo==TRUE)
  326. DrawCombo();
  327. }
  328. void CMenuBar::SetTabbed(BOOL bIstabed)
  329. {
  330. bIsTabbed=bIstabed;
  331. }
  332. //******************************************************************
  333. BOOL CMenuBar::InitItems()
  334. {
  335. ASSERT(m_hMenu);
  336. // clean up all items
  337. DeleteItems();
  338. // buttons
  339. for (int i = 0; i < ::GetMenuItemCount(m_hMenu); ++i) {
  340. m_arrItem.Add(new CMenuButton(m_hMenu, i,this));
  341. }
  342. if (m_bMDIApp) {
  343. // icon
  344. CWnd* pFrame = GetTopLevelFrame();
  345. ASSERT_VALID(pFrame);
  346. CMDIFrameWnd* pMDIFrame = STATIC_DOWNCAST(CMDIFrameWnd, pFrame);
  347. HWND hWndMDIClient = pMDIFrame->m_hWndMDIClient;
  348. ASSERT(::IsWindow(hWndMDIClient));
  349. HWND hWndChild = (HWND)::SendMessage(hWndMDIClient,
  350. WM_MDIGETACTIVE, 0, 0);
  351. if ((!bIsTabbed) )
  352. {
  353. m_pMenuIcon = new CMenuIcon(this);
  354. m_arrItem.InsertAt(0, m_pMenuIcon);
  355. // frame control
  356. m_pMenuControl = new CMenuControl(this);
  357. m_arrItem.Add(m_pMenuControl);
  358. // reinitializing
  359. m_pMenuIcon->OnActivateChildWnd();
  360. m_pMenuControl->OnActivateChildWnd();
  361. }
  362. }
  363. return TRUE;
  364. }
  365. //******************************************************************
  366. BOOL CMenuBar::LoadMenuBar(UINT nIDResource)
  367. {
  368. ASSERT(m_hMenu == NULL);
  369. ASSERT_VALID(m_pDockSite);
  370. if (m_pDockSite->GetMenu()) {
  371. PostMessage(MB_SET_MENU_NULL, (WPARAM)m_pDockSite->GetSafeHwnd());
  372. }
  373. m_hMenu = ::LoadMenu(AfxGetInstanceHandle(), MAKEINTRESOURCE(nIDResource));
  374. if (m_hMenu == NULL) {
  375. TRACE(_T("Failed to load menun"));
  376. return FALSE;
  377. }
  378. return InitItems();
  379. }
  380. //******************************************************************
  381. HMENU CMenuBar::LoadMenu(HMENU hMenu, HMENU hWindowMenu)
  382. {
  383. ASSERT(::IsMenu(hMenu));
  384. ASSERT_VALID(this);
  385. CFrameWnd* pFrame = GetParentFrame();
  386. if (::GetMenu(pFrame->GetSafeHwnd()) != NULL) {
  387. // not to make MFC ignore SetMenu(NULL), post it.
  388. PostMessage(MB_SET_MENU_NULL, (WPARAM)pFrame->GetSafeHwnd());
  389. }
  390. HMENU hOldMenu = m_hMenu;
  391. m_hMenu = hMenu;// menu is shared with MFC
  392. // initialize Items 
  393. VERIFY(InitItems());
  394. if (hMenu) {
  395. m_hWindowMenu = hWindowMenu;
  396. RefreshBar();// and menubar itself
  397. }
  398. return hOldMenu;
  399. }
  400. //******************************************************************
  401. void CMenuBar::RefreshBar()
  402. {
  403. InvalidateRect(NULL);
  404. #if _MFC_VER >= 0x600
  405. if (GetParent()->IsKindOf(RUNTIME_CLASS(CReBar))) {
  406. m_bDelayedButtonLayout = TRUE;// to avoid ASSERTION
  407. Layout();
  408. }
  409. #endif
  410. CFrameWnd* pFrame = (CFrameWnd*)GetTopLevelFrame();
  411. ASSERT_VALID(pFrame); ASSERT(pFrame->IsFrameWnd());
  412. pFrame->RecalcLayout();
  413. // floating frame
  414. CFrameWnd* pMiniFrame = GetParentFrame();
  415. if (pMiniFrame->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)))
  416. pMiniFrame->RecalcLayout();
  417. }
  418. /////////////////////////////////////////////////////////////////////////////
  419. // CMenuBar clean up 
  420. CMenuBar::~CMenuBar()
  421. {
  422. }
  423. //******************************************************************
  424. void CMenuBar::DeleteItems()
  425. {
  426. for(int i = 0; i < m_arrItem.GetSize(); ++i) {
  427. CMenuItem* pItem = m_arrItem[i];
  428. delete pItem;
  429. }
  430. m_arrItem.RemoveAll();
  431. m_pMenuIcon = NULL;
  432. m_pMenuControl = NULL;
  433. }
  434. //******************************************************************
  435. /////////////////////////////////////////////////////////////////////////////
  436. // CMenuBar draw
  437. //******************************************************************
  438. void CMenuBar::UpdateBar(TrackingState nState, int nNewIndex)
  439. {
  440. if (m_nTrackingState == buttonmouse)
  441. m_bIgnoreAlt = FALSE;// if prev state is BUTTONMOUSE, always should be FALSE!
  442. m_nTrackingState = nState;
  443. // clean up
  444. if (IsValidIndex(m_nCurIndex)) {
  445. CMenuItem* pItem = m_arrItem[m_nCurIndex];
  446. CClientDC dc(this);
  447. pItem->ModifyState(MISTATE_HOT | MISTATE_PRESSED, 0);
  448. pItem->Update(&dc);
  449. // draw captions forcefully
  450. if (m_pMenuControl) {
  451. CRect rcCross = m_pMenuControl->GetRect() & m_arrItem[m_nCurIndex]->GetRect();
  452. if (!rcCross.IsRectEmpty()) {
  453. m_pMenuControl->DrawControl();
  454. if (m_bCombo==TRUE)
  455. DrawCombo();
  456. }
  457. }
  458. m_nCurIndex = -1;
  459. }
  460. if (nState != none) {
  461. ASSERT(IsValidIndex(nNewIndex));
  462. m_nCurIndex = nNewIndex;
  463. CMenuItem* pItem = m_arrItem[m_nCurIndex];
  464. CClientDC dc(this);
  465. if (nState == button || nState == buttonmouse) {
  466. pItem->ModifyState(MISTATE_PRESSED, MISTATE_HOT);
  467. pItem->Update(&dc);
  468. }
  469. else if (nState == popup) {
  470. pItem->ModifyState(MISTATE_HOT, MISTATE_PRESSED);
  471. pItem->Update(&dc);
  472. }
  473. // draw captions forcefully
  474. if (m_pMenuControl) {
  475. CRect rcCross = m_pMenuControl->GetRect() & m_arrItem[m_nCurIndex]->GetRect();
  476. if (!rcCross.IsRectEmpty()) {
  477. m_pMenuControl->DrawControl();
  478. if (m_bCombo==TRUE)
  479. DrawCombo();
  480. }
  481. }
  482. }
  483. else {
  484. // must be default parameter
  485. ASSERT(nNewIndex == -1);
  486. }
  487. m_bProcessRightArrow = m_bProcessLeftArrow = TRUE;
  488. }
  489. /////////////////////////////////////////////////////////////////////////////
  490. // CMenuBar message handler
  491. int CMenuBar::HitTestOnTrack(CPoint point)
  492. {
  493. for (int i = 0; i < GetItemCount(); ++i) {
  494. CMenuItem* pItem = m_arrItem[i];
  495. CRect rcItem = pItem->GetRect();
  496. if ((pItem->GetStyle() & MISTYLE_TRACKABLE) &&
  497. rcItem.PtInRect(point))
  498. return i;
  499. }
  500. return -1;
  501. }
  502. //*******************************************************************
  503. void CMenuBar::OnLButtonDblClk(UINT nFlags, CPoint point) 
  504. {
  505. }
  506. //******************************************************************
  507. void CMenuBar::OnLButtonDown(UINT nFlags, CPoint point) 
  508. {
  509. SetCursor (LoadCursor(NULL, IDC_SIZEALL));
  510. //int nIndex = HitTestOnTrack(point);
  511. int nIndex=nFlags >= 100? nFlags-100: -1;
  512. if(m_bMDIApp && !bIsTabbed)
  513. {
  514. if (nFlags == 1000)
  515. nIndex=0;
  516. else if (nIndex == -1)
  517. nIndex=-2;
  518. else 
  519. nIndex++;
  520. }
  521. if (IsValidIndex(nIndex) && (m_arrItem[nIndex]->GetStyle() & MISTYLE_TRACKABLE)) {
  522. UpdateBar(button, nIndex);
  523. TrackPopup(nIndex);
  524. return; // eat it!
  525. }
  526. CControlBar::OnLButtonDown(nFlags, point);
  527. }
  528. void CMenuBar::OnRButtonDown(UINT nFlags, CPoint point) 
  529. {
  530. ClientToScreen (&point);
  531. CMenu m_menu;
  532. if (m_MenuContext!= NULL)
  533. {
  534. m_menu.LoadMenu(m_MenuContext);
  535. CMenu* m_SubMenu = m_menu.GetSubMenu(0);
  536. m_SubMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,
  537. point.x, point.y-2, AfxGetMainWnd());
  538. Invalidate();
  539. UpdateWindow();
  540. }
  541. // CMenuBar::OnRButtonDown(nFlags, point);
  542. }
  543. //******************************************************************
  544. void CMenuBar::OnMouseMove(UINT nFlags, CPoint point)
  545. {
  546. int nIndex = HitTestOnTrack(point);
  547. if (!IsTopParentActive() || !GetTopLevelParent()->IsWindowEnabled())
  548. return;
  549. if (IsValidIndex(nIndex)) {
  550. if (m_nCurIndex == -1 || m_nCurIndex != nIndex) {// if other button
  551. UpdateBar(buttonmouse, nIndex);// button made hot with mouse
  552. if (!m_nIDEvent)
  553. m_nIDEvent = SetTimer(1, 100, NULL);
  554. }
  555. }
  556. else {
  557. UpdateBar();
  558. }
  559. CControlBar::OnMouseMove(nFlags, point);
  560. }
  561. //******************************************************************
  562. LRESULT CMenuBar::OnSetMenuNull(WPARAM wParam, LPARAM)
  563. {
  564. HWND hWnd = (HWND)wParam;
  565. ASSERT(::IsWindow(hWnd));
  566. ::SetMenu(hWnd, NULL);
  567. return 0;
  568. }
  569. //******************************************************************
  570. LRESULT CMenuBar::OnSettingChange(WPARAM wParam, LPARAM lParam)
  571. {
  572. // reinitialize fonts etc
  573. if (!_InitCommonResources(TRUE)) {
  574. TRACE(_T("Failed to create bar resourcen"));
  575. return FALSE;
  576. }
  577. VERIFY(InitItems());
  578. CFrameWnd* pFrame = GetParentFrame();
  579. ASSERT_VALID(pFrame);
  580. pFrame->RecalcLayout();
  581. return 0;
  582. }
  583. //******************************************************************
  584. void CMenuBar::OnLButtonUp(UINT nFlags, CPoint point) 
  585. {
  586. CControlBar::OnLButtonUp(nFlags, point);
  587. }
  588. //******************************************************************
  589. void CMenuBar::CheckActiveChildWndMaximized()
  590. {
  591. if(!m_pMenuControl) return;
  592. if (!bIsTabbed)
  593. {
  594. ASSERT(m_pMenuControl);
  595. ASSERT(m_pMenuIcon);
  596. }
  597. BOOL bMaximized = FALSE;
  598. GetActiveChildWnd(bMaximized);
  599. if (m_bMDIMaximized != bMaximized) {
  600. LTRACE(_T("CMenuBar::CheckActiveChildWndMaximized---state changed, refreshingn"));
  601. m_bMDIMaximized = bMaximized;
  602. if (!bIsTabbed)
  603. {
  604. m_pMenuControl->OnActivateChildWnd();
  605. m_pMenuIcon->OnActivateChildWnd();
  606. if(!m_bMDIMaximized )
  607. {
  608. m_bChangeState=TRUE;
  609. m_pMenuControl->m_arrButton[0].ShowWindow(SW_HIDE);
  610. m_pMenuControl->m_arrButton[1].ShowWindow(SW_HIDE);
  611. m_pMenuControl->m_arrButton[2].ShowWindow(SW_HIDE);
  612. }
  613. else
  614. {
  615. m_bChangeState=TRUE;
  616. m_pMenuControl->m_arrButton[0].ShowWindow(SW_SHOW);
  617. m_pMenuControl->m_arrButton[1].ShowWindow(SW_SHOW);
  618. m_pMenuControl->m_arrButton[2].ShowWindow(SW_SHOW);
  619. }
  620. }
  621. if (m_bCombo==TRUE)
  622. DrawCombo();
  623. RefreshBar();
  624. }
  625. }
  626. //******************************************************************
  627. void CMenuBar::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
  628. {
  629. LTRACE(_T("CMenuBar::OnInitMenuPopupn"));
  630. CMenu menu;
  631. menu.Attach((HMENU)m_hWindowMenu);
  632. // scan for first window command
  633. int n = menu.GetMenuItemCount();
  634. BOOL bAddSeperator = TRUE;
  635. for (int iPos=0; iPos<n; iPos++) {
  636. if (menu.GetMenuItemID(iPos) >= AFX_IDM_FIRST_MDICHILD) {
  637. bAddSeperator = FALSE;
  638. break;
  639. }
  640. }
  641. while (iPos < (int)menu.GetMenuItemCount())
  642. menu.RemoveMenu(iPos, MF_BYPOSITION);
  643. // get active window so I can check its menu item
  644. ASSERT(m_hWndMDIClient);
  645. HWND hwndActive = (HWND)::SendMessage(m_hWndMDIClient,
  646. WM_MDIGETACTIVE, 0, NULL);
  647. // append window names in the form "# title"
  648. // *****fixed by VORGA, thanks!*****
  649. int iWin;
  650. int nID = AFX_IDM_FIRST_MDICHILD;
  651. CString sWinName, sMenuItem;
  652. HWND hwnd;
  653. for (iWin = 1; iWin <= 10; iWin++, nID++)
  654. {
  655. hwnd = ::GetDlgItem(m_hWndMDIClient, nID);
  656. if (hwnd == NULL)
  657. break;
  658. if (bAddSeperator)
  659. {
  660. menu.InsertMenu(iPos++, MF_BYPOSITION | MF_SEPARATOR);
  661. bAddSeperator = FALSE;
  662. }
  663. if (iWin < 10)
  664. {
  665. CWnd::FromHandle(hwnd)->GetWindowText(sWinName);
  666. sMenuItem.Format(_T("&%d %s"), iWin, (LPCTSTR)sWinName);
  667. menu.InsertMenu(iPos, MF_BYPOSITION, nID, sMenuItem);
  668. if (hwnd == hwndActive)
  669. menu.CheckMenuItem(iPos, MF_BYPOSITION | MF_CHECKED);
  670. }
  671. else
  672. {
  673. menu.InsertMenu(iPos, MF_BYPOSITION, nID, _szMoreWindows);
  674. }
  675. iPos++;
  676. }
  677. menu.Detach();
  678. }
  679. //******************************************************************
  680. void CMenuBar::OnSetMenu(HMENU hNewMenu, HMENU hWindowMenu)
  681. {
  682. if (!bIsTabbed)
  683. ASSERT(m_pMenuIcon && m_pMenuControl);
  684. // We can get active MDI child window on this message!
  685. BOOL bMax = FALSE;
  686. HWND hWndChild = GetActiveChildWnd(bMax);
  687. if (!m_hWndActiveChild || m_hWndActiveChild != hWndChild) {// an active child window changed
  688. LTRACE(_T("CMenuBar::OnSetMenu---an active child window changedn"));
  689. m_hWndActiveChild = hWndChild;
  690. // tell MenuIcon child window has been changed
  691. if (!bIsTabbed)
  692. m_pMenuIcon->OnActivateChildWnd();
  693. }
  694. if (!m_hMenu || m_hMenu != hNewMenu) { // menu changed
  695. LTRACE(_T("CMenuBar::OnSetMenu---menu changedn"));
  696. LoadMenu(hNewMenu, hWindowMenu); // set menubar menu
  697. GetOwner()->SetMenu(NULL); // clear frame menu
  698. }
  699. }
  700. //******************************************************************
  701. BOOL CMenuBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  702. {
  703. CPoint ptCurPos; 
  704. CRect rc;GetClientRect(rc);
  705. GetCursorPos (&ptCurPos);
  706. ScreenToClient (&ptCurPos);
  707. if (m_dwStyle & CBRS_ORIENT_HORZ)
  708. {
  709. rc.right=rc.left+2;
  710. if (ptCurPos.x< 0)
  711. {
  712. SetCursor (LoadCursor(NULL, IDC_SIZEALL));
  713. return TRUE;
  714. }
  715. }
  716. else
  717. {
  718. rc.bottom=rc.top+2;
  719. if (ptCurPos.y< 0)
  720. {
  721. SetCursor (LoadCursor(NULL, IDC_SIZEALL));
  722. return TRUE;
  723. }
  724. }
  725. return CControlBar::OnSetCursor(pWnd, nHitTest, message);
  726. }
  727. //******************************************************************
  728. void CMenuBar::OnNcPaint() 
  729. {
  730. EraseNonClientEx();
  731. }
  732. //******************************************************************
  733. UINT CMenuBar::OnNcHitTest(CPoint point) 
  734. {
  735. // make nonclient area clickable
  736. return HTCLIENT;
  737. }
  738. //******************************************************************
  739. void CMenuBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
  740. {
  741. // calculate border space (will add to top/bottom, subtract from right/bottom)
  742. CRect rect; rect.SetRectEmpty();
  743. BOOL bHorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0;
  744. _CalcInsideRect(rect, bHorz);
  745. if (!(m_dwStyle & CBRS_FLOATING))
  746. {
  747. // adjust non-client area for border space
  748. lpncsp->rgrc[0].left += bHorz?rect.left+4:rect.left+1;
  749. lpncsp->rgrc[0].top += bHorz?rect.top+4:rect.top+2;
  750. }
  751. else
  752. {
  753. lpncsp->rgrc[0].left += rect.left;
  754. lpncsp->rgrc[0].top += rect.top+4;
  755. }
  756. lpncsp->rgrc[0].right += rect.right;
  757. lpncsp->rgrc[0].bottom += rect.bottom;
  758. }
  759. //******************************************************************
  760. void CMenuBar::OnDestroy() 
  761. {
  762. if(m_bCombo==TRUE)
  763. cmb->SaveHistory(szNameHistory,bSaveHistory);
  764. CControlBar::OnDestroy();
  765. // TODO: 
  766. DeleteItems();
  767. if (m_nIDEvent)
  768. KillTimer(m_nIDEvent);
  769. // for SDI application
  770. if (m_bMDIApp == FALSE && m_hMenu != NULL)
  771. ::FreeResource(m_hMenu);
  772. }
  773. //******************************************************************
  774. void CMenuBar::OnTimer(UINT nIDEvent) 
  775. {
  776. if (m_nTrackingState == buttonmouse) {
  777. CPoint pt; ::GetCursorPos(&pt);
  778. CRect rect;
  779. GetWindowRect(&rect);
  780. if (!rect.PtInRect(pt)) {
  781. UpdateBar();
  782. if (m_nIDEvent) {
  783. KillTimer(m_nIDEvent);
  784. m_nIDEvent = NULL;
  785. }
  786. }
  787. }
  788. CControlBar::OnTimer(nIDEvent);
  789. }
  790. //******************************************************************
  791. HWND CMenuBar::GetActiveChildWnd(BOOL& bMaximized)
  792. {
  793. if (!m_hWndMDIClient)
  794. return NULL;
  795. BOOL bMax = FALSE;
  796. HWND hWnd = (HWND)::SendMessage(m_hWndMDIClient,
  797. WM_MDIGETACTIVE, 0, (LPARAM)&bMax);
  798. bMaximized = bMax;
  799. return hWnd;
  800. }
  801. //******************************************************************
  802. /////////////////////////////////////////////////////////////////////////////
  803. // CMenuBar system hook
  804. void CMenuBar::OnMenuSelect(HMENU hMenu, UINT nIndex)
  805. {
  806. // LTRACE(_T("CMenuBar::OnMenuSelectn"));
  807. if (m_nTrackingState == popup) {
  808. m_bProcessRightArrow = (::GetSubMenu(hMenu, nIndex) == NULL);
  809. HMENU hSubMenu = ::GetSubMenu(hMenu, m_nCurIndex);
  810. if (hSubMenu == NULL)
  811. return;
  812. m_bProcessLeftArrow = (hMenu == hSubMenu);
  813. }
  814. }
  815. //******************************************************************
  816. void CMenuBar::OnFrameNcActivate(BOOL bActive) 
  817. {
  818. CFrameWnd* pFrame = GetTopLevelFrame();
  819. ASSERT_VALID(pFrame);
  820. if (pFrame->m_nFlags & WF_STAYACTIVE)
  821. bActive = TRUE;
  822. if (!pFrame->IsWindowEnabled())
  823. bActive = FALSE;
  824. if (bActive == m_bFrameActive)
  825. return;
  826. if (!bActive) {
  827. for (int i = 0; i < GetItemCount(); ++i) {
  828. m_arrItem[i]->ModifyState(0, MISTATE_INACTIVE);
  829. }
  830. }
  831. else {
  832. for (int i = 0; i < GetItemCount(); ++i) {
  833. m_arrItem[i]->ModifyState(MISTATE_INACTIVE, 0);
  834. }
  835. }
  836. m_bFrameActive = bActive;
  837. // InvalidateRect(NULL); is better, but too late
  838. // while clicking the application title bar (like IE5)
  839. // so we have to redraw now!
  840. }
  841. //******************************************************************
  842. LRESULT CALLBACK CMenuBar::MenuInputFilter(int code, WPARAM wParam, LPARAM lParam)
  843. {
  844. return (
  845. code == MSGF_MENU &&
  846. g_pMenuBar &&
  847. g_pMenuBar->OnMenuInput( *((MSG*)lParam) )
  848. ) ? TRUE : CallNextHookEx(g_hMsgHook, code, wParam, lParam);
  849. }
  850. //******************************************************************
  851. void CMenuBar::TrackPopup(int nIndex)
  852. {
  853. ASSERT_VALID(this);
  854. m_nCurIndex = nIndex;
  855. m_bLoop = TRUE;
  856. while (m_bLoop == TRUE) {
  857. UpdateWindow(); // force to repaint when button hidden by other window
  858. UpdateBar(popup, m_nCurIndex);
  859. // install hook
  860. ASSERT(g_pMenuBar == NULL);
  861. g_pMenuBar = this;
  862. ASSERT(g_hMsgHook == NULL);
  863. m_bLoop = FALSE;
  864. g_hMsgHook = ::SetWindowsHookEx(WH_MSGFILTER,
  865. MenuInputFilter, NULL, AfxGetApp()->m_nThreadID);// m_bLoop may become TRUE
  866. // popup!!
  867. m_nTrackingState = popup;
  868. _nPrevIndexForCmd = m_nCurIndex;
  869. m_arrItem[m_nCurIndex]->TrackPopup(this, GetTopLevelParent());
  870. // uninstall hook
  871. ::UnhookWindowsHookEx(g_hMsgHook);
  872. g_hMsgHook = NULL;
  873. g_pMenuBar = NULL;
  874. }
  875. UpdateBar();
  876. }
  877. //******************************************************************
  878. BOOL CMenuBar::OnMenuInput(MSG& m)
  879. {
  880. ASSERT_VALID(this);
  881. int nMsg = m.message;
  882. CPoint pt = m.lParam;
  883. ScreenToClient(&pt);
  884. switch (nMsg) {
  885. case WM_MOUSEMOVE:
  886. if (pt != m_ptMouse) {
  887. int nIndex = HitTestOnTrack(pt);
  888. if ((IsValidIndex(nIndex) && nIndex != m_nCurIndex ) ) {
  889. // defferent button clicked
  890. // Invalidate();
  891. if (!bActivSystemMenu)
  892. AfxGetMainWnd()->PostMessage(WM_CANCELMODE); // destroy popupped menu
  893. if (bActivSystemMenu)
  894. PostMessage(WM_CANCELMODE);
  895. UpdateBar(button, nIndex);
  896. UpdateBar();
  897. bActivSystemMenu=FALSE;
  898. m_nCurIndex = nIndex;
  899. m_bLoop = TRUE; // continue loop
  900. }
  901. m_ptMouse = pt;
  902. }
  903. break;
  904. case WM_LBUTTONDOWN:
  905. if ((HitTestOnTrack(pt) != -1 && HitTestOnTrack(pt) == m_nCurIndex)) {
  906. // same button clicked
  907. AfxGetMainWnd()->PostMessage(WM_CANCELMODE); // destroy popupped menu
  908. //PostMessage(WM_CANCELMODE);
  909. UpdateBar(button, m_nCurIndex);
  910. m_bLoop = FALSE; // out of loop
  911. return TRUE; // eat it!
  912. }
  913. break;
  914. case WM_KEYDOWN: {
  915. TCHAR vKey = m.wParam;
  916. if (m_dwStyle & CBRS_ORIENT_VERT) { // if vertical
  917. break; // do nothing
  918. }
  919. if ((vKey == VK_LEFT  && m_bProcessLeftArrow) ||
  920. (vKey == VK_RIGHT && m_bProcessRightArrow)) {
  921. // no submenu
  922. int nNewIndex = GetNextOrPrevButton(m_nCurIndex, vKey==VK_LEFT);
  923. AfxGetMainWnd()->PostMessage(WM_CANCELMODE); // destroy popupped menu
  924. UpdateBar();
  925. m_nCurIndex = nNewIndex;
  926. m_bLoop = TRUE; // continue loop
  927. return TRUE; // eat it!
  928. }
  929. }
  930. break;
  931. case WM_SYSKEYDOWN:
  932. // LTRACE(_T("    m_bIgnore = TRUEn"));
  933. m_bIgnoreAlt = TRUE; // next SysKeyUp will be ignored
  934. break;
  935. }
  936. return FALSE; // pass along...
  937. }
  938. //******************************************************************
  939. BOOL CMenuBar::TranslateFrameMessage(MSG* pMsg)
  940. {
  941. ASSERT_VALID(this);
  942. ASSERT(pMsg);
  943. UINT nMsg = pMsg->message;
  944. if (WM_LBUTTONDOWN <= nMsg && nMsg <= WM_MOUSELAST) {
  945. if (pMsg->hwnd != m_hWnd && m_nTrackingState > 0) {
  946. // clicked outside
  947. UpdateBar();
  948. }
  949. }
  950. else if (nMsg == WM_SYSKEYDOWN || nMsg == WM_SYSKEYUP || nMsg == WM_KEYDOWN) {
  951. BOOL bAlt = HIWORD(pMsg->lParam) & KF_ALTDOWN; // Alt key presed?
  952. TCHAR vkey = pMsg->wParam; // + X key
  953. if (vkey == VK_MENU ||
  954. (vkey == VK_F10 && !((GetKeyState(VK_SHIFT) & 0x80000000) ||
  955.                    (GetKeyState(VK_CONTROL) & 0x80000000) || bAlt))) {
  956. // only alt key pressed
  957. if (nMsg == WM_SYSKEYUP) {
  958. switch (m_nTrackingState) {
  959. case none:
  960. if (m_bIgnoreAlt == TRUE) {
  961. // LTRACE(_T("    ignore ALT key upn"));
  962. m_bIgnoreAlt = FALSE;
  963. break;
  964. }
  965. if (m_bMDIApp) {
  966. UpdateBar(button, GetNextOrPrevButton(0, FALSE));
  967. }
  968. else {
  969. UpdateBar(button, 0);
  970. }
  971. break;
  972. case button:
  973. UpdateBar();
  974. break;
  975. case buttonmouse:
  976. break; // do nothing
  977. }
  978. }
  979. return TRUE;
  980. }
  981. else if ((nMsg == WM_SYSKEYDOWN || nMsg == WM_KEYDOWN)) {
  982. if (m_nTrackingState == button) {
  983. if (m_dwStyle & CBRS_ORIENT_HORZ) { // if horizontal
  984. switch (vkey) {
  985. case VK_LEFT:
  986. case VK_RIGHT: {
  987. int nNewIndex  = GetNextOrPrevButton(m_nCurIndex, vkey == VK_LEFT);
  988. UpdateBar(button, nNewIndex);
  989. return TRUE;
  990.    }
  991. case VK_SPACE:
  992. case VK_UP:
  993. case VK_DOWN:
  994. TrackPopup(m_nCurIndex);
  995. return TRUE;
  996. case VK_ESCAPE:
  997. UpdateBar();
  998. return TRUE;
  999. }
  1000. }
  1001. else { // if vertical
  1002. switch (vkey) {
  1003. case VK_UP:
  1004. case VK_DOWN:{
  1005. int nNewIndex = GetNextOrPrevButton(m_nCurIndex, vkey == VK_UP);
  1006. UpdateBar(button, nNewIndex);
  1007. return TRUE;
  1008.    }
  1009. case VK_SPACE:
  1010. case VK_RIGHT:
  1011. case VK_LEFT:
  1012. TrackPopup(m_nCurIndex);
  1013. return TRUE;
  1014. case VK_ESCAPE:
  1015. UpdateBar();
  1016. return TRUE;
  1017. }
  1018. }
  1019. }
  1020. // Alt + X pressed
  1021. if ((bAlt || m_nTrackingState == button) && _istalnum(vkey)) {
  1022. int nIndex;
  1023. if (MapAccessKey(vkey, nIndex) == TRUE) {
  1024. UpdateBar(button, nIndex);
  1025. UpdateBar();
  1026. TrackPopup(nIndex);
  1027. return TRUE; // eat it!
  1028. }
  1029. else if (m_nTrackingState==button && !bAlt) {
  1030. // MessageBeep(0); // if you want
  1031. return TRUE;
  1032. }
  1033. }
  1034. if (m_nTrackingState > 0) { // unknown key
  1035. if (m_nTrackingState != buttonmouse) { // if tracked with mouse, don't update bar
  1036. UpdateBar();
  1037. }
  1038. }
  1039. }
  1040. }
  1041. return FALSE; // pass along...
  1042. }
  1043. //******************************************************************
  1044. BOOL CMenuBar::MapAccessKey(TCHAR cAccessKey, int& nIndex)
  1045. {
  1046. for (int i = 0; i < GetItemCount(); ++i) {
  1047. // fixing point
  1048. TCHAR cKey = m_arrItem[i]->GetAccessKey();
  1049. if (toupper(cKey)/*_totupper(cKey)*/ == cAccessKey) {// *****fixed by andi, thanx!*****
  1050. nIndex = i;
  1051. return TRUE;
  1052. }
  1053. }
  1054. return FALSE;
  1055. }
  1056. /////////////////////////////////////////////////////////////////////////////
  1057. // CMenuBar layout
  1058. int CMenuBar::GetClipBoxLength(BOOL bHorz)
  1059. {
  1060. CFrameWnd* pFrame = GetTopLevelFrame(); ASSERT_VALID(pFrame);
  1061. CRect rcFrame; pFrame->GetWindowRect(rcFrame);
  1062. CWnd* pParent = GetParent(); ASSERT_VALID(pParent);
  1063. CRect rcParent; pParent->GetWindowRect(rcParent);
  1064. const int cxFrameBorder = ::GetSystemMetrics(SM_CXFRAME);
  1065. int cxNonClient = cxFrameBorder*2 + m_cxLeftBorder + m_cxRightBorder;
  1066. if (m_dwExStyle & CBRS_GRIPPER)
  1067. cxNonClient += CX_GRIPPER_ALL;
  1068. if (m_dwStyle & CBRS_SIZE_DYNAMIC) {
  1069. if (bHorz) {
  1070. return rcFrame.Width() - cxNonClient;
  1071. }
  1072. else {
  1073. int nResult = rcParent.Height();
  1074. // I don't know the reason of the following code...
  1075. nResult -= m_cxRightBorder + m_cxLeftBorder + cyBorder2*2;
  1076. if (m_dwExStyle & CBRS_GRIPPER)
  1077. nResult -= CY_GRIPPER_ALL;
  1078. return nResult;
  1079. }
  1080. }
  1081. else {
  1082. CRect rect; GetClientRect(rect);
  1083. if (bHorz) {
  1084. return rect.Width();
  1085. }
  1086. else {
  1087. return rect.Height();
  1088. }
  1089. }
  1090. }
  1091. //******************************************************************
  1092. CSize CMenuBar::CalcLayout(DWORD dwMode, int nLength)
  1093. {
  1094. ASSERT_VALID(this);
  1095. ASSERT(::IsWindow(m_hWnd));
  1096. if (dwMode & LM_HORZDOCK)
  1097. ASSERT(dwMode & LM_HORZ);
  1098. // make SC_CLOSE button disable
  1099. if (m_dwStyle & CBRS_FLOATING) {
  1100. CFrameWnd* pMiniFrame = GetParentFrame(); ASSERT_KINDOF(CMiniFrameWnd, pMiniFrame);
  1101. // Don't do this, cause right click menu turns unavairable
  1102. // pMiniFrame->ModifyStyle(WS_SYSMENU, 0);
  1103. CMenu* pSysMenu = pMiniFrame->GetSystemMenu(FALSE); ASSERT_VALID(pSysMenu);
  1104. pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
  1105. }
  1106. int nCount = GetItemCount();
  1107. CSize sizeResult(0, 0);
  1108. if (nCount > 0)
  1109. {
  1110. if (!(m_dwStyle & CBRS_SIZE_FIXED))
  1111. {
  1112. BOOL bDynamic = m_dwStyle & CBRS_SIZE_DYNAMIC;
  1113. if (bDynamic && (dwMode & LM_MRUWIDTH))
  1114. {
  1115. LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_MRUWIDTHn"));
  1116. SizeMenuBar(m_nMRUWidth);
  1117. CalcItemLayout(nCount);// added
  1118. sizeResult = CalcSize(nCount);
  1119. }
  1120. else if (bDynamic && (dwMode & LM_HORZDOCK))
  1121. {
  1122. LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_HORZDOCKn"));
  1123. if (IsFloating() || (m_dwStyle & CBRS_ORIENT_VERT)) {
  1124. // I can't synchronize horz size on dragging with size on dock bar
  1125. // as VC++ developer can't.
  1126. SizeMenuBar(32767);
  1127. }
  1128. else {
  1129. // Menu Button wrapped by frame width
  1130. SizeMenuBar(GetClipBoxLength(TRUE));
  1131. }
  1132. CalcItemLayout(nCount);// added
  1133. sizeResult = CalcSize(nCount);
  1134. if (!IsFloating() && !(m_dwStyle & CBRS_ORIENT_VERT)) {
  1135. if (m_pDockContext->m_pDC) {// while dragging (m_pDockContext->m_bDragging is helpless)
  1136. sizeResult.cx = GetClipBoxLength(TRUE);
  1137. }
  1138. }
  1139. }
  1140. else if (bDynamic && (dwMode & LM_VERTDOCK))
  1141. {
  1142. LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---LM_VERTDOCKn"));
  1143. //SizeMenuBar(0);
  1144. CalcItemLayout(nCount, TRUE);// added
  1145. sizeResult = CalcVertDockSize(nCount);
  1146. if (!IsFloating() && !(m_dwStyle & CBRS_ORIENT_HORZ)) {
  1147. if (m_pDockContext->m_pDC) {// while dragging
  1148. sizeResult.cy = GetClipBoxLength(FALSE);//GetrcParent.Height() - m_cxRightBorder - m_cxLeftBorder;
  1149. }
  1150. }
  1151. }
  1152. else if (bDynamic && (nLength != -1))
  1153. {
  1154. LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---nLength != -1n"));
  1155. CRect rect; rect.SetRectEmpty();
  1156. _CalcInsideRect(rect, (dwMode & LM_HORZ));
  1157. BOOL bVert = (dwMode & LM_LENGTHY);
  1158. int nLen = nLength + (bVert ? rect.Height() : rect.Width());
  1159. SizeMenuBar(nLen, bVert);
  1160. CalcItemLayout(nCount, bVert);// added
  1161. sizeResult = CalcSize(nCount);
  1162. }
  1163. else if (bDynamic && (m_dwStyle & CBRS_FLOATING))
  1164. {
  1165. LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---CBRS_FLOATINGn"));
  1166. SizeMenuBar(m_nMRUWidth);
  1167. CalcItemLayout(nCount);// added
  1168. sizeResult = CalcSize(nCount);
  1169. }
  1170. else
  1171. {
  1172. if (!bDynamic) {
  1173. InvalidateRect(NULL);
  1174. goto Junk;
  1175. }
  1176. LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_DYNAMIC)---othern"));
  1177. BOOL bVert = !(dwMode & LM_HORZ);
  1178. SizeMenuBar(GetClipBoxLength(TRUE));
  1179. CalcItemLayout(nCount, bVert);// added
  1180. if (bVert) {
  1181. InvalidateRect(NULL);// draw forcefully for captions
  1182. sizeResult = CalcVertDockSize(nCount);
  1183. // DockBar not replaced yet, so I can't get precise size
  1184. sizeResult.cy = 10000;
  1185. }
  1186. else {
  1187. sizeResult = CalcSize(nCount);
  1188. sizeResult.cx = GetClipBoxLength(TRUE);
  1189. }
  1190. }
  1191. }
  1192. else {// CBRS_SIZE_FIXED
  1193. LTRACE(_T("CMenuBar::CalcLayout(CBRS_SIZE_FIXED)n"));
  1194. Junk:
  1195. BOOL bVert = !(dwMode & LM_HORZ);
  1196. SizeMenuBar(32767);
  1197. CalcItemLayout(nCount, bVert);// added
  1198. if (bVert) {
  1199. sizeResult = CalcVertDockSize(nCount);
  1200. }
  1201. else {
  1202. sizeResult = CalcSize(nCount);
  1203. }
  1204. }
  1205. if (dwMode & LM_COMMIT)
  1206. {
  1207. LTRACE(_T("CMenuBar::CalcLayout---LM_COMMITn"));
  1208. int nControlCount = 0;
  1209. BOOL bIsDelayed = m_bDelayedButtonLayout;
  1210. m_bDelayedButtonLayout = FALSE;
  1211. if ((m_dwStyle & CBRS_FLOATING) && (m_dwStyle & CBRS_SIZE_DYNAMIC))
  1212. m_nMRUWidth = sizeResult.cx;
  1213. CalcItemLayout(nCount, dwMode);
  1214. m_bDelayedButtonLayout = bIsDelayed;
  1215. }
  1216. }
  1217. //BLOCK: Adjust Margins
  1218. {
  1219. CRect rect; rect.SetRectEmpty();
  1220. _CalcInsideRect(rect, (dwMode & LM_HORZ));
  1221. sizeResult.cy -= rect.Height();
  1222. sizeResult.cx -= rect.Width();
  1223. CSize size = CControlBar::CalcFixedLayout((dwMode & LM_STRETCH), (dwMode & LM_HORZ));
  1224. sizeResult.cx = max(sizeResult.cx, size.cx);
  1225. sizeResult.cy = max(sizeResult.cy, size.cy);
  1226. }
  1227. if (dwMode & LM_HORZ)
  1228. sizeResult.cy+=5;
  1229. else
  1230. sizeResult.cx+=3;
  1231. return sizeResult;
  1232. }
  1233. //******************************************************************
  1234. CSize CMenuBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  1235. {
  1236. LTRACE(_T("CMenuBar::CalcFixedLayoutn"));
  1237. ASSERT_VALID(this);
  1238. ASSERT(::IsWindow(m_hWnd));
  1239. DWORD dwMode = bStretch ? LM_STRETCH : 0;
  1240. dwMode |= bHorz ? LM_HORZ : 0;
  1241. return CalcLayout(dwMode);
  1242. }
  1243. //******************************************************************
  1244. CSize CMenuBar::CalcDynamicLayout(int nLength, DWORD dwMode)
  1245. {
  1246. LTRACE(_T("CMenuBar::CalcDynamicLayoutn"));
  1247. if ((nLength == -1) && !(dwMode & LM_MRUWIDTH) && !(dwMode & LM_COMMIT) &&
  1248. ((dwMode & LM_HORZDOCK) || (dwMode & LM_VERTDOCK)))
  1249. {
  1250. LTRACE(_T("    FixedLayoutn"));
  1251. return CalcFixedLayout(dwMode & LM_STRETCH, dwMode & LM_HORZDOCK);
  1252. }
  1253. return CalcLayout(dwMode, nLength);
  1254. }
  1255. // set m_bWrapped by nWidth
  1256. int CMenuBar::WrapMenuBar(int nCount, int nWidth)
  1257. {
  1258. // LTRACE(_T("CMenuBar::WrapMenuBarn"));
  1259. int nResult = 0;
  1260. int x = 0;
  1261. for (int i = 0; i < nCount; ++i) {
  1262. CMenuItem* pItem = m_arrItem[i];
  1263. if (i+1 == nCount)
  1264. return ++nResult;
  1265. if (x + pItem->GetHorizontalSize().cx> nWidth) {// itself is over
  1266. if (pItem->GetStyle() & MISTYLE_WRAPPABLE) {
  1267. pItem->ModifyState(0, MISTATE_WRAP);
  1268. ++nResult;
  1269. x = 0;
  1270. }
  1271. }
  1272. else if (x + pItem->GetHorizontalSize().cx + 
  1273.  m_arrItem[i+1]->GetHorizontalSize().cx> nWidth) {
  1274. if (pItem->GetStyle() & MISTYLE_WRAPPABLE) {
  1275. pItem->ModifyState(0, MISTATE_WRAP);
  1276. ++nResult;
  1277. x = 0;
  1278. }
  1279. }
  1280. else {
  1281. pItem->ModifyState(MISTATE_WRAP, 0);
  1282. x += pItem->GetHorizontalSize().cx;
  1283. }
  1284. }
  1285. return nResult + 1;
  1286. }
  1287. //******************************************************************
  1288. // calc only size, by using m_bWrapped
  1289. CSize CMenuBar::CalcSize(int nCount)
  1290. {
  1291. ASSERT(nCount > 0);
  1292. CPoint cur(0,0);
  1293. CSize sizeResult(0,0);
  1294. int nWrap = 0;
  1295. for (int i = 0; i < nCount; ++i) {
  1296. CMenuItem* pItem = m_arrItem[i];
  1297. sizeResult.cx = max(cur.x + pItem->GetHorizontalSize().cx, sizeResult.cx);
  1298. sizeResult.cy = max(cur.y + pItem->GetHorizontalSize().cy, sizeResult.cy);
  1299. cur.x += pItem->GetHorizontalSize().cx;
  1300. if (pItem->GetState() & MISTATE_WRAP) {
  1301. //LTRACE(_T("    nIndex:%d is wrappedn"), i);
  1302. cur.x = 0;// reset x pos
  1303. cur.y += pItem->GetHorizontalSize().cy;
  1304. ++nWrap;
  1305. }
  1306. }
  1307. return sizeResult;
  1308. }
  1309. //******************************************************************
  1310. void CMenuBar::Layout()
  1311. {
  1312. ASSERT(m_bDelayedButtonLayout);
  1313. m_bDelayedButtonLayout = FALSE;
  1314. BOOL bHorz = (m_dwStyle & CBRS_ORIENT_HORZ) != 0;
  1315. if ((m_dwStyle & CBRS_FLOATING) && (m_dwStyle & CBRS_SIZE_DYNAMIC))
  1316. ((CMenuBar*)this)->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH | LM_COMMIT);
  1317. else if (bHorz)
  1318. ((CMenuBar*)this)->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK | LM_COMMIT);
  1319. else
  1320. ((CMenuBar*)this)->CalcDynamicLayout(0, LM_VERTDOCK | LM_COMMIT);
  1321. }
  1322. //******************************************************************
  1323. void CMenuBar::SizeMenuBar(int nLength, BOOL bVert)
  1324. {
  1325. //LTRACE("CMenuBar::SizeMenuBarn");
  1326. int nCount = GetItemCount(); ASSERT(nCount > 0);
  1327. if (!bVert) { // nLength is horizontal length
  1328. if (IsFloating()) { // half size wrapping
  1329. CSize sizeMax, sizeMin, sizeMid;
  1330. // Wrap MenuBar vertically
  1331. WrapMenuBar(nCount, 0);
  1332. sizeMin = CalcSize(nCount);
  1333. // Wrap MenuBar horizontally
  1334. WrapMenuBar(nCount, 32767);
  1335. sizeMax = CalcSize(nCount);
  1336. // we can never understand this algorithm :), see CToolBar implementation
  1337. while (sizeMin.cx < sizeMax.cx) {
  1338. // LTRACE("looping sizeMin.cx:%d < sizeMax.cx:%dn", sizeMin.cx, sizeMax.cx);
  1339. sizeMid.cx = (sizeMin.cx + sizeMax.cx) / 2;
  1340. WrapMenuBar(nCount, sizeMid.cx);
  1341. sizeMid = CalcSize(nCount);
  1342. if (sizeMid.cx == sizeMax.cx) { // if you forget, it loops forever!
  1343. return;
  1344. }
  1345. // LTRACE("    sizeMid : %d %dn", sizeMid.cx, sizeMid.cy);
  1346. if (nLength >= sizeMax.cx) {
  1347. // LTRACE("    nLength:%d >= sizeMax.cx:%dn", nLength, sizeMax.cx);
  1348. if (sizeMin == sizeMid) {
  1349. WrapMenuBar(nCount, sizeMax.cx);
  1350. // LTRACE("out SizeMenuBarn");
  1351. return;
  1352. }
  1353. sizeMin = sizeMid;
  1354. }
  1355. else if (nLength < sizeMax.cx) {
  1356. // LTRACE("    nLength:%d < sizeMax.cx:%dn", nLength, sizeMax.cx);
  1357. sizeMax = sizeMid;
  1358. }
  1359. else {
  1360. // LTRACE("out SizeMenuBarn");
  1361. return;
  1362. }
  1363. }
  1364. }
  1365. else { // each one wrapping
  1366. //LTRACE("    just each one wrappingn");
  1367. WrapMenuBar(nCount, nLength);
  1368. }
  1369. }
  1370. else { // nLength is vertical length
  1371. CSize sizeMax, sizeMin, sizeMid;
  1372. // Wrap MenuBar vertically
  1373. WrapMenuBar(nCount, 0);
  1374. sizeMin = CalcSize(nCount);
  1375. // Wrap MenuBar horizontally
  1376. WrapMenuBar(nCount, 32767);
  1377. sizeMax = CalcSize(nCount);
  1378. while (sizeMin.cx < sizeMax.cx) {
  1379. sizeMid.cx = (sizeMin.cx + sizeMax.cx) / 2;
  1380. WrapMenuBar(nCount, sizeMid.cx);
  1381. sizeMid = CalcSize(nCount);
  1382. if (sizeMid.cx == sizeMax.cx) {
  1383. return;
  1384. }
  1385. if (nLength < sizeMid.cy) {
  1386. if (sizeMin == sizeMid) {
  1387. WrapMenuBar(nCount, sizeMax.cx);
  1388. //LTRACE("out SizeMenuBarn");
  1389. return;
  1390. }
  1391. sizeMin = sizeMid;
  1392. }
  1393. else if (nLength > sizeMid.cy)
  1394. sizeMax = sizeMid;
  1395. else {
  1396. //LTRACE("out SizeMenuBarn");
  1397. return;
  1398. }
  1399. }
  1400. }
  1401. //LTRACE("out SizeMenuBarn");
  1402. }
  1403. //***********************************************************************************
  1404. void CMenuBar::DrawCombo()
  1405. {
  1406. CRect rect;
  1407. GetClientRect(rect);
  1408. CalcSizeItem();
  1409. CWnd* pFrame = GetTopLevelFrame();
  1410. BOOL bMaximized = FALSE;
  1411. //la idea es verificar que la ventana es MDI
  1412. if (pFrame->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)))
  1413. {
  1414. ASSERT_VALID(pFrame);
  1415. CMDIFrameWnd* pMDIFrame = STATIC_DOWNCAST(CMDIFrameWnd, pFrame);
  1416. HWND hWndMDIClient = pMDIFrame->m_hWndMDIClient;
  1417. ASSERT(::IsWindow(hWndMDIClient));
  1418. HWND hWndChild = (HWND)::SendMessage(hWndMDIClient,
  1419. WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
  1420. }
  1421. if ((m_dwStyle & CBRS_ORIENT_HORZ) && m_bCombo==TRUE && !(m_dwStyle & CBRS_FLOATING))
  1422. {
  1423. CRect reccombo;
  1424. cmb->GetClientRect (&reccombo);
  1425. if (rect.Width() > m_sizex+(bMaximized?30:0)+reccombo.Width() )
  1426. {
  1427. cmb->ShowWindow(SW_SHOW);
  1428. CRect rctemp=rect;
  1429. rctemp.top=-1;
  1430. rctemp.bottom-=2;
  1431. int nDif;
  1432. if (!bIsTabbed)
  1433.    nDif=bMaximized?60:0;
  1434. else
  1435.    nDif=0;
  1436. rctemp.left=rctemp.right-reccombo.Width()-  nDif;
  1437. rctemp.right=rctemp.left+reccombo.Width();
  1438. cmb->MoveWindow(rctemp);
  1439. }
  1440. else
  1441. {
  1442. cmb->ShowWindow(SW_HIDE);
  1443. }
  1444. }
  1445. }
  1446. //******************************************************************
  1447. void CMenuBar::CalcSizeItem()
  1448. {
  1449. m_sizex=0;
  1450. for(int i = 0; i < m_arrItem.GetSize(); ++i) {
  1451. CMenuItem* pItem = m_arrItem[i];
  1452. m_sizex+=pItem->GetRect().Width();
  1453. }
  1454. }
  1455. //******************************************************************
  1456. CSize CMenuBar::CalcVertDockSize(int nCount)
  1457. {
  1458. ASSERT(nCount > 0);
  1459. CSize sizeResult(0, 0);
  1460. for (int i = 0; i < nCount; ++i) {
  1461. CMenuItem* pItem = m_arrItem[i];
  1462. sizeResult.cy += pItem->GetRect().Height();
  1463. }
  1464. sizeResult.cx = _cyMenuOnBar;
  1465. return sizeResult;
  1466. }
  1467. //******************************************************************
  1468. void CMenuBar::CalcItemLayout(int nCount, BOOL bVert)
  1469. {
  1470. ASSERT(nCount > 0);
  1471. int x = 0; int y = 0;
  1472. if (!bVert) {
  1473. for (int i = 0; i < nCount; ++i) {
  1474. CMenuItem* pItem = m_arrItem[i];
  1475. CPoint ptItem(x, y);
  1476. pItem->Layout(ptItem, TRUE);// layout by itself!
  1477. if (pItem->GetState() & MISTATE_WRAP) {
  1478. x = 0;// reset x to 0
  1479. y += pItem->GetRect().Height();
  1480. }
  1481. else
  1482. x += pItem->GetRect().Width();
  1483. }
  1484. }
  1485. else {
  1486. for (int i = 0; i < nCount; ++i) {
  1487. CMenuItem* pItem = m_arrItem[i];
  1488. CPoint ptItem(0, y);
  1489. pItem->Layout(ptItem, FALSE); // layout by itself
  1490. y += pItem->GetRect().Height();
  1491. }
  1492. }
  1493. }
  1494. //******************************************************************
  1495. //////////////////////////////////////////////////////////////////////
  1496. // Added by Koay Kah Hoe. Thanx!
  1497. void CMenuBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  1498. {
  1499. if (m_bMDIApp)
  1500. CheckActiveChildWndMaximized();
  1501. }
  1502. //******************************************************************
  1503. //////////////////////////////////////////////////////////////////////
  1504. // CMenuBar decoration
  1505. void CMenuBar::_DrawGripper(CWindowDC* dc,CRect* rcWin)
  1506. {
  1507. if (m_dwStyle & CBRS_FLOATING) return ;
  1508. if(m_StyleDisplay == GUISTYLE_2003) //no es XP
  1509. {
  1510. if (m_dwStyle & CBRS_ORIENT_HORZ)
  1511. {
  1512. rcWin->top+=(rcWin->Height()/2)-4;
  1513. rcWin->left+=7;
  1514. rcWin->right=rcWin->left+2;
  1515. rcWin->bottom-=8;
  1516. CRect rcBlack;
  1517. for (int i=0; i < rcWin->Height(); i+=4)
  1518. {
  1519. CRect rcWindow;
  1520. CBrush cb;
  1521. cb.CreateSolidBrush(::GetSysColor(COLOR_BTNHIGHLIGHT));
  1522. rcWindow=rcWin;
  1523. rcWindow.top=rcWin->top+i;
  1524. rcWindow.bottom=rcWindow.top+2;
  1525. dc->FillRect(rcWindow,&cb);
  1526. rcBlack=rcWindow;
  1527. rcBlack.left-=1;
  1528. rcBlack.top=(rcWin->top+i)-1;
  1529. rcBlack.bottom=rcBlack.top+2;
  1530. rcBlack.right=rcBlack.left+2;
  1531. cb.DeleteObject();
  1532. cb.CreateSolidBrush(GuiDrawLayer::GetRGBColorShadow(m_StyleDisplay));
  1533. dc->FillRect(rcBlack,&cb);
  1534. }
  1535. }
  1536. else
  1537. {
  1538. rcWin->top+=3;
  1539. rcWin->left+=4;
  1540. rcWin->right-=2;
  1541. rcWin->bottom=rcWin->top+2;
  1542. CRect rcBlack;
  1543. for (int i=0; i < rcWin->Width(); i+=4)
  1544. {
  1545. CRect rcWindow;
  1546. CBrush cb;
  1547. cb.CreateSolidBrush(::GetSysColor(COLOR_BTNHIGHLIGHT));
  1548. rcWindow=rcWin;
  1549. rcWindow.left=rcWindow.left+i;
  1550. rcWindow.right=rcWindow.left+2;
  1551. dc->FillRect(rcWindow,&cb);
  1552. rcBlack=rcWindow;
  1553. rcBlack.top-=1;
  1554. rcBlack.left-=1;
  1555. rcBlack.bottom=rcBlack.top+2;
  1556. rcBlack.right=rcBlack.left+2;
  1557. cb.DeleteObject();
  1558. cb.CreateSolidBrush(GuiDrawLayer::GetRGBColorShadow(m_StyleDisplay));
  1559. dc->FillRect(rcBlack,&cb);
  1560. }
  1561. }
  1562. }
  1563. else
  1564. {
  1565. if (m_dwStyle & CBRS_ORIENT_HORZ)
  1566. {
  1567. rcWin->top+=(rcWin->Height()/2)-4;
  1568. rcWin->left+=7;
  1569. rcWin->right=rcWin->left+3;
  1570. rcWin->bottom-=6;
  1571. for (int i=0; i < rcWin->Height(); i+=2)
  1572. {
  1573. CRect rcWindow;
  1574. CBrush cb;
  1575. cb.CreateSolidBrush(::GetSysColor(COLOR_BTNSHADOW));
  1576. rcWindow=rcWin;
  1577. rcWindow.top=rcWin->top+i;
  1578. rcWindow.bottom=rcWindow.top+1;
  1579. dc->FillRect(rcWindow,&cb);
  1580. }
  1581. }
  1582. else
  1583. {
  1584. rcWin->top+=2;
  1585. rcWin->left+=2;
  1586. rcWin->right-=2;
  1587. rcWin->bottom=rcWin->top+3;
  1588. for (int i=0; i < rcWin->Width(); i+=2)
  1589. {
  1590. CRect rcWindow;
  1591. CBrush cb;
  1592. cb.CreateSolidBrush(::GetSysColor(COLOR_BTNSHADOW));
  1593. rcWindow=rcWin;
  1594. rcWindow.left=rcWindow.left+i;
  1595. rcWindow.right=rcWindow.left+1;
  1596. dc->FillRect(rcWindow,&cb);
  1597. }
  1598. }
  1599. }
  1600. }
  1601. //******************************************************************
  1602. void CMenuBar::EraseNonClientEx()
  1603. {
  1604. // get window DC that is clipped to the non-client area
  1605. CRect rcWindow;
  1606. CRect rcClient;
  1607. CWindowDC dc(this);
  1608. GetWindowRect(&rcWindow);
  1609. GetClientRect(&rcClient);
  1610. CBrush cbr;
  1611. cbr.CreateSolidBrush(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  1612. rcClient.OffsetRect(-rcWindow.TopLeft());
  1613.     rcWindow.OffsetRect(-rcWindow.TopLeft());
  1614.     ScreenToClient(rcWindow);
  1615. rcClient.OffsetRect(-rcWindow.left, - rcWindow.top);
  1616. dc.ExcludeClipRect(rcClient);   
  1617. rcWindow.OffsetRect(-rcWindow.left, -rcWindow.top);
  1618. int ibotton = rcWindow.bottom;
  1619. rcWindow.top = rcWindow.bottom - 1;
  1620. dc.FillRect(rcWindow, &cbr); 
  1621. rcWindow.top = 0;
  1622. rcWindow.bottom += 3;
  1623. dc.FillRect(rcWindow, &cbr); 
  1624. dc.FillSolidRect(0, rcWindow.top + 1, rcWindow.right + 1, 1, 
  1625. GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style)); 
  1626. cbr.DeleteObject();
  1627. // draw gripper in non-client area
  1628. _DrawGripper(&dc, &rcWindow);
  1629. }
  1630. #define CX_BORDER   1
  1631. #define CY_BORDER   1
  1632. //******************************************************************
  1633. void CMenuBar::DrawRaisedBorders(CDC* pDC, CRect& rect)
  1634. {
  1635. ASSERT_VALID(this);
  1636. ASSERT_VALID(pDC);
  1637. DWORD dwStyle = m_dwStyle;
  1638. if (!(dwStyle & CBRS_BORDER_ANY))
  1639. return;
  1640. // prepare for dark lines
  1641. ASSERT(rect.top == 0 && rect.left == 0);
  1642. CRect rect1, rect2;
  1643. rect1 = rect;
  1644. rect2 = rect;
  1645. COLORREF clrBtnShadow = GuiDrawLayer::GetRGBColorShadow(GuiDrawLayer::m_Style);//afxData.bWin4 ? afxData.clrBtnShadow : afxData.clrWindowFrame;
  1646. COLORREF clrBtnFace = GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style);
  1647. COLORREF clrBtnHilight = ::GetSysColor(COLOR_BTNHILIGHT);
  1648. // draw dark line one pixel back/up
  1649. if (dwStyle & CBRS_BORDER_3D)
  1650. {
  1651. rect1.right -= CX_BORDER;
  1652. rect1.bottom -= CY_BORDER;
  1653. }
  1654. if (dwStyle & CBRS_BORDER_TOP)
  1655. rect2.top += cyBorder2;
  1656. if (dwStyle & CBRS_BORDER_BOTTOM)
  1657. rect2.bottom -= cyBorder2;
  1658. // draw left and top
  1659. if (dwStyle & CBRS_BORDER_LEFT)
  1660. pDC->FillSolidRect(0, rect2.top, CX_BORDER, rect2.Height(), clrBtnFace);
  1661. if (dwStyle & CBRS_BORDER_TOP)
  1662. pDC->FillSolidRect(0, 0, rect.right, CY_BORDER, clrBtnFace);
  1663. // draw right and bottom
  1664. if (dwStyle & CBRS_BORDER_RIGHT)
  1665. pDC->FillSolidRect(rect1.right, rect2.top, -CX_BORDER, rect2.Height(), clrBtnShadow);
  1666. if (dwStyle & CBRS_BORDER_BOTTOM)
  1667. pDC->FillSolidRect(0, rect1.bottom, rect.right, -CY_BORDER, clrBtnShadow);
  1668. if (dwStyle & CBRS_BORDER_3D)
  1669. {
  1670. // draw left and top
  1671. if (dwStyle & CBRS_BORDER_LEFT)
  1672. pDC->FillSolidRect(1, rect2.top, CX_BORDER, rect2.Height(), clrBtnHilight);
  1673. if (dwStyle & CBRS_BORDER_TOP)
  1674. pDC->FillSolidRect(0, 1, rect.right, CY_BORDER, clrBtnHilight);
  1675. // draw right and bottom
  1676. if (dwStyle & CBRS_BORDER_RIGHT)
  1677. pDC->FillSolidRect(rect.right, rect2.top, -CX_BORDER, rect2.Height(), clrBtnFace);
  1678. if (dwStyle & CBRS_BORDER_BOTTOM)
  1679. pDC->FillSolidRect(0, rect.bottom, rect.right, -CY_BORDER, clrBtnFace);
  1680. }
  1681. if (dwStyle & CBRS_BORDER_LEFT)
  1682. rect.left += cxBorder2;
  1683. if (dwStyle & CBRS_BORDER_TOP)
  1684. rect.top += cyBorder2;
  1685. if (dwStyle & CBRS_BORDER_RIGHT)
  1686. rect.right -= cxBorder2;
  1687. if (dwStyle & CBRS_BORDER_BOTTOM)
  1688. rect.bottom -= cyBorder2;
  1689. }
  1690. //******************************************************************
  1691. int CMenuBar::GetNextOrPrevButton(int nIndex, BOOL bPrev)
  1692. {
  1693. int nCount = GetItemCount();
  1694. if (bPrev) { // <-
  1695. --nIndex;
  1696. if (nIndex < 0)
  1697. nIndex = nCount - 1;
  1698. }
  1699. else { // ->
  1700. ++nIndex;
  1701. if (nIndex >= nCount)
  1702. nIndex = 0;
  1703. }
  1704. if (!(m_arrItem[nIndex]->GetStyle() & MISTYLE_TRACKABLE) ||
  1705. (m_arrItem[nIndex]->GetState() & MISTATE_HIDDEN)) {
  1706. return GetNextOrPrevButton(nIndex, bPrev);
  1707. }
  1708. return nIndex;
  1709. }
  1710. //******************************************************************
  1711. /////////////////////////////////////////////////////////////////////////////
  1712. // CMenuBar OLE menu support
  1713. // MFC does'nt do command routing for other process server.
  1714. // ::TrackPopupMenuEx won't accept HWND of other process and
  1715. // we have to determine a message target(ole server window or not)
  1716. // as ::OleCreateMenuDescriptor do.
  1717. // This is a hard coding. 
  1718. // First menu(ordinarily File menu) and WindowMenu regarded as container's own menu.
  1719. // Some components can't update toolbar button and statusbar pane.
  1720. HWND CMenuBar::OleMenuDescriptor(BOOL& bSend, UINT nMsg, WPARAM wParam, LPARAM lParam)
  1721. {
  1722. CWnd* pOleWnd = GetCmdSentOleWnd();
  1723. if (pOleWnd == NULL)
  1724. return NULL;
  1725. HWND hWndSentCmd = NULL;
  1726. HMENU hMenu = NULL;
  1727. if (nMsg == WM_INITMENUPOPUP || nMsg == WM_INITMENU)
  1728. hMenu = (HMENU)wParam;
  1729. else if (nMsg == WM_MENUSELECT)
  1730. hMenu = (HMENU)lParam;
  1731. switch (nMsg) {
  1732. case WM_INITMENUPOPUP:
  1733. case WM_INITMENU:
  1734. case WM_MENUSELECT:
  1735. bSend = TRUE;
  1736. if (m_nTrackingState == popup) {
  1737. LTRACE2(_T("    now popupn"));
  1738. if (m_bMDIApp) {
  1739. LTRACE2(_T("    this is MDIn"));
  1740. if (m_nCurIndex == 0 || m_nCurIndex == 1 || hMenu == m_hWindowMenu) {
  1741. LTRACE2(_T("    it's container menu, send to framen"));
  1742. return NULL;
  1743. }
  1744. }
  1745. else {
  1746. LTRACE2(_T("    it's container menu, send to framen"));
  1747. if (m_nCurIndex == 0) {
  1748. return NULL;
  1749. }
  1750. }
  1751. LTRACE2(_T("    it's server menu, send to servern"));
  1752. return pOleWnd->GetSafeHwnd();
  1753. }
  1754. break;
  1755. case WM_COMMAND:
  1756. bSend = FALSE;
  1757. if (m_bMDIApp) {
  1758. LTRACE2(_T("    this is MDIn"));
  1759. if (_nPrevIndexForCmd == 0 || _nPrevIndexForCmd == 1 || _bWindowMenuSendCmd) {
  1760. LTRACE2(_T("    it's container menu, send to framen"));
  1761. return NULL;
  1762. }
  1763. }
  1764. else {
  1765. if (_nPrevIndexForCmd == 0) {
  1766. LTRACE2(_T("    it's container menu, send to framen"));
  1767. return NULL;
  1768. }
  1769. }
  1770. LTRACE2(_T("    it's server menu, send to servern"));
  1771. return pOleWnd->GetSafeHwnd();
  1772. }
  1773. return NULL;// send to frame
  1774. }
  1775. //******************************************************************
  1776. CWnd* CMenuBar::GetCmdSentOleWnd()
  1777. {
  1778. // *****fixed by VORGA, thanks!*****
  1779. CWnd* pWnd = AfxGetMainWnd();
  1780. if (pWnd == NULL || !pWnd->IsFrameWnd())
  1781. return NULL;
  1782. CFrameWnd* pFrame = NULL;
  1783. if (m_bMDIApp) {
  1784. CMDIFrameWnd *pMDIFrame = STATIC_DOWNCAST(CMDIFrameWnd, pWnd);
  1785. if (pMDIFrame == NULL)
  1786. return NULL;
  1787. pFrame = pMDIFrame->GetActiveFrame();
  1788. }
  1789. else {
  1790. pFrame = STATIC_DOWNCAST(CFrameWnd, pWnd);
  1791. }
  1792. if (pFrame == NULL)
  1793. return NULL;
  1794. CDocument* pDoc = pFrame->GetActiveDocument();
  1795. if (pDoc != NULL && pDoc->IsKindOf(RUNTIME_CLASS(COleDocument))) {
  1796. COleDocument* pOleDoc = STATIC_DOWNCAST(COleDocument, pDoc);
  1797. ASSERT_VALID(pOleDoc);
  1798. COleClientItem* pClientItem = pOleDoc->GetInPlaceActiveItem(pFrame);
  1799. CWnd* pWnd = (pClientItem == NULL) ? NULL : pClientItem->GetInPlaceWindow();
  1800. if (pWnd != NULL) {
  1801. return pWnd;
  1802. }
  1803. }
  1804. return NULL;
  1805. }
  1806. //******************************************************************
  1807. /////////////////////////////////////////////////////////////////////////////
  1808. // CMDIClientHook 
  1809. CMDIClientHook::CMDIClientHook()
  1810. {
  1811. m_pMenuBar = NULL;
  1812. }
  1813. //******************************************************************
  1814. BOOL CMDIClientHook::Install(CMenuBar* pMenuBar, HWND hWndToHook)
  1815. {
  1816. ASSERT_VALID(pMenuBar);
  1817. ASSERT(m_pMenuBar == NULL);
  1818. m_pMenuBar = pMenuBar;
  1819. return HookWindow(hWndToHook);
  1820. }
  1821. //******************************************************************
  1822. CMDIClientHook::~CMDIClientHook()
  1823. {
  1824. HookWindow((HWND)NULL);
  1825. }
  1826. //******************************************************************
  1827. LRESULT CMDIClientHook::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
  1828. {
  1829. ASSERT_VALID(m_pMenuBar);
  1830. switch (nMsg) {
  1831. case WM_MDISETMENU: // only sent to MDI client window
  1832. // Setting new frame/window menu: bypass MDI. wParam is new menu.
  1833. if (wParam) {
  1834. //LTRACE(_T("CMenuBar::WM_MDISETMENU 0x%04xn"), wParam);
  1835. m_pMenuBar->OnSetMenu((HMENU)wParam, (HMENU)lParam);
  1836. }
  1837. return 0;
  1838. case WM_MDIREFRESHMENU: // only sent to MDI client window
  1839. // Normally, would call DrawMenuBar, but I have the menu, so eat it.
  1840. //LTRACE(_T("CMenuBar::WM_MDIREFRESHMENUn"));
  1841. return 0;
  1842. }
  1843. return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
  1844. }
  1845. //******************************************************************
  1846. /////////////////////////////////////////////////////////////////////////////
  1847. // CMainFrameHook 
  1848. CMainFrameHook::CMainFrameHook()
  1849. {
  1850. m_pMenuBar = NULL;
  1851. }
  1852. //******************************************************************
  1853. BOOL CMainFrameHook::Install(CMenuBar* pMenuBar, HWND hWndToHook)
  1854. {
  1855. ASSERT_VALID(pMenuBar);
  1856. ASSERT(m_pMenuBar == NULL);
  1857. m_pMenuBar = pMenuBar;
  1858. return HookWindow(hWndToHook);
  1859. }
  1860. //******************************************************************
  1861. CMainFrameHook::~CMainFrameHook()
  1862. {
  1863. }
  1864. //******************************************************************
  1865. LRESULT CMainFrameHook::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
  1866. {
  1867. ASSERT_VALID(m_pMenuBar);
  1868. // be care for other windows(MainFrame) hooking
  1869. // possible called when already this wnd destroyed (WM_NCACTIVATE is)
  1870. if (!::IsWindow(m_pMenuBar->m_hWnd)) {
  1871. return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
  1872. }
  1873. BOOL bSend = FALSE;
  1874. if (HWND hWndServer = m_pMenuBar->OleMenuDescriptor(bSend, nMsg, wParam, lParam)) {
  1875. // OLE wnd will handle message
  1876. if (bSend)
  1877. return ::SendMessage(hWndServer, nMsg, wParam, lParam);
  1878. else
  1879. return ::PostMessage(hWndServer, nMsg, wParam, lParam);
  1880. }
  1881. switch (nMsg) {
  1882. case WM_MENUSELECT:
  1883. m_pMenuBar->OnMenuSelect((HMENU)lParam, (UINT)LOWORD(wParam));
  1884. break;
  1885. case WM_INITMENUPOPUP:
  1886. if (!HIWORD(lParam) && (HMENU)wParam == m_pMenuBar->m_hWindowMenu)
  1887. m_pMenuBar->OnInitMenuPopup(CMenu::FromHandle((HMENU)wParam),
  1888. LOWORD(lParam), (BOOL)HIWORD(lParam));
  1889. break;
  1890. case WM_NCACTIVATE:
  1891. m_pMenuBar->OnFrameNcActivate((BOOL)wParam);
  1892. break;
  1893. case WM_SYSCOLORCHANGE:
  1894. case WM_SETTINGCHANGE:
  1895. LTRACE(_T("CMenuBar::WM_SETTINGCHANGEn"));
  1896. // It's enough to reinitialize common resources once.
  1897. m_pMenuBar->OnSettingChange(wParam, lParam);
  1898. break;
  1899. }
  1900. if (nMsg == CMenuBar::WM_GETMENU)
  1901. return (LRESULT)m_pMenuBar->m_hMenu;
  1902. return CSubclassWnd::WindowProc(nMsg, wParam, lParam);
  1903. }
  1904. //******************************************************************
  1905. //////////////////////////////////////////////////////////////////////
  1906. // CMenuItem interface
  1907. CMenuItem::CMenuItem()
  1908. {
  1909. m_fsStyle = 0;
  1910. m_fsState = 0;
  1911. m_rcItem.SetRectEmpty();
  1912. m_sizeHorz = CSize(0, 0);
  1913. m_cAccessKey = 0;
  1914. }
  1915. //******************************************************************
  1916. void CMenuItem::ModifyState(BYTE fsRemove, BYTE fsAdd)
  1917. {
  1918. m_fsState = (m_fsState & ~fsRemove) | fsAdd;
  1919. }
  1920. //******************************************************************
  1921. CSize CMenuItem::GetHorizontalSize() const
  1922. {
  1923. if (m_fsState & MISTATE_HIDDEN)
  1924. return CSize(0, 0);
  1925. else
  1926. return m_sizeHorz;
  1927. }
  1928. //-----------------------------------------------------------------
  1929. CGuiMenuButton::CGuiMenuButton()
  1930. {
  1931. m_bHorz=TRUE;
  1932. }
  1933. CGuiMenuButton::~CGuiMenuButton()
  1934. {
  1935. }
  1936. void CGuiMenuButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  1937. {
  1938. CDC*  pdc= CDC::FromHandle(lpDrawItemStruct->hDC);
  1939. CRect rc=lpDrawItemStruct->rcItem;
  1940. UINT  uState=lpDrawItemStruct->itemState;
  1941. CBrush cb;
  1942. if( uState & ODS_SELECTED) //the button is pressed
  1943. cb.CreateSolidBrush(GuiDrawLayer::GetRGBPressBXP());
  1944. else
  1945. if (m_bMouserOver)
  1946. {
  1947. if(m_StyleDisplay==GUISTYLE_2003)
  1948. {
  1949. if (GuiDrawLayer::m_Theme)
  1950. {
  1951. CGradient M(CSize(rc.Width(),rc.Height()));
  1952. M.PrepareCaption(pdc,m_StyleDisplay);
  1953. M.Draw(pdc,rc.left,rc.top,0,0,rc.Width(),rc.Height(),SRCCOPY);
  1954. cb.CreateStockObject(NULL_BRUSH);
  1955. }
  1956. else
  1957. cb.CreateSolidBrush(GuiDrawLayer::GetRGBFondoXP());
  1958. }
  1959. else
  1960. cb.CreateSolidBrush(GuiDrawLayer::GetRGBFondoXP());
  1961. }
  1962. else
  1963. {
  1964. if(m_StyleDisplay==GUISTYLE_2003)
  1965. cb.CreateSolidBrush(GuiDrawLayer::GetRGBColorFace(m_StyleDisplay));
  1966. else
  1967. cb.CreateSolidBrush(m_clColor);
  1968. }
  1969. if (( uState == ODS_SELECTED) || m_bMouserOver )
  1970. {
  1971. pdc->Draw3dRect(rc,GuiDrawLayer::GetRGBCaptionXP(),GuiDrawLayer::GetRGBCaptionXP());
  1972. rc.DeflateRect(1,1);
  1973. }
  1974. pdc->FillRect(rc,&cb);
  1975. if (m_SizeText.cx > 2)
  1976. {
  1977. int nMode = pdc->SetBkMode(TRANSPARENT);
  1978. if (m_bHorz)
  1979. {
  1980. CRect rectletra=rc;
  1981. CPoint pt=CSize(rectletra.top+1,rectletra.left);
  1982. if (uState & ODS_DISABLED)
  1983. pdc->DrawState(pt, m_SizeText, m_szText, DSS_DISABLED, TRUE, 0, (CBrush*)NULL);
  1984. else
  1985. {
  1986. if(m_bMouserOver != 1) 
  1987. pdc->SetTextColor(m_clrFont);
  1988. pdc->DrawText(m_szText,rectletra,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  1989. }
  1990. }
  1991. else
  1992. {
  1993. if (( uState == ODS_SELECTED) || m_bMouserOver )
  1994. rc.InflateRect(1,1);
  1995. COLORREF clr = ::GetSysColor(COLOR_MENUTEXT);
  1996. pdc->SetTextColor(clr);
  1997. CPoint ptOffset=CPoint(1,1);
  1998. CRect rcBtn = rc;
  1999. int nLength = m_szText.GetLength();
  2000. int nIndex = m_szText.Find('&');
  2001. CString strBtn = m_szText.Left(nIndex) + m_szText.Right(nLength - (nIndex+1));
  2002. // fixed for WinNT. *****fixed by Simon, thanks!*****
  2003. int iGraphicsMode = ::GetGraphicsMode(pdc->m_hDC);
  2004. ::SetGraphicsMode(pdc->m_hDC, GM_ADVANCED);
  2005. pdc->SetBkMode(TRANSPARENT);
  2006. CFont* pOldFont = pdc->SelectObject(&_fontVertMenu);
  2007. // I know precise text size
  2008. //m_sizeHorz=((CMenuBar*)GetParent())->m_sizeHors;
  2009. CSize m_sizeHorz;
  2010. m_sizeHorz.cx = (_CalcTextWidth(m_szText) + CXTEXTMARGIN*2)+8;
  2011. m_sizeHorz.cy = (_cyHorzFont + _cyTextMargin*2)+1;
  2012. CRect rcString = CRect(
  2013. CPoint(rcBtn.right - _cyTextMargin, rcBtn.top + CXTEXTMARGIN), m_sizeHorz);
  2014. pdc->DrawText(strBtn, rcString + ptOffset,
  2015. DT_SINGLELINE | DT_NOCLIP | DT_NOPREFIX);// don't forget DT_NOCLIP
  2016. gbintHorz=-1;
  2017. rcMenu=rcBtn;
  2018. rcMenu.bottom-=3;
  2019. pdc->SelectObject(pOldFont);
  2020. // CDC::DrawText is poor, so we have to draw vertical line by ourselves
  2021. CPen pen(PS_SOLID, 0, clr);
  2022. CPen* pOldPen = pdc->SelectObject(&pen);
  2023. CPoint m_ptLineFrom;
  2024. CPoint m_ptLineTo;
  2025. if (nIndex == 0) {
  2026. m_ptLineFrom = CPoint(_cyTextMargin-1, CXTEXTMARGIN+1);
  2027. m_ptLineTo  = CPoint(_cyTextMargin-1, CXTEXTMARGIN + _CalcTextWidth(strBtn.Left(nIndex+1)));
  2028. }
  2029. else {
  2030. m_ptLineFrom = CPoint(_cyTextMargin-1, CXTEXTMARGIN + _CalcTextWidth(strBtn.Left(nIndex+1)));
  2031. m_ptLineTo = CPoint(_cyTextMargin-1, CXTEXTMARGIN + _CalcTextWidth(strBtn.Left(nIndex+1)));
  2032. }
  2033. pdc->MoveTo(rcBtn.TopLeft() + m_ptLineFrom);
  2034. pdc->LineTo(rcBtn.TopLeft() + m_ptLineTo );
  2035. pdc->SelectObject(pOldPen);
  2036. ::SetGraphicsMode( pdc->m_hDC, iGraphicsMode );
  2037. }
  2038. }
  2039. }
  2040. BEGIN_MESSAGE_MAP(CGuiMenuButton,CGuiToolButton)
  2041. ON_WM_LBUTTONDOWN()
  2042. END_MESSAGE_MAP()
  2043. void CGuiMenuButton::OnLButtonDown(UINT nFlags, CPoint point)
  2044. {
  2045. ShowWindow(SW_HIDE);
  2046. ClientToScreen(&point);
  2047. GetParent()->SendMessage(WM_LBUTTONDOWN,100+GetDlgCtrlID(),MAKEWPARAM(point.x,point.y));
  2048. }
  2049. CGuiIconButton::CGuiIconButton()
  2050. {
  2051. }
  2052. CGuiIconButton::~CGuiIconButton()
  2053. {
  2054. ::FreeResource(m_Icon);
  2055. }
  2056. void CGuiIconButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  2057. {
  2058. CDC*  pdc= CDC::FromHandle(lpDrawItemStruct->hDC);
  2059. CRect rc=lpDrawItemStruct->rcItem;
  2060. UINT  uState=lpDrawItemStruct->itemState;
  2061. CBrush cb;
  2062. cb.CreateSolidBrush(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2063. pdc->FillRect(rc,&cb);
  2064. CPoint m_point=CPoint(1,1);
  2065. if (m_SizeImage.cx > 2)
  2066. {
  2067. pdc->DrawState (m_point, m_SizeImage,m_Icon,
  2068. (uState==ODS_DISABLED?DSS_DISABLED:DSS_NORMAL),(CBrush*)NULL);
  2069. }
  2070. }
  2071. BEGIN_MESSAGE_MAP(CGuiIconButton,CGuiToolButton)
  2072. ON_WM_LBUTTONDOWN()
  2073. END_MESSAGE_MAP()
  2074. void CGuiIconButton::OnLButtonDown(UINT nFlags, CPoint point)
  2075. {
  2076. ClientToScreen(&point);
  2077. GetParent()->SendMessage(WM_LBUTTONDOWN,1000,MAKEWPARAM(point.x,point.y));
  2078. }
  2079. //-----------------------------------------------------------------
  2080. //******************************************************************
  2081. //////////////////////////////////////////////////////////////////////
  2082. // CMenuButton class
  2083. CMenuButton::CMenuButton(HMENU hMenu, int nIndex,CWnd* pWnd)
  2084. {
  2085. ASSERT(::IsMenu(hMenu));
  2086. ASSERT(nIndex >= 0);
  2087. pParent=pWnd;
  2088. m_cfont.CreateFont(-11,0,0,0,400,0,0,0,0,1,2,1,34,"MS Sans Serif");
  2089. m_fsStyle |= (MISTYLE_TRACKABLE | MISTYLE_WRAPPABLE);
  2090. m_bt.Create(_T(""), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, 
  2091. CRect(0,0,0,0), pWnd, nIndex);
  2092. m_bt.SetFont(&_fontHorzMenu);
  2093. m_bt.StyleDispl(GuiDrawLayer::m_Style);
  2094. m_bt.SetColor(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2095. InitButtonStringAndSubMenuHandle(hMenu, nIndex);
  2096. InitHorizontalButtonSize();
  2097. InitAccessKeyAndVerticalLinePoint();
  2098. }
  2099. //******************************************************************
  2100. // ERNESTO
  2101. void CMenuButton::SetText(TCHAR *szText)
  2102. {
  2103. m_strBtn  = szText;
  2104. InitHorizontalButtonSize();
  2105. InitAccessKeyAndVerticalLinePoint();
  2106. }
  2107. //******************************************************************
  2108. void CMenuButton::InitButtonStringAndSubMenuHandle(HMENU hMenu, int nIndex)
  2109. {
  2110. // get menu button Text
  2111. TCHAR szText[256];
  2112. MENUITEMINFO info; ::memset(&info, 0, sizeof(MENUITEMINFO));
  2113. info.cbSize = sizeof(MENUITEMINFO);
  2114. info.fMask = MIIM_ID | MIIM_TYPE;
  2115. info.dwTypeData = szText;
  2116. info.cch = sizeof(szText);
  2117. ::GetMenuItemInfo(hMenu, nIndex, TRUE, &info);
  2118. m_strBtn = CString(szText);
  2119. m_bt.SetCaption(m_strBtn);
  2120. m_hSubMenu = ::GetSubMenu(hMenu, nIndex);
  2121. if (!m_hSubMenu) {
  2122. m_nID = ::GetMenuItemID(hMenu, nIndex);
  2123. ASSERT(m_nID != -1);
  2124. }
  2125. else {
  2126. m_nID = -1;
  2127. }
  2128. }
  2129. //******************************************************************
  2130. void CMenuButton::InitHorizontalButtonSize()
  2131. {
  2132. // get menu button Text size
  2133. ASSERT(m_strBtn.IsEmpty() == FALSE);
  2134. m_sizeHorz.cx = (_CalcTextWidth(m_strBtn) + CXTEXTMARGIN*2)+8;
  2135. m_sizeHorz.cy = (_cyHorzFont + _cyTextMargin*2)+1;
  2136. }
  2137. //******************************************************************
  2138. void CMenuButton::InitAccessKeyAndVerticalLinePoint()
  2139. {
  2140. int nIndex = m_strBtn.Find('&');
  2141. if (nIndex + 1 == m_strBtn.GetLength()) {
  2142. TRACE(_T("warning : & is bad position, access key is invalid.n"));
  2143. m_cAccessKey = 0;
  2144. m_ptLineFrom = m_ptLineTo = CPoint(0, 0);
  2145. return;
  2146. }
  2147. m_cAccessKey = m_strBtn[nIndex + 1];// -1 + 1 = 0; it's ok
  2148. if (nIndex == -1) {
  2149. m_ptLineFrom = m_ptLineTo = CPoint(0, 0);
  2150. }
  2151. else if (nIndex == 0) {
  2152. m_ptLineFrom = CPoint(_cyTextMargin, CXTEXTMARGIN);
  2153. m_ptLineTo  = CPoint(_cyTextMargin, CXTEXTMARGIN + _CalcTextWidth(m_strBtn.Left(nIndex+2)));
  2154. }
  2155. else {
  2156. m_ptLineFrom = CPoint(_cyTextMargin, CXTEXTMARGIN + _CalcTextWidth(m_strBtn.Left(nIndex)));
  2157. m_ptLineTo = CPoint(_cyTextMargin, CXTEXTMARGIN + _CalcTextWidth(m_strBtn.Left(nIndex+2)));
  2158. }
  2159. }
  2160. //******************************************************************
  2161. void CMenuButton::Layout(CPoint point, BOOL bHorz)
  2162. {
  2163. if (bHorz)
  2164. m_fsState |= MISTATE_HORZ;
  2165. else
  2166. m_fsState &= ~MISTATE_HORZ;
  2167. if (m_fsState & MISTATE_HIDDEN) {
  2168. m_rcItem.SetRectEmpty();
  2169. return;
  2170. }
  2171. if (bHorz) {
  2172. m_rcItem = CRect(point, m_sizeHorz);
  2173. }
  2174. else {
  2175. m_rcItem = CRect(point, CSize(m_sizeHorz.cy, m_sizeHorz.cx));
  2176. }
  2177. }
  2178. //******************************************************************
  2179. void CMenuButton::Update(CDC* pDC)
  2180. {
  2181. if (m_fsState & MISTATE_HIDDEN)
  2182. return;
  2183. // clean background
  2184. COLORREF clr = GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style );
  2185. pDC->FillSolidRect(m_rcItem, clr);
  2186. if (m_fsState & MISTATE_HOT){
  2187. if (m_bt.IsWindowVisible()) m_bt.ShowWindow(SW_HIDE);
  2188. DrawHot(pDC);
  2189. }
  2190. else if (m_fsState & MISTATE_PRESSED){
  2191. if (m_bt.IsWindowVisible()) m_bt.ShowWindow(SW_HIDE);
  2192. DrawPressed(pDC);
  2193. }
  2194. else {
  2195. DrawNone(pDC);
  2196. }
  2197. }
  2198. //*********************************************************
  2199. void CMenuButton::TrackPopup(CWnd* pBar, CWnd* pWndSentCmd)
  2200. {
  2201. LTRACE(_T("CMenuButton::TrackPopupn"));
  2202. ASSERT_VALID(pBar);
  2203. ASSERT(!(m_fsState & MISTATE_HIDDEN));
  2204. pMenuBar = STATIC_DOWNCAST(CMenuBar, pBar);
  2205. ASSERT_VALID(pMenuBar);
  2206. // "! menu" (no sub menu)
  2207. if (!m_hSubMenu) {
  2208. ASSERT(m_nID != -1);
  2209. pWndSentCmd->SendMessage(WM_COMMAND, (WPARAM)m_nID, (LPARAM)pBar->GetSafeHwnd());
  2210. return;
  2211. }
  2212. CRect rcItem(m_rcItem); pMenuBar->ClientToScreen(rcItem);
  2213. UINT fuFlags; TPMPARAMS tpm;
  2214. CPoint pt = _ComputeMenuTrackPoint(rcItem, pMenuBar->GetBarStyle(), fuFlags, tpm);
  2215. if (m_hSubMenu == pMenuBar->m_hWindowMenu)
  2216. _bWindowMenuSendCmd = TRUE;
  2217. else
  2218. _bWindowMenuSendCmd = FALSE;
  2219. if (pMenuBar->GetBarStyle() & CBRS_ORIENT_HORZ)
  2220. {
  2221. pt.x+=1; pt.y-=2;
  2222. }
  2223. else
  2224. {
  2225. pt.x-=2; pt.y+=2;
  2226. }
  2227. ::TrackPopupMenuEx(m_hSubMenu, fuFlags,
  2228. pt.x, pt.y, pWndSentCmd->GetSafeHwnd(), &tpm);
  2229. gbintHorz=-1;
  2230. rcMenu.SetRectEmpty();
  2231. }
  2232. //****************************************************************
  2233. void CMenuButton::DrawHorzText(CDC* pDC, CPoint ptOffset)
  2234. {
  2235. COLORREF clr = (m_fsState & MISTATE_INACTIVE) ? 
  2236. ::GetSysColor(COLOR_GRAYTEXT) : ::GetSysColor(COLOR_MENUTEXT);
  2237. pDC->SetTextColor(clr);
  2238. CRect rcBtn = m_rcItem;
  2239. rcBtn.right-=1;
  2240. pDC->SetBkMode(TRANSPARENT);
  2241. CFont* pOldFont = pDC->SelectObject(&_fontHorzMenu);
  2242. // I know precise text size, but better to leave this job to Windows
  2243. // *****fixed by andi, thanks!*****
  2244. ptOffset.y-=1;
  2245. ptOffset.x+=2;
  2246. pDC->DrawText(m_strBtn, rcBtn + ptOffset,
  2247. DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  2248. pDC->SelectObject(pOldFont);
  2249. gbintHorz=0;
  2250. rcMenu=rcBtn;
  2251. rcMenu.right-=4;
  2252. }
  2253. //******************************************************************
  2254. void CMenuButton::DrawVertText(CDC* pDC, CPoint ptOffset)
  2255. {
  2256. COLORREF clr = (m_fsState & MISTATE_INACTIVE) ? 
  2257. ::GetSysColor(COLOR_GRAYTEXT) : ::GetSysColor(COLOR_MENUTEXT);
  2258. pDC->SetTextColor(clr);
  2259. CRect rcBtn = m_rcItem;
  2260. int nLength = m_strBtn.GetLength();
  2261. int nIndex = m_strBtn.Find('&');
  2262. CString strBtn = m_strBtn.Left(nIndex) + m_strBtn.Right(nLength - (nIndex+1));
  2263. // fixed for WinNT. *****fixed by Simon, thanks!*****
  2264. int iGraphicsMode = ::GetGraphicsMode(pDC->m_hDC);
  2265. ::SetGraphicsMode(pDC->m_hDC, GM_ADVANCED);
  2266. pDC->SetBkMode(TRANSPARENT);
  2267. CFont* pOldFont = pDC->SelectObject(&_fontVertMenu);
  2268. // I know precise text size
  2269. CRect rcString = CRect(
  2270. CPoint(rcBtn.right - _cyTextMargin, rcBtn.top + CXTEXTMARGIN), m_sizeHorz);
  2271. pDC->DrawText(strBtn, rcString + ptOffset,
  2272. DT_SINGLELINE | DT_NOCLIP | DT_NOPREFIX);// don't forget DT_NOCLIP
  2273. gbintHorz=1;
  2274. rcMenu=rcBtn;
  2275. rcMenu.bottom-=3;
  2276. pDC->SelectObject(pOldFont);
  2277. // CDC::DrawText is poor, so we have to draw vertical line by ourselves
  2278. CPen pen(PS_SOLID, 0, clr);
  2279. CPen* pOldPen = pDC->SelectObject(&pen);
  2280. rcBtn.left-=2;
  2281. pDC->MoveTo(rcBtn.TopLeft() + m_ptLineFrom + ptOffset);
  2282. pDC->LineTo(rcBtn.TopLeft() + m_ptLineTo + ptOffset);
  2283. pDC->SelectObject(pOldPen);
  2284. ::SetGraphicsMode( pDC->m_hDC, iGraphicsMode );
  2285. }
  2286. //******************************************************************
  2287. void CMenuButton::DrawButton(CDC* pDC,WORD wState)
  2288. {
  2289. CBrush cblu;
  2290. CRect rcBtn =m_rcItem;
  2291. if (dSt & CBRS_ORIENT_HORZ )
  2292. rcBtn.right-=4;
  2293. else
  2294. rcBtn.bottom-=2;
  2295. if (wState & BDR_RAISEDINNER)
  2296. pDC->Draw3dRect(rcBtn,m_dw.GetRGBCaptionXP(),m_dw.GetRGBCaptionXP());
  2297. else
  2298. {
  2299. if (dSt & CBRS_ORIENT_HORZ )
  2300. rcBtn.bottom+=1;
  2301. else
  2302. rcBtn.bottom-=1;
  2303. COLORREF ColBorder;
  2304. if (GuiDrawLayer::m_Style==GUISTYLE_XP)
  2305. ColBorder = GuiDrawLayer::GetRGBMenu();
  2306. else
  2307. ColBorder=GuiDrawLayer::GetRGBColorShadow(GuiDrawLayer::m_Style);
  2308. pDC->Draw3dRect(rcBtn,ColBorder,ColBorder);
  2309. if (dSt & CBRS_ORIENT_HORZ )
  2310. rcBtn.bottom-=1;
  2311. else
  2312. rcBtn.bottom+=1;
  2313. if (GuiDrawLayer::m_Style == GUISTYLE_2003)
  2314. {
  2315. CRect rcb=rcBtn;
  2316. if (dSt & CBRS_ORIENT_HORZ)
  2317. {
  2318. CGradient M(CSize(rcb.Width(),rcb.Height()));
  2319. M.PrepareVertical(pDC,GuiDrawLayer::m_Style);
  2320. M.Draw(pDC,rcb.left+1,rcb.top+1,0,0,rcb.Width()-2,rcb.Height(),SRCCOPY);
  2321. }
  2322. else
  2323. {
  2324. CGradient M(CSize(rcb.Width(),rcb.Height()));
  2325. M.PrepareHorizontal(pDC,GuiDrawLayer::m_Style);
  2326. M.Draw(pDC,rcb.left+1,rcb.top+1,0,0,rcb.Width(),rcb.Height()-3,SRCCOPY);
  2327. }
  2328. }
  2329. COLORREF ColB = GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style);
  2330. CPen pen(PS_SOLID, 0, ColB);
  2331. CPen* pOldPen = pDC->SelectObject(&pen);
  2332. pDC->MoveTo(rcBtn.left, rcBtn.bottom);
  2333. pDC->LineTo(rcBtn.right, rcBtn.bottom);
  2334. COLORREF ColA = GetSysColor(COLOR_WINDOW);
  2335. CRect rect = rcBtn;
  2336. int X,Y;
  2337. X=Y=0;
  2338. int winH = rect.Height(); 
  2339. int winW = rect.Width();
  2340. if (dSt & CBRS_ORIENT_HORZ )
  2341. rect.right+=4;
  2342. // Simulate a shadow on right edge... 
  2343. for (X=1; X<=4 ;X++)
  2344.   for (Y=0; Y<4 ;Y++)
  2345. pDC->SetPixel(rect.right-X,Y+rect.top, ColB );
  2346.   for (Y=4; Y<8 ;Y++)
  2347.   pDC->SetPixel(rect.right-X,Y+rect.top,GuiDrawLayer::DarkenColor(3 * X * (Y - 3), ColB)) ;
  2348.   for (Y=8; Y<=(winH-1) ;Y++)
  2349. pDC->SetPixel(rect.right - X, Y+rect.top, GuiDrawLayer::DarkenColor(15 * X, ColB) );
  2350. }
  2351. }
  2352. else
  2353. {
  2354.   rect.bottom+=2;
  2355.   for(Y=1; Y<=3 ;Y++)
  2356.   {
  2357. for(X=0; X<=3 ;X++)
  2358. {
  2359.   pDC->SetPixel(X,rect.bottom-Y,pDC->GetPixel(rect.left+X,rect.bottom-Y)) ;
  2360. }
  2361. for(X=4; X<=7 ;X++)
  2362. {
  2363.   COLORREF c = pDC->GetPixel(rect.left + X, rect.bottom - Y) ;
  2364.   pDC->SetPixel(X, rect.bottom - Y, GuiDrawLayer::DarkenColor(3 * (X - 3) * Y, c)) ;
  2365. }
  2366. for(X=8; X<=(winW-2) ;X++)
  2367. {
  2368.   COLORREF  c = pDC->GetPixel(rect.left + X, rect.bottom - Y); 
  2369.   pDC->SetPixel(X, rect.bottom- Y, GuiDrawLayer::DarkenColor(15 * Y, c)) ;
  2370. }
  2371.   }   
  2372.   
  2373. }
  2374. pDC->SelectObject(pOldPen);
  2375. }
  2376. rcBtn.DeflateRect(1,1);
  2377. if (wState & BDR_RAISEDINNER)
  2378. {
  2379. cblu.CreateSolidBrush(m_dw.GetRGBFondoXP());
  2380. pDC->FillRect(rcBtn,&cblu);
  2381. }
  2382. }
  2383. //******************************************************************
  2384. void CMenuButton::DrawHot(CDC* pDC)
  2385. {
  2386. if (m_fsState & MISTATE_HORZ) {
  2387. // draw pressed button
  2388. dSt=CBRS_ORIENT_HORZ;
  2389. DrawButton(pDC,BDR_RAISEDINNER);
  2390. //pDC->DrawEdge(m_rcItem, BDR_RAISEDINNER, BF_RECT);
  2391. DrawHorzText(pDC,CPoint(-1, 1));
  2392. }
  2393. else {
  2394. dSt=CBRS_ORIENT_VERT;
  2395. DrawButton(pDC,BDR_RAISEDINNER);
  2396. //pDC->DrawEdge(m_rcItem, BDR_RAISEDINNER, BF_RECT);
  2397. DrawVertText(pDC);
  2398. }
  2399. }
  2400. //******************************************************************
  2401. void CMenuButton::DrawPressed(CDC* pDC)
  2402. {
  2403. if (m_fsState & MISTATE_HORZ) {
  2404. DrawButton(pDC,BDR_SUNKENOUTER);
  2405. //pDC->DrawEdge(m_rcItem, BDR_SUNKENOUTER, BF_RECT);// draw pressed button
  2406. DrawHorzText(pDC, CPoint(-1, 1));
  2407. }
  2408. else {
  2409. DrawButton(pDC,BDR_SUNKENOUTER);
  2410. //pDC->DrawEdge(m_rcItem, BDR_SUNKENOUTER, BF_RECT);
  2411. DrawVertText(pDC, CPoint(1, 1));
  2412. }
  2413. }
  2414. //--------------------------------
  2415. //--------------------------------
  2416. //******************************************************************
  2417. void CMenuButton::DrawNone(CDC* pDC)
  2418. {
  2419. CRect rcBtn = m_rcItem;
  2420. if (!m_bt.IsWindowVisible())
  2421. m_bt.ShowWindow(SW_SHOW);
  2422. m_bt.MoveWindow(rcBtn);
  2423. if (m_fsState & MISTATE_HORZ) {
  2424. m_bt.SetHorzVert();
  2425. }
  2426. else {
  2427. CRect rcBtn = m_rcItem;
  2428. m_bt.SetHorzVert(FALSE);
  2429. }
  2430. }
  2431. void CMenuButton::UpdateButtons()
  2432. {
  2433. if (m_bt.IsWindowVisible())
  2434. {
  2435. CRect rcBtn = m_rcItem;
  2436. m_bt.ShowWindow(SW_SHOW);
  2437. m_bt.MoveWindow(rcBtn);
  2438. m_bt.Invalidate();
  2439. m_bt.UpdateWindow();
  2440. }
  2441. }
  2442. //******************************************************************
  2443. //////////////////////////////////////////////////////////////////////
  2444. // CMenuIcon class
  2445. CMenuIcon::CMenuIcon(CWnd* pMenuBar)
  2446. {
  2447. ASSERT_VALID(pMenuBar);
  2448. m_pMenuBar = pMenuBar;
  2449. m_hIconWinLogo = AfxGetApp()->LoadStandardIcon(IDI_WINLOGO);
  2450. ASSERT(m_hIconWinLogo);
  2451. m_btnIcon.Create(_T(""), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, 
  2452. CRect(0,0,0,0), pMenuBar, 0x999);
  2453. m_btnIcon.ShowWindow(SW_HIDE);
  2454. m_btnIcon.SetScrollButton();
  2455. m_fsStyle |= MISTYLE_TRACKABLE;
  2456. m_fsState |= MISTATE_HIDDEN;
  2457. m_sizeHorz = CSize(::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
  2458. }
  2459. //******************************************************************
  2460. CMenuIcon::~CMenuIcon()
  2461. {
  2462. if (m_hIconWinLogo != NULL) 
  2463. ::FreeResource(m_hIconWinLogo);
  2464. }
  2465. //******************************************************************
  2466. void CMenuIcon::OnActivateChildWnd()
  2467. {
  2468. //LTRACE(_T("CMenuIcon::OnActivateChildWndn"));
  2469. ASSERT_VALID(m_pMenuBar);
  2470. CWnd* pFrame = m_pMenuBar->GetTopLevelFrame();
  2471. ASSERT_VALID(pFrame);
  2472. CMDIFrameWnd* pMDIFrame = STATIC_DOWNCAST(CMDIFrameWnd, pFrame);
  2473. HWND hWndMDIClient = pMDIFrame->m_hWndMDIClient;
  2474. ASSERT(::IsWindow(hWndMDIClient));
  2475. BOOL bMaximized = FALSE;
  2476. HWND hWndChild = (HWND)::SendMessage(hWndMDIClient,
  2477. WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
  2478. if (bMaximized == FALSE) {
  2479. //LTRACE(_T("    not maximizedn"));
  2480. m_fsState |= MISTATE_HIDDEN;
  2481. m_btnIcon.ShowWindow(SW_HIDE);
  2482. }
  2483. else {
  2484. //LTRACE(_T("    maximizedn"));
  2485. m_fsState &= ~MISTATE_HIDDEN;
  2486. m_btnIcon.SethIcon(m_hDocIcon);
  2487. m_btnIcon.ShowWindow(SW_SHOW);
  2488. }
  2489. m_hDocIcon = (HICON)::GetClassLong(hWndChild, GCL_HICONSM);
  2490. if (m_hDocIcon == NULL) // if hWndChild doesn't have own icon
  2491. m_hDocIcon = m_hIconWinLogo;
  2492. }
  2493. //******************************************************************
  2494. void CMenuIcon::Update(CDC* pDC)
  2495. {
  2496. if (m_fsState & MISTATE_HIDDEN)
  2497. return;
  2498. ASSERT(m_hDocIcon);
  2499. ASSERT(m_rcItem.IsRectEmpty() == FALSE);
  2500. m_btnIcon.MoveWindow(m_rcItem);
  2501. ::DrawIconEx(pDC->m_hDC, m_rcItem.left, m_rcItem.top, m_hDocIcon,
  2502. m_rcItem.Width(), m_rcItem.Height(), 0, NULL, DI_NORMAL);
  2503. }
  2504. void CMenuIcon::UpdateButtons()
  2505. {
  2506. }
  2507. //******************************************************************
  2508. void CMenuIcon::TrackPopup(CWnd* pBar, CWnd* pWndSentCmd)
  2509. {
  2510. ASSERT(!(m_fsState & MISTATE_HIDDEN));
  2511. ASSERT_VALID(m_pMenuBar);
  2512. CWnd* pFrame = m_pMenuBar->GetTopLevelFrame();
  2513. ASSERT_VALID(pFrame);
  2514. CMDIFrameWnd* pMDIFrame = STATIC_DOWNCAST(CMDIFrameWnd, pFrame);
  2515. HWND hWndMDIClient = pMDIFrame->m_hWndMDIClient;
  2516. ASSERT(::IsWindow(hWndMDIClient));
  2517. BOOL bMaximized = FALSE;
  2518. HWND hWndChild = (HWND)::SendMessage(hWndMDIClient,
  2519. WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
  2520. ASSERT(bMaximized);
  2521. HMENU hSysMenu = ::GetSystemMenu(hWndChild, FALSE);
  2522. ASSERT(::IsMenu(hSysMenu));
  2523. CControlBar* pControlBar = STATIC_DOWNCAST(CControlBar, m_pMenuBar);
  2524. ASSERT_VALID(pControlBar);
  2525. CRect rcItem(m_rcItem); m_pMenuBar->ClientToScreen(rcItem);
  2526. UINT fuFlags; TPMPARAMS tpm;
  2527. bActivSystemMenu=TRUE;
  2528. CPoint pt = _ComputeMenuTrackPoint(rcItem, pControlBar->GetBarStyle(), fuFlags, tpm);
  2529. gbintHorz=-1;
  2530. CRect rcBtn=CRect(0,0,0,0);
  2531. CRect rcMenu=rcBtn;
  2532. ::TrackPopupMenuEx(hSysMenu, fuFlags, pt.x, pt.y,m_pMenuBar->GetSafeHwnd(), &tpm);
  2533. bActivSystemMenu=FALSE;
  2534. }
  2535. //******************************************************************
  2536. void CMenuIcon::Layout(CPoint point, BOOL bHorz)
  2537. {
  2538. if (bHorz)
  2539. m_fsState |= MISTATE_HORZ;
  2540. else
  2541. m_fsState &= ~MISTATE_HORZ;
  2542. if (m_fsState & MISTATE_HIDDEN) {
  2543. m_rcItem.SetRectEmpty();
  2544. return;
  2545. }
  2546. m_rcItem = CRect(point, CSize(::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON)));
  2547. }
  2548. //******************************************************************
  2549. //////////////////////////////////////////////////////////////////////
  2550. // CMenuControl class
  2551. #define CX_GAP_CAPTION 2
  2552. CMenuControl::CMenuControl(CWnd* pMenuBar)
  2553. {
  2554. ASSERT_VALID(pMenuBar);
  2555. m_pMenuBar = pMenuBar;
  2556. m_bDown = FALSE;
  2557. m_nTracking = -1;
  2558. m_fsState |= MISTATE_HIDDEN;
  2559. if (!m_img.Create(IDB_GUI_MDIICONS,9,3,RGB(255,0,255)))
  2560. {
  2561. TRACE0("error");
  2562. }
  2563. m_arrButton[2].Create(_T(""), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, 
  2564. CRect(0,0,0,0),m_pMenuBar, SC_CLOSE);
  2565. m_arrButton[2].SethIcon(m_img.ExtractIcon(2));
  2566. m_arrButton[2].SetToolTip("Close");
  2567. m_arrButton[2].SetColor(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2568. m_arrButton[2].ShowDark(FALSE);
  2569. m_arrButton[1].Create(_T(""), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, 
  2570. CRect(0,0,0,0),m_pMenuBar, SC_RESTORE);
  2571. m_arrButton[1].SethIcon(m_img.ExtractIcon(1));
  2572. m_arrButton[1].SetToolTip("Restore");
  2573. m_arrButton[1].SetColor(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2574. m_arrButton[1].ShowDark(FALSE);
  2575. m_arrButton[0].Create(_T(""), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, 
  2576. CRect(0,0,0,0),m_pMenuBar,SC_MINIMIZE);
  2577. m_arrButton[0].SethIcon(m_img.ExtractIcon(0));
  2578. m_arrButton[0].SetToolTip("Minimize");
  2579. m_arrButton[0].SetColor(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2580. m_arrButton[0].ShowDark(FALSE);
  2581. CSize sizeCaption = GetCaptionSize();
  2582. m_sizeHorz = CSize(sizeCaption.cx*3 + CX_GAP_CAPTION + 1, sizeCaption.cy + 2);
  2583. }
  2584. void CMenuControl::SetColorButton(COLORREF clrBtn)
  2585. {
  2586. m_arrButton[2].SetColor(clrBtn);
  2587. m_arrButton[1].SetColor(clrBtn);
  2588. m_arrButton[0].SetColor(clrBtn);
  2589. }
  2590. //******************************************************************
  2591. void CMenuControl::Update(CDC* pDC)
  2592. {
  2593. // do nothing
  2594. }
  2595. void CMenuControl::UpdateButtons()
  2596. {
  2597. }
  2598. //******************************************************************
  2599. void CMenuControl::Layout(CPoint point, BOOL bHorz)
  2600. {
  2601. //LTRACE(_T("CMenuControl::Layout bHorz:%dn"), bHorz);
  2602. if (bHorz)
  2603. m_fsState |= MISTATE_HORZ;
  2604. else
  2605. m_fsState &= ~MISTATE_HORZ;
  2606. if (m_fsState & MISTATE_HIDDEN) {
  2607. m_rcItem.SetRectEmpty();
  2608. return;
  2609. }
  2610. // just layout easily
  2611. if (bHorz) {
  2612. m_rcItem = CRect(point, m_sizeHorz);
  2613. }
  2614. else {
  2615. m_rcItem = CRect(point, CSize(m_sizeHorz.cy, m_sizeHorz.cx));
  2616. }
  2617. }
  2618. //******************************************************************
  2619. void CMenuControl::DelayLayoutAndDraw(CDC* pDC, CSize sizeBar,BOOL bFlota)
  2620. {
  2621. CSize sizeCaption = GetCaptionSize();
  2622. int cxCaption = sizeCaption.cx;
  2623. int cyCaption = sizeCaption.cy;
  2624. if (m_fsState & MISTATE_HORZ) {
  2625. CRect rcCaption;
  2626. rcCaption.right = !bFlota?sizeBar.cx-5:sizeBar.cx;
  2627. rcCaption.bottom = sizeBar.cy-3;
  2628. rcCaption.left = rcCaption.right - cxCaption;
  2629. rcCaption.top = (rcCaption.bottom - cyCaption);
  2630. m_arrCaption[0] = rcCaption;
  2631. rcCaption -= CPoint(cxCaption+CX_GAP_CAPTION, 0);
  2632. m_arrCaption[1] = rcCaption;
  2633. rcCaption -= CPoint(cxCaption, 0);
  2634. m_arrCaption[2] = rcCaption;
  2635. m_rcItem = CRect(m_arrCaption[2].left, m_arrCaption[2].top,
  2636. m_arrCaption[0].right, m_arrCaption[0].bottom);
  2637. }
  2638. else {
  2639. CRect rcCaption;
  2640. rcCaption.left = 0;
  2641. rcCaption.bottom = sizeBar.cy-5;
  2642. rcCaption.right = rcCaption.left + cxCaption;
  2643. rcCaption.top = rcCaption.bottom - cyCaption;
  2644. m_arrCaption[0] = rcCaption;
  2645. rcCaption -= CPoint(0, cyCaption+CX_GAP_CAPTION);
  2646. m_arrCaption[1] = rcCaption;
  2647. rcCaption -= CPoint(0, cyCaption);
  2648. m_arrCaption[2] = rcCaption;
  2649. m_rcItem = CRect(m_arrCaption[2].left, m_arrCaption[2].top,
  2650. m_arrCaption[0].right, m_arrCaption[0].bottom);
  2651. }
  2652. if (m_fsState & MISTATE_HIDDEN) {
  2653. //LTRACE(_T("    hiddenn"));
  2654. return;
  2655. }
  2656. // draw frame controls
  2657. DrawControl();
  2658. }
  2659. //******************************************************************
  2660. //******************************************************************
  2661. void CMenuControl::DrawControl()
  2662. {
  2663. CWnd* pFrame = m_pMenuBar->GetTopLevelFrame();
  2664. ASSERT_VALID(pFrame);
  2665. CMDIFrameWnd* pMDIFrame = STATIC_DOWNCAST(CMDIFrameWnd, pFrame);
  2666. HWND hWndMDIClient = pMDIFrame->m_hWndMDIClient;
  2667. ASSERT(::IsWindow(hWndMDIClient));
  2668. BOOL bMaximized = FALSE;
  2669. HWND hWndChild = (HWND)::SendMessage(hWndMDIClient,
  2670. WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
  2671. if (bMaximized == TRUE) {
  2672. m_arrButton[2].MoveWindow(m_arrCaption[0]);
  2673. if (!(m_fsState & MISTATE_HORZ)) m_arrButton[0].SetSimpleButton();
  2674. else m_arrButton[2].SetSimpleButton(FALSE);
  2675. m_arrButton[1].MoveWindow(m_arrCaption[1]);
  2676. if (!(m_fsState & MISTATE_HORZ)) m_arrButton[1].SetSimpleButton();
  2677. else m_arrButton[1].SetSimpleButton(FALSE);
  2678. m_arrButton[0].MoveWindow(m_arrCaption[2]);
  2679. if (!(m_fsState & MISTATE_HORZ)) m_arrButton[2].SetSimpleButton();
  2680. else m_arrButton[0].SetSimpleButton(FALSE);
  2681. }
  2682. /* m_arrButton[2].SetColor(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2683. m_arrButton[1].SetColor(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2684. m_arrButton[0].SetColor(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2685. */
  2686. m_arrButton[2].Invalidate();
  2687. m_arrButton[1].Invalidate();
  2688. m_arrButton[0].Invalidate();
  2689. m_arrButton[2].UpdateWindow();
  2690. m_arrButton[1].UpdateWindow();
  2691. m_arrButton[0].UpdateWindow();
  2692. }
  2693. //******************************************************************
  2694. //******************************************************************
  2695. void CMenuControl::OnActivateChildWnd()
  2696. {
  2697. //LTRACE(_T("CMenuControl::OnActivateChildWndn"));
  2698. ASSERT_VALID(m_pMenuBar);
  2699. CWnd* pFrame = m_pMenuBar->GetTopLevelFrame();
  2700. ASSERT_VALID(pFrame);
  2701. CMDIFrameWnd* pMDIFrame = STATIC_DOWNCAST(CMDIFrameWnd, pFrame);
  2702. HWND hWndMDIClient = pMDIFrame->m_hWndMDIClient;
  2703. ASSERT(::IsWindow(hWndMDIClient));
  2704. BOOL bMaximized = FALSE;
  2705. HWND hWndChild = (HWND)::SendMessage(hWndMDIClient,
  2706. WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
  2707. if (bMaximized == FALSE) {
  2708. m_fsState |= MISTATE_HIDDEN;
  2709. }
  2710. else {
  2711. m_fsState &= ~MISTATE_HIDDEN;
  2712. }
  2713. }
  2714. //******************************************************************
  2715. CSize CMenuControl::GetCaptionSize()
  2716. {
  2717. NONCLIENTMETRICS info; info.cbSize = sizeof(info);
  2718. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
  2719. // due to my own feeling
  2720. return CSize(info.iMenuHeight - info.iBorderWidth*2, info.iMenuHeight - info.iBorderWidth*4);
  2721. }
  2722. //******************************************************************
  2723. #if _MFC_VER < 0x0600
  2724. void CMenuBar::SetBorders(int cxLeft, int cyTop, int cxRight, int cyBottom)
  2725. {
  2726. ASSERT(cxLeft >= 0);
  2727. ASSERT(cyTop >= 0);
  2728. ASSERT(cxRight >= 0);
  2729. ASSERT(cyBottom >= 0);
  2730. m_cxLeftBorder = cxLeft;
  2731. m_cyTopBorder = cyTop;
  2732. m_cxRightBorder = cxRight;
  2733. m_cyBottomBorder = cyBottom;
  2734. }
  2735. #endif
  2736. //******************************************************************
  2737. // input CRect should be client rectangle size
  2738. void CMenuBar::_CalcInsideRect(CRect& rect, BOOL bHorz) const
  2739. {
  2740. LTRACE(_T("CMenuBar::_CalcInsideRectn"));
  2741. ASSERT_VALID(this);
  2742. DWORD dwStyle = m_dwStyle;
  2743. if (dwStyle & CBRS_BORDER_LEFT)
  2744. rect.left += cxBorder2;
  2745. if (dwStyle & CBRS_BORDER_TOP)
  2746. rect.top += cyBorder2;
  2747. if (dwStyle & CBRS_BORDER_RIGHT) 
  2748. rect.right -= cxBorder2;
  2749. if (dwStyle & CBRS_BORDER_BOTTOM)
  2750. rect.bottom -= cyBorder2;
  2751. BOOL bDrawGripper = !(m_dwStyle & CBRS_FLOATING) && (m_dwExStyle & CBRS_GRIPPER);
  2752. // inset the top and bottom.
  2753. if (bHorz)
  2754. {
  2755. rect.left += m_cxLeftBorder;
  2756. rect.top += m_cyTopBorder;
  2757. rect.right -= m_cxRightBorder;
  2758. rect.bottom -= m_cyBottomBorder;
  2759. if (bDrawGripper)
  2760. rect.left += CX_GRIPPER_ALL;
  2761. }
  2762. else
  2763. {
  2764. rect.left += m_cyTopBorder;
  2765. rect.top += m_cxLeftBorder;
  2766. rect.right -= m_cyBottomBorder;
  2767. rect.bottom -= m_cxRightBorder;
  2768. if (bDrawGripper)
  2769. rect.top += CY_GRIPPER_ALL;
  2770. }
  2771. }
  2772. //******************************************************************
  2773. /////////////////////////////////////////////////////////////////////////////
  2774. // CMenuDockBar implementation
  2775. // a little changed from CDockBar implementation
  2776. static BOOL _IsMenuBar(int nPos, CPtrArray& arrBars)
  2777. {
  2778. if (nPos < arrBars.GetSize()) {
  2779. CControlBar* pBar = (CControlBar*)arrBars[nPos];
  2780. if (pBar && pBar->GetDlgCtrlID() == AFX_IDW_MENUBAR)
  2781. return TRUE;
  2782. else
  2783. return FALSE;
  2784. }
  2785. else
  2786. return FALSE;
  2787. }
  2788. //******************************************************************
  2789. // ERNESTO
  2790. BOOL CMenuBar::SetSubMenuText( int id, TCHAR *szText)
  2791. {
  2792. BOOL ret= FALSE;
  2793. if( id >= m_arrItem.GetSize() )
  2794. return FALSE;
  2795. CMenuButton *pMenu = (CMenuButton*)m_arrItem.GetAt(id);
  2796. if( pMenu)
  2797. {
  2798. pMenu->SetText(szText);
  2799. ret = TRUE;
  2800. }
  2801. else 
  2802. ret = FALSE;
  2803. return ret;
  2804. }
  2805. //******************************************************************
  2806. void CMenuBar::OnPaint()
  2807. {
  2808. CPaintDC pDC(this); // device context for painting
  2809. // TODO: Add your message handler code here
  2810. // Do not call CControlBar::OnPaint() for painting messages
  2811. CRect rect; GetClientRect(rect);
  2812. BOOL bFlota=m_dwStyle & CBRS_FLOATING;
  2813. // draw items
  2814. m_sizex=0;
  2815. CRect m_rect;
  2816. GetClientRect(m_rect);
  2817. CBrush cbr;
  2818. cbr.CreateSolidBrush(GuiDrawLayer::GetRGBColorFace(GuiDrawLayer::m_Style));
  2819. pDC.FillRect(m_rect,&cbr);
  2820. for (int i = 0; i < m_arrItem.GetSize(); ++i) {
  2821. m_arrItem[i]->Update(&pDC);
  2822. if (m_bChangeState)
  2823. m_arrItem[i]->UpdateButtons();
  2824. }
  2825. if (m_bChangeState)
  2826. m_bChangeState=FALSE;
  2827. // delay draw captions 
  2828. if (m_pMenuControl) {
  2829. if (IsFloating()) {
  2830. m_pMenuControl->DelayLayoutAndDraw(&pDC, rect.Size(),bFlota);
  2831. }
  2832. else {
  2833. if (m_dwStyle & CBRS_ORIENT_HORZ)
  2834. m_pMenuControl->DelayLayoutAndDraw(&pDC, CSize(GetClipBoxLength(TRUE), rect.Height()),bFlota);
  2835. else
  2836. m_pMenuControl->DelayLayoutAndDraw(&pDC, CSize(rect.Width(), GetClipBoxLength(FALSE)),bFlota);
  2837. }
  2838. }
  2839. }