MenuBar.cpp
上传用户:zhanglf88
上传日期:2013-11-19
资源大小:6036k
文件大小:82k
源码类别:

金融证券系统

开发平台:

Visual C++

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