XTPDockingPaneMiniWnd.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:26k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPDockingPaneMiniWnd.cpp : implementation of the CXTPDockingPaneMiniWnd class.
  2. //
  3. // This file is a part of the XTREME DOCKINGPANE MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPDrawHelpers.h"
  23. #include "Common/XTPToolTipContext.h"
  24. #include "Common/XTPResourceManager.h"
  25. #include "TabManager/XTPTabManager.h"
  26. #include "XTPDockingPaneMiniWnd.h"
  27. #include "XTPDockingPane.h"
  28. #include "XTPDockingPaneSplitterContainer.h"
  29. #include "XTPDockingPaneTabbedContainer.h"
  30. #include "XTPDockingPaneContext.h"
  31. #include "XTPDockingPaneManager.h"
  32. #include "XTPDockingPaneLayout.h"
  33. #include "XTPDockingPaneAutoHidePanel.h"
  34. #ifdef _DEBUG
  35. #define new DEBUG_NEW
  36. #undef THIS_FILE
  37. static char THIS_FILE[] = __FILE__;
  38. #endif
  39. BOOL CXTPDockingPaneMiniWnd::m_bShowPinButton = TRUE;
  40. #define TID_NCLEAVE 2345
  41. #define TID_CHECKACTIVE 1
  42. #define TID_SLIDEIN 2
  43. #define TID_SLIDEOUT 3
  44. #ifndef LWA_ALPHA
  45. #define LWA_ALPHA               0x00000002
  46. #endif
  47. #ifndef WS_EX_LAYERED
  48. #define WS_EX_LAYERED           0x00080000
  49. #endif
  50. IMPLEMENT_DYNAMIC(CXTPDockingPaneMiniWnd, CMiniFrameWnd)
  51. AFX_INLINE int ResetStepsCount()
  52. {
  53. if (CXTPDockingPaneAutoHideWnd::m_nAnimationInterval == 0)
  54. return 1;
  55. return max(1, CXTPDockingPaneAutoHideWnd::m_nAnimationDuration / CXTPDockingPaneAutoHideWnd::m_nAnimationInterval);
  56. }
  57. CXTPDockingPaneMiniWnd::CXTPDockingPaneMiniWnd(CXTPDockingPaneLayout* pLayout)
  58. : CXTPDockingPaneBase(xtpPaneTypeMiniWnd, pLayout)
  59. {
  60. m_pTopContainer = NULL;
  61. m_pCaptionButtons = new CXTPDockingPaneCaptionButtons();
  62. m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_CLOSE, this));
  63. m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_AUTOHIDE, this));
  64. m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_MENU, this));
  65. m_bSlideOut = m_bExpanded = m_bCollapsed = FALSE;
  66. m_nExpandedHeight = 0;
  67. m_nSlideStep = 0;
  68. m_nStepsCount = ResetStepsCount();
  69. m_bDelayInvalidate = FALSE;
  70. m_nDeactivationCount = 0;
  71. }
  72. void CXTPDockingPaneMiniWnd::Init(CXTPDockingPaneBase* pPane, CRect rc)
  73. {
  74. m_rcWindow = rc;
  75. CreateContainer();
  76. if (pPane->GetType() == xtpPaneTypeDockingPane)
  77. {
  78. CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)GetDockingPaneManager()->
  79. OnCreatePane(xtpPaneTypeTabbedContainer, m_pLayout);
  80. pContainer->Init((CXTPDockingPane*)pPane, this);
  81. pPane = pContainer;
  82. }
  83. m_pTopContainer = (CXTPDockingPaneSplitterContainer*)GetDockingPaneManager()->
  84. OnCreatePane(xtpPaneTypeSplitterContainer, m_pLayout);
  85. m_pTopContainer->Init(pPane, TRUE, this);
  86. m_pTopContainer->m_pParentContainer = this;
  87. m_bDelayInvalidate = TRUE;
  88. PostMessage(WM_IDLEUPDATECMDUI);
  89. DelayRecalcLayout();
  90. OnFocusChanged();
  91. }
  92. CXTPDockingPaneMiniWnd::~CXTPDockingPaneMiniWnd()
  93. {
  94. DestroyWindow();
  95. }
  96. void CXTPDockingPaneMiniWnd::Copy(CXTPDockingPaneBase* pCloneBase, CXTPPaneToPaneMap* pMap, DWORD /*dwIgnoredOptions*/)
  97. {
  98. CXTPDockingPaneMiniWnd* pClone = (CXTPDockingPaneMiniWnd*)pCloneBase;
  99. ASSERT(pMap);
  100. m_pTopContainer = (CXTPDockingPaneSplitterContainer*)pClone->m_pTopContainer->Clone(m_pLayout, pMap);
  101. m_pTopContainer->m_pParentContainer = this;
  102. m_pTopContainer->m_pDockingSite = this;
  103. m_rcWindow = pClone->m_rcWindow;
  104. if (pClone->m_hWnd) ::GetWindowRect(pClone->m_hWnd, &m_rcWindow);
  105. m_bCollapsed = ((CXTPDockingPaneMiniWnd*)pClone)->m_bCollapsed;
  106. m_nExpandedHeight = ((CXTPDockingPaneMiniWnd*)pClone)->m_nExpandedHeight;
  107. if (m_bCollapsed)
  108. {
  109. m_rcWindow.bottom = m_rcWindow.top + GetPaintManager()->GetCaptionHeight() + 8;
  110. }
  111. if (!m_pLayout->IsUserLayout())
  112. {
  113. CreateContainer();
  114. m_pTopContainer->OnParentContainerChanged(m_pTopContainer);
  115. OnChildContainerChanged(m_pTopContainer);
  116. }
  117. }
  118. void CXTPDockingPaneMiniWnd::RemovePane(CXTPDockingPaneBase* pPane)
  119. {
  120. ASSERT(pPane == m_pTopContainer);
  121. pPane->m_pParentContainer = NULL;
  122. m_pTopContainer = NULL;
  123. if (m_hWnd) ShowWindow(SW_HIDE);
  124. if (m_bCollapsed)
  125. OnPinButtonClick();
  126. }
  127. void CXTPDockingPaneMiniWnd::InvalidatePane(BOOL /*bSelectionChanged*/)
  128. {
  129. if (!m_pTopContainer)
  130. return;
  131. if (!m_hWnd)
  132. return;
  133. CXTPDockingPaneBaseList lstTabbed;
  134. FindPane(xtpPaneTypeTabbedContainer, &lstTabbed);
  135. int nCount = (int)lstTabbed.GetCount();
  136. POSITION pos = lstTabbed.GetHeadPosition();
  137. while (pos)
  138. {
  139. CXTPDockingPaneBase* pPane = lstTabbed.GetNext(pos);
  140. ASSERT(pPane->GetType() == xtpPaneTypeTabbedContainer);
  141. ((CXTPDockingPaneTabbedContainer*)pPane)->ShowTitle(nCount != 1);
  142. }
  143. CString strTitle = (nCount != 1) ? GetDockingPaneManager()->m_strFloatingFrameCaption : ((CXTPDockingPaneTabbedContainer*)lstTabbed.GetHead())->GetTitle();
  144. SetWindowText(strTitle);
  145. if (nCount > 0)
  146. {
  147. BOOL bEnabled = FALSE;
  148. CXTPDockingPaneBaseList lstChilds;
  149. FindPane(xtpPaneTypeDockingPane, &lstChilds);
  150. pos = lstChilds.GetHeadPosition();
  151. while (pos)
  152. {
  153. CXTPDockingPaneBase* pPane = lstChilds.GetNext(pos);
  154. if ((((CXTPDockingPane*)pPane)->GetOptions() & xtpPaneNoCloseable) == 0)
  155. bEnabled = TRUE;
  156. }
  157. if (!bEnabled || !m_bCloseEnabled)
  158. {
  159. CMenu* pSysMenu = GetSystemMenu(FALSE);
  160. pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | (bEnabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED));
  161. m_bCloseEnabled = bEnabled;
  162. }
  163. if ((GetStyle() & WS_CHILD) == 0)
  164. UpdatePosition();
  165. if ((GetStyle() & WS_VISIBLE) == 0)
  166. ShowWindow(SW_SHOWNOACTIVATE);
  167. }
  168. SendMessage(WM_NCPAINT);
  169. OnFocusChanged();
  170. }
  171. void CXTPDockingPaneMiniWnd::UpdatePosition()
  172. {
  173. CXTPWindowRect rc(this);
  174. CSize sz = rc.Size();
  175. if (IsThemed())
  176. {
  177. MINMAXINFO mmi;
  178. ZeroMemory(&mmi, sizeof(mmi));
  179. mmi.ptMaxTrackSize.x = 32000;
  180. mmi.ptMaxTrackSize.y = 32000;
  181. GetMinMaxInfo(&mmi);
  182. sz.cx = max(min(sz.cx, mmi.ptMaxTrackSize.x), mmi.ptMinTrackSize.x);
  183. sz.cy = max(min(sz.cy, mmi.ptMaxTrackSize.y), mmi.ptMinTrackSize.y);
  184. }
  185. MoveWindow(rc.left, rc.top, sz.cx, sz.cy);
  186. }
  187. void CXTPDockingPaneMiniWnd::CreateContainer()
  188. {
  189. if (!m_hWnd)
  190. {
  191. Create(m_rcWindow);
  192. }
  193. }
  194. void CXTPDockingPaneMiniWnd::OnChildContainerChanged(CXTPDockingPaneBase* /*pContainer*/)
  195. {
  196. if (!m_hWnd)
  197. return;
  198. if (m_pTopContainer == NULL || m_pTopContainer->IsEmpty())
  199. {
  200. DestroyWindow();
  201. }
  202. else
  203. {
  204. m_bDelayInvalidate = TRUE;
  205. PostMessage(WM_IDLEUPDATECMDUI);
  206. }
  207. }
  208. void CXTPDockingPaneMiniWnd::RecalcLayout(BOOL /*bNotify*/)
  209. {
  210. if (m_pTopContainer == NULL)
  211. return;
  212. if (m_bInRecalcLayout)
  213. return;
  214. m_bInRecalcLayout = TRUE;
  215. m_nIdleFlags &= ~(idleLayout | idleNotify);
  216. if (m_pTopContainer->IsEmpty())
  217. {
  218. ShowWindow(SW_HIDE);
  219. if (m_bCollapsed)
  220. OnPinButtonClick();
  221. }
  222. else
  223. {
  224. //ShowWindow(SW_SHOW);
  225. AFX_SIZEPARENTPARAMS layout;
  226. layout.bStretch = TRUE;
  227. GetClientRect(&layout.rect);
  228. layout.hDWP = ::BeginDeferWindowPos(8); // reasonable guess
  229. m_pTopContainer->OnSizeParent(this, layout.rect, &layout);
  230. if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP))
  231. TRACE0("Warning: DeferWindowPos failed - low system resources.n");
  232. CWnd::GetWindowRect(&m_pTopContainer->m_rcWindow);
  233. ScreenToClient(&m_pTopContainer->m_rcWindow);
  234. }
  235. GetDockingPaneManager()->SyncPanesState();
  236. m_bInRecalcLayout = FALSE;
  237. }
  238. BOOL CXTPDockingPaneMiniWnd::Create(CRect rc)
  239. {
  240. DWORD dwStyle = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_BORDER |
  241. MFS_BLOCKSYSMENU | WS_THICKFRAME | (GetDockingPaneManager()->m_bSyncActiveFloatingFrames ? MFS_SYNCACTIVE : 0);
  242. DWORD dwExStyle = 0;
  243. if (GetDockingPaneManager()->IsLayoutRTL())
  244. {
  245. dwExStyle = WS_EX_LAYOUTRTL;
  246. }
  247. CXTPDockingPaneContext::EnsureVisible(rc);
  248. if (!CMiniFrameWnd::CreateEx(dwExStyle,
  249. _T("XTPDockingPaneMiniWnd"), _T(""), dwStyle, rc, GetDockingPaneManager()->GetSite()))
  250. {
  251. return FALSE;
  252. }
  253. CMenu* pSysMenu = GetSystemMenu(FALSE);
  254. pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
  255. pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
  256. pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
  257. CString strHide;
  258. if (strHide.LoadString(AFX_IDS_HIDE))
  259. {
  260. pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
  261. pSysMenu->AppendMenu(MF_STRING | MF_ENABLED, SC_CLOSE, strHide);
  262. }
  263. m_bCloseEnabled = TRUE;
  264. if (IsThemed())
  265. {
  266. ModifyStyle(WS_BORDER | WS_THICKFRAME, 0, SWP_FRAMECHANGED);
  267. }
  268. SetWindowPos(0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  269. UpdateWindowOpacity();
  270. return TRUE;
  271. }
  272. BEGIN_MESSAGE_MAP(CXTPDockingPaneMiniWnd, CMiniFrameWnd)
  273. ON_WM_CLOSE()
  274. ON_WM_NCLBUTTONDOWN()
  275. ON_WM_NCRBUTTONUP()
  276. ON_WM_NCLBUTTONDBLCLK()
  277. ON_WM_DESTROY()
  278. ON_WM_CONTEXTMENU()
  279. ON_WM_NCHITTEST_EX()
  280. ON_WM_NCPAINT()
  281. ON_WM_NCCALCSIZE()
  282. ON_WM_NCMOUSEMOVE()
  283. ON_WM_TIMER()
  284. ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
  285. ON_WM_GETMINMAXINFO()
  286. ON_WM_SETFOCUS()
  287. ON_WM_NCACTIVATE()
  288. ON_WM_SIZING()
  289. END_MESSAGE_MAP()
  290. void CXTPDockingPaneMiniWnd::OnSizing(UINT nSide, LPRECT lpRect)
  291. {
  292. CMiniFrameWnd::OnSizing(nSide, lpRect);
  293. GetDockingPaneManager()->GetDockingContext()->OnSizingFloatingFrame(this, nSide, lpRect);
  294. }
  295. void CXTPDockingPaneMiniWnd::UpdateWindowOpacity()
  296. {
  297. if (!GetSafeHwnd())
  298. return;
  299. CXTPDockingPaneManager::PFNSETLAYEREDWINDOWATTRIBUTES pfnSetLayeredWindowAttributes =
  300. GetDockingPaneManager()->m_pfnSetLayeredWindowAttributes;
  301. if (!pfnSetLayeredWindowAttributes)
  302. return;
  303. int nFloatingFramesOpacity = GetDockingPaneManager()->m_nFloatingFramesOpacity;
  304. if (nFloatingFramesOpacity == 255)
  305. {
  306. ModifyStyleEx(WS_EX_LAYERED, 0);
  307. return;
  308. }
  309. if (!m_bActive)
  310. {
  311. ModifyStyleEx(0, WS_EX_LAYERED);
  312. pfnSetLayeredWindowAttributes(m_hWnd, 0x00, (BYTE)nFloatingFramesOpacity, LWA_ALPHA);
  313. }
  314. else
  315. {
  316. pfnSetLayeredWindowAttributes(m_hWnd, 0x00, (BYTE)255, LWA_ALPHA);
  317. }
  318. }
  319. void CXTPDockingPaneMiniWnd::OnFocusChanged()
  320. {
  321. if (GetSafeHwnd())
  322. {
  323. CWnd* pFocus = GetFocus();
  324. BOOL bActive = (pFocus->GetSafeHwnd() && (pFocus == this || IsChild(pFocus) ||
  325. (pFocus->GetOwner()->GetSafeHwnd() && IsChild(pFocus->GetOwner()))));
  326. if (bActive != m_bActive)
  327. {
  328. m_bActive = bActive;
  329. if (IsThemed())
  330. {
  331. SendMessage(WM_NCPAINT);
  332. }
  333. UpdateWindowOpacity();
  334. }
  335. }
  336. }
  337. void CXTPDockingPaneMiniWnd::OnIdleUpdateCmdUI()
  338. {
  339. if (!GetSafeHwnd())
  340. return;
  341. if (m_bDelayInvalidate)
  342. {
  343. m_bDelayInvalidate = FALSE;
  344. InvalidatePane(FALSE);
  345. }
  346. CMiniFrameWnd::OnIdleUpdateCmdUI();
  347. }
  348. void CXTPDockingPaneMiniWnd::OnClose()
  349. {
  350. if (m_pTopContainer)
  351. {
  352. CXTPDockingPaneManager* pManager = GetDockingPaneManager();
  353. CXTPDockingPaneBaseList lst;
  354. FindPane(xtpPaneTypeDockingPane, &lst);
  355. POSITION pos = lst.GetHeadPosition();
  356. while (pos)
  357. {
  358. CXTPDockingPane* pPane = (CXTPDockingPane*)lst.GetNext(pos);
  359. if ((pPane->GetOptions() & xtpPaneNoCloseable) != 0)
  360. continue;
  361. pPane->InternalAddRef();
  362. if (!pManager->NotifyAction(xtpPaneActionClosing, pPane))
  363. {
  364. pPane->Close();
  365. pManager->NotifyAction(xtpPaneActionClosed, pPane);
  366. }
  367. pPane->InternalRelease();
  368. }
  369. }
  370. }
  371. void CXTPDockingPaneMiniWnd::OnSetFocus(CWnd* pOldWnd)
  372. {
  373. CMiniFrameWnd::OnSetFocus(pOldWnd);
  374. if (m_pTopContainer == 0)
  375. return;
  376. if (!m_pLayout || !m_pLayout->IsValid())
  377. return;
  378. CXTPDockingPaneBaseList lst;
  379. FindPane(xtpPaneTypeTabbedContainer, &lst);
  380. if (lst.GetCount() == 1)
  381. {
  382. CXTPDockingPane* pPane =
  383. ((CXTPDockingPaneTabbedContainer*)lst.GetHead())->GetSelected();
  384. if (pPane)
  385. {
  386. pPane->SetFocus();
  387. }
  388. }
  389. GetDockingPaneManager()->UpdatePanes();
  390. }
  391. void CXTPDockingPaneMiniWnd::PostNcDestroy()
  392. {
  393. // prevent auto deleting
  394. }
  395. void CXTPDockingPaneMiniWnd::FindPane(XTPDockingPaneType type, CXTPDockingPaneBaseList* pList) const
  396. {
  397. if (GetType() == type)
  398. {
  399. pList->AddTail((CXTPDockingPaneBase*)this);
  400. }
  401. else if (m_pTopContainer)
  402. {
  403. m_pTopContainer->FindPane(type, pList);
  404. }
  405. }
  406. void CXTPDockingPaneMiniWnd::OnContextMenu(CWnd* pWnd, CPoint point)
  407. {
  408. CXTPDockingPaneBaseList lst;
  409. FindPane(xtpPaneTypeTabbedContainer, &lst);
  410. CXTPDockingPane* pSelectedPane = 0;
  411. if (lst.GetCount() == 1)
  412. {
  413. pSelectedPane = ((CXTPDockingPaneTabbedContainer*)lst.GetHead())->GetSelected();
  414. }
  415. else
  416. {
  417. POSITION pos = lst.GetHeadPosition();
  418. while (pos)
  419. {
  420. CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)lst.GetNext(pos);
  421. if (pContainer->IsActive())
  422. {
  423. pSelectedPane = pContainer->GetSelected();
  424. break;
  425. }
  426. }
  427. }
  428. if (pSelectedPane) pSelectedPane->SetFocus();
  429. XTP_DOCKINGPANE_CLICK menu;
  430. menu.pPane = pSelectedPane;
  431. menu.pt = point;
  432. menu.rcExclude.SetRectEmpty();
  433. menu.pContainer = this;
  434. if (GetDockingPaneManager()->NotifyOwner(XTP_DPN_CONTEXTMENU, (LPARAM)&menu))
  435. return;
  436. CMiniFrameWnd::OnContextMenu(pWnd, point);
  437. }
  438. void CXTPDockingPaneMiniWnd::OnNcRButtonUp(UINT nHitTest, CPoint point)
  439. {
  440. if (IsThemed() && (nHitTest == HTCAPTION))
  441. {
  442. OnContextMenu(this, point);
  443. return;
  444. }
  445. CMiniFrameWnd::OnNcRButtonUp(nHitTest, point);
  446. }
  447. void CXTPDockingPaneMiniWnd::OnNcLButtonDblClk(UINT nHitTest, CPoint /*point*/)
  448. {
  449. if (nHitTest == HTCAPTION)
  450. {
  451. if (m_bCollapsed)
  452. OnPinButtonClick();
  453. else
  454. GetDockingPaneManager()->ToggleDocking(m_pTopContainer);
  455. }
  456. }
  457. void CXTPDockingPaneMiniWnd::OnDestroy()
  458. {
  459. ::GetWindowRect(m_hWnd, &m_rcWindow);
  460. CWnd::OnDestroy();
  461. }
  462. BOOL CXTPDockingPaneMiniWnd::IsThemed() const
  463. {
  464. return GetDockingPaneManager()->IsThemedFloatingFrames();
  465. }
  466. //////////////////////////////////////////////////////////////////////////
  467. // Themed methods.
  468. LRESULT CXTPDockingPaneMiniWnd::OnNcHitTest(CPoint point)
  469. {
  470. LRESULT nHitTest = (LRESULT)CMiniFrameWnd::OnNcHitTest(point);
  471. if (!IsThemed())
  472. return nHitTest;
  473. CXTPWindowRect rcWindow(this);
  474. CRect rcBorders = rcWindow;
  475. rcBorders.DeflateRect(3, 3);
  476. if (rcWindow.PtInRect(point) && !rcBorders.PtInRect(point))
  477. {
  478. int ht = 0;
  479. if (point.y < rcBorders.top)
  480. ht = (HTTOP - HTSIZEFIRST + 1);
  481. else if (point.y >= rcBorders.bottom)
  482. ht = (HTBOTTOM - HTSIZEFIRST + 1);
  483. if (point.x < rcBorders.left)
  484. ht += (HTLEFT - HTSIZEFIRST + 1);
  485. else if (point.x >= rcBorders.right)
  486. ht += (HTRIGHT - HTSIZEFIRST + 1);
  487. return (LRESULT)(ht + HTSIZEFIRST - 1);
  488. }
  489. if (nHitTest == HTNOWHERE)
  490. {
  491. int nPoint = point.y - rcWindow.top;
  492. if (nPoint < GetPaintManager()->GetCaptionHeight() + 4)
  493. return HTCAPTION;
  494. }
  495. return nHitTest;
  496. }
  497. void CXTPDockingPaneMiniWnd::RedrawPane()
  498. {
  499. if (!IsThemed())
  500. return;
  501. if (GetSafeHwnd())
  502. ::InvalidateRect(GetSafeHwnd(), 0, FALSE);
  503. SendMessage(WM_NCPAINT);
  504. }
  505. void CXTPDockingPaneMiniWnd::OnNcPaint()
  506. {
  507. if (IsThemed())
  508. {
  509. CXTPWindowRect rc(this);
  510. rc.OffsetRect(-rc.TopLeft());
  511. CWindowDC dc(this);
  512. CXTPDockingPanePaintManager* pPaintManager = GetPaintManager();
  513. pPaintManager->DrawFloatingFrame(&dc, this, rc);
  514. }
  515. else
  516. {
  517. Default();
  518. }
  519. }
  520. BOOL CXTPDockingPaneMiniWnd::OnNcActivate(BOOL bActive)
  521. {
  522. if (IsThemed())
  523. {
  524. return TRUE;
  525. }
  526. return CMiniFrameWnd::OnNcActivate(bActive);
  527. }
  528. void CXTPDockingPaneMiniWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
  529. {
  530. if (IsThemed())
  531. {
  532. int nSize = 3;
  533. lpncsp->rgrc[0].left += nSize;
  534. lpncsp->rgrc[0].top += nSize;
  535. lpncsp->rgrc[0].right -= nSize;
  536. lpncsp->rgrc[0].bottom -= nSize;
  537. int nTitleFont = GetPaintManager()->GetCaptionHeight();
  538. lpncsp->rgrc[0].top += nTitleFont + 2;
  539. return;
  540. }
  541. CMiniFrameWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
  542. }
  543. void CXTPDockingPaneMiniWnd::OnNcMouseMove(UINT nHitTest, CPoint point)
  544. {
  545. CMiniFrameWnd::OnNcMouseMove(nHitTest, point);
  546. if (IsThemed())
  547. {
  548. CXTPDrawHelpers::ScreenToWindow(this, &point);
  549. if (m_pCaptionButtons->CheckForMouseOver(point))
  550. {
  551. SetTimer (TID_NCLEAVE, 100, NULL);
  552. }
  553. Expand();
  554. }
  555. }
  556. void CXTPDockingPaneMiniWnd::Collapse(BOOL bDelay)
  557. {
  558. m_nSlideStep = m_nStepsCount = ResetStepsCount();
  559. CWnd::GetWindowRect(&m_rcWindow);
  560. m_nExpandedHeight = m_rcWindow.Height();
  561. m_bCollapsed = TRUE;
  562. m_bExpanded = TRUE;
  563. if (!bDelay)
  564. {
  565. if (!OnAction(xtpPaneActionCollapsing))
  566. {
  567. m_nSlideStep = 0;
  568. DoSlideStep(FALSE);
  569. KillTimer(TID_SLIDEOUT);
  570. KillTimer(TID_CHECKACTIVE);
  571. OnAction(xtpPaneActionCollapsed);
  572. return;
  573. }
  574. }
  575. if (m_bSlideOut)
  576. {
  577. m_bSlideOut = FALSE;
  578. KillTimer(TID_SLIDEOUT);
  579. OnAction(xtpPaneActionCollapsed);
  580. }
  581. m_nDeactivationCount = 6;
  582. SetTimer(TID_CHECKACTIVE, 100, NULL);
  583. }
  584. void CXTPDockingPaneMiniWnd::OnCaptionButtonClick(CXTPDockingPaneCaptionButton* pButton)
  585. {
  586. if (pButton->GetID() == XTP_IDS_DOCKINGPANE_CLOSE)
  587. {
  588. OnClose();
  589. return;
  590. }
  591. if (pButton->GetID() == XTP_IDS_DOCKINGPANE_AUTOHIDE)
  592. {
  593. OnPinButtonClick();
  594. return;
  595. }
  596. if (pButton->GetID() == XTP_IDS_DOCKINGPANE_MENU)
  597. {
  598. }
  599. }
  600. BOOL CXTPDockingPaneMiniWnd::OnCaptionButtonDown(CXTPDockingPaneCaptionButton* pButton)
  601. {
  602. switch (pButton->GetID())
  603. {
  604. case XTP_IDS_DOCKINGPANE_MENU:
  605. CXTPDockingPane* pSelectedPane = GetSelectedPane();
  606. if (pSelectedPane)
  607. {
  608. m_bActive = TRUE;
  609. CXTPDockingPaneManager* pManager = GetDockingPaneManager();
  610. XTP_DOCKINGPANE_CLICK menu;
  611. menu.pContainer = this;
  612. menu.rcExclude = pButton->GetRect();
  613. CXTPWindowRect rcWindow(this);
  614. if (GetExStyle() & WS_EX_LAYOUTRTL)
  615. {
  616. menu.rcExclude.OffsetRect(-menu.rcExclude.left + rcWindow.right - menu.rcExclude.right, rcWindow.top);
  617. menu.pt = CPoint(menu.rcExclude.right, menu.rcExclude.bottom);
  618. }
  619. else
  620. {
  621. menu.rcExclude.OffsetRect(rcWindow.left, rcWindow.top);
  622. menu.pt = CPoint(menu.rcExclude.left, menu.rcExclude.bottom);
  623. }
  624. menu.pPane = pSelectedPane;
  625. pButton->m_bPressed = TRUE;
  626. SendMessage(WM_NCPAINT);
  627. pManager->NotifyOwner(XTP_DPN_CONTEXTMENU, (LPARAM)&menu);
  628. pButton->m_bPressed = FALSE;
  629. if (m_hWnd) SendMessage(WM_NCPAINT);
  630. }
  631. return TRUE;
  632. }
  633. return FALSE;
  634. }
  635. BOOL CXTPDockingPaneMiniWnd::OnAction(XTPDockingPaneAction action)
  636. {
  637. if (m_pTopContainer)
  638. {
  639. return m_pTopContainer->OnAction(action);
  640. }
  641. return FALSE;
  642. }
  643. void CXTPDockingPaneMiniWnd::OnPinButtonClick()
  644. {
  645. if (!m_hWnd)
  646. return;
  647. BOOL bPinning = m_bCollapsed;
  648. if (OnAction(bPinning ? xtpPaneActionPinning : xtpPaneActionUnpinning))
  649. return;
  650. if (!m_bCollapsed)
  651. {
  652. Collapse(TRUE);
  653. }
  654. else
  655. {
  656. if (m_nStepsCount != m_nSlideStep)
  657. {
  658. CXTPWindowRect rcWindow(this);
  659. SetWindowPos(0, 0, 0, rcWindow.Width(), m_nExpandedHeight, SWP_NOZORDER | SWP_NOMOVE);
  660. }
  661. m_bCollapsed = FALSE;
  662. m_bExpanded = FALSE;
  663. KillTimer(TID_CHECKACTIVE);
  664. KillTimer(TID_SLIDEOUT);
  665. }
  666. SendMessage(WM_NCPAINT);
  667. OnAction(bPinning ? xtpPaneActionPinned : xtpPaneActionUnpinned);
  668. }
  669. void CXTPDockingPaneMiniWnd::DoSlideStep(BOOL bActivate)
  670. {
  671. int nMinHeight = GetPaintManager()->GetCaptionHeight() + 8;
  672. CXTPWindowRect rc(this);
  673. rc.bottom = rc.top + max(nMinHeight, m_nSlideStep * m_nExpandedHeight / m_nStepsCount);
  674. SetWindowPos(&CWnd::wndTop, rc.left, rc.top, rc.Width(), rc.Height(), (!bActivate ? SWP_NOZORDER | SWP_NOACTIVATE : SWP_NOACTIVATE));
  675. Invalidate(FALSE);
  676. }
  677. CXTPDockingPane* CXTPDockingPaneMiniWnd::GetSelectedPane() const
  678. {
  679. if (!m_pTopContainer)
  680. return 0;
  681. CXTPDockingPaneBaseList lst;
  682. FindPane(xtpPaneTypeTabbedContainer, &lst);
  683. int nCount = (int)lst.GetCount();
  684. if (nCount != 1)
  685. return 0;
  686. return ((CXTPDockingPaneTabbedContainer*)lst.GetHead())->GetSelected();
  687. }
  688. BOOL CXTPDockingPaneMiniWnd::IsCaptionButtonVisible(CXTPDockingPaneCaptionButton* pButton)
  689. {
  690. if (pButton->GetID() == XTP_IDS_DOCKINGPANE_CLOSE)
  691. return m_bCloseEnabled;
  692. if (pButton->GetID() == XTP_IDS_DOCKINGPANE_AUTOHIDE)
  693. {
  694. pButton->SetState(m_bCollapsed ? xtpPanePinPushed : 0);
  695. return m_bShowPinButton;
  696. }
  697. if (pButton->GetID() == XTP_IDS_DOCKINGPANE_MENU)
  698. {
  699. CXTPDockingPane* pSelectedPane = GetSelectedPane();
  700. return pSelectedPane && (pSelectedPane->GetOptions() & xtpPaneHasMenuButton);
  701. }
  702. return TRUE;
  703. }
  704. void CXTPDockingPaneMiniWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
  705. {
  706. if (IsThemed())
  707. {
  708. CPoint ptClick(point);
  709. CXTPDrawHelpers::ScreenToWindow(this, &ptClick);
  710. for (int i = 0; i < m_pCaptionButtons->GetSize(); i++)
  711. {
  712. CXTPDockingPaneCaptionButton* pButton = m_pCaptionButtons->GetAt(i);
  713. if (pButton->PtInRect(ptClick))
  714. {
  715. if (!pButton->IsEnabled())
  716. return;
  717. if (OnCaptionButtonDown(pButton))
  718. return;
  719. if (pButton->Click(this, ptClick, FALSE))
  720. {
  721. OnCaptionButtonClick(pButton);
  722. }
  723. return;
  724. }
  725. }
  726. }
  727. if (nHitTest == HTCAPTION)
  728. {
  729. // special activation for floating toolbars
  730. ActivateTopParent();
  731. BringWindowToTop();
  732. CXTPDockingPaneContext* pContext = GetDockingPaneManager()->GetDockingContext();
  733. pContext->Drag(m_pTopContainer, point);
  734. return;
  735. }
  736. CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
  737. }
  738. void CXTPDockingPaneMiniWnd::OnTimer(UINT_PTR nIDEvent)
  739. {
  740. if (nIDEvent == TID_NCLEAVE)
  741. {
  742. CPoint pt;
  743. ::GetCursorPos (&pt);
  744. CXTPWindowRect rcCaption(this);
  745. rcCaption.bottom = rcCaption.top + GetPaintManager()->GetCaptionHeight() + 4;
  746. if (!rcCaption.PtInRect(pt))
  747. {
  748. m_pCaptionButtons->CheckForMouseOver(CPoint(-1, -1));
  749. KillTimer(TID_NCLEAVE);
  750. }
  751. }
  752. if (nIDEvent == TID_SLIDEOUT && m_bSlideOut)
  753. {
  754. m_nSlideStep--;
  755. if (m_nSlideStep > -1)
  756. DoSlideStep();
  757. else
  758. {
  759. m_bSlideOut = FALSE;
  760. m_bExpanded = FALSE;
  761. KillTimer(TID_SLIDEOUT);
  762. OnAction(xtpPaneActionCollapsed);
  763. }
  764. }
  765. if (nIDEvent == TID_CHECKACTIVE)
  766. {
  767. CPoint pt;
  768. GetCursorPos(&pt);
  769. CWnd* pFocus = GetFocus();
  770. BOOL bActive = (pFocus->GetSafeHwnd() && (pFocus == this || IsChild(pFocus)));
  771. if (!bActive && !m_bSlideOut && !CXTPWindowRect(this).PtInRect(pt) && ::GetCapture() == NULL)
  772. {
  773. if (--m_nDeactivationCount <= 0)
  774. {
  775. if (OnAction(xtpPaneActionCollapsing))
  776. {
  777. m_nDeactivationCount = 6;
  778. return;
  779. }
  780. if (m_nSlideStep == m_nStepsCount)
  781. {
  782. m_nExpandedHeight = CXTPWindowRect(this).Height();
  783. }
  784. m_bSlideOut = TRUE;
  785. SetTimer(TID_SLIDEOUT, CXTPDockingPaneAutoHideWnd::m_nAnimationInterval, NULL);
  786. KillTimer(TID_CHECKACTIVE);
  787. }
  788. }
  789. }
  790. CMiniFrameWnd::OnTimer(nIDEvent);
  791. }
  792. void CXTPDockingPaneMiniWnd::OnThemedChanged()
  793. {
  794. if (!m_hWnd)
  795. return;
  796. ModifyStyle(IsThemed() ? WS_BORDER | WS_THICKFRAME: 0, IsThemed() ? 0 : WS_BORDER | WS_THICKFRAME, SWP_FRAMECHANGED);
  797. if (!IsThemed() && m_bCollapsed)
  798. {
  799. OnPinButtonClick();
  800. }
  801. SetWindowPos(0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
  802. if (m_bCollapsed && IsThemed())
  803. {
  804. DoSlideStep();
  805. }
  806. }
  807. void CXTPDockingPaneMiniWnd::Expand()
  808. {
  809. if (m_bCollapsed && m_nSlideStep <= 0)
  810. {
  811. if (m_bSlideOut)
  812. {
  813. m_bSlideOut = FALSE;
  814. m_bExpanded = FALSE;
  815. KillTimer(TID_SLIDEOUT);
  816. OnAction(xtpPaneActionCollapsed);
  817. }
  818. if (OnAction(xtpPaneActionExpanding))
  819. return;
  820. m_bExpanded = TRUE;
  821. m_nSlideStep = m_nStepsCount = ResetStepsCount();
  822. DoSlideStep(TRUE);
  823. m_nDeactivationCount = 8;
  824. SetTimer(TID_CHECKACTIVE, 100, NULL);
  825. OnAction(xtpPaneActionExpanded);
  826. }
  827. }
  828. void CXTPDockingPaneMiniWnd::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
  829. {
  830. CMiniFrameWnd::OnGetMinMaxInfo(lpMMI);
  831. GetMinMaxInfo(lpMMI);
  832. }
  833. void CXTPDockingPaneMiniWnd::GetMinMaxInfo(LPMINMAXINFO lpMMI) const
  834. {
  835. if (m_pTopContainer && ((!m_bCollapsed || m_bExpanded) && !m_bSlideOut))
  836. {
  837. CXTPWindowRect rcWindow(this);
  838. CXTPClientRect rcClient(this);
  839. CSize szBorder = rcWindow.Size() - rcClient.Size();
  840. MINMAXINFO mInfo;
  841. m_pTopContainer->GetMinMaxInfo(&mInfo);
  842. lpMMI->ptMinTrackSize.x = max(lpMMI->ptMinTrackSize.x, mInfo.ptMinTrackSize.x + szBorder.cx);
  843. lpMMI->ptMinTrackSize.y = max(lpMMI->ptMinTrackSize.y, mInfo.ptMinTrackSize.y + szBorder.cy);
  844. lpMMI->ptMaxTrackSize.x = min(lpMMI->ptMaxTrackSize.x, mInfo.ptMaxTrackSize.x + szBorder.cx);
  845. lpMMI->ptMaxTrackSize.y = min(lpMMI->ptMaxTrackSize.y, mInfo.ptMaxTrackSize.y + szBorder.cy);
  846. }
  847. }
  848. BOOL CXTPDockingPaneMiniWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  849. {
  850. CXTPDockingPaneManager* pManager = GetDockingPaneManager();
  851. if (pManager)
  852. {
  853. pManager->GetToolTipContext()->FilterToolTipMessage(this, message, wParam, lParam);
  854. }
  855. return CWnd::OnWndMsg(message, wParam, lParam, pResult);
  856. }
  857. INT_PTR CXTPDockingPaneMiniWnd::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  858. {
  859. ASSERT_VALID(this);
  860. ASSERT(::IsWindow(m_hWnd));
  861. if (!IsThemed())
  862. return -1;
  863. CXTPWindowRect rcWindow(this);
  864. CPoint ptTopLeft(rcWindow.TopLeft());
  865. ScreenToClient(&ptTopLeft);
  866. if (GetExStyle() & WS_EX_LAYOUTRTL)
  867. ptTopLeft.x -= rcWindow.Width();
  868. for (int i = 0; i < m_pCaptionButtons->GetSize(); i++)
  869. {
  870. CXTPDockingPaneCaptionButton* pButton = m_pCaptionButtons->GetAt(i);
  871. CRect rc = pButton->GetRect();
  872. rc.OffsetRect(ptTopLeft);
  873. if (rc.PtInRect(point))
  874. {
  875. INT_PTR nHit = (INT_PTR)pButton->GetID();
  876. CString strTip;
  877. XTPResourceManager()->LoadString(&strTip, (UINT)nHit);
  878. if (strTip.GetLength() == 0)
  879. return -1;
  880. CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, rc, nHit, strTip);
  881. return nHit;
  882. }
  883. }
  884. return -1;
  885. }
  886. void CXTPDockingPaneMiniWnd::DeletePane()
  887. {
  888. InternalRelease();
  889. }
  890. void CXTPDockingPaneMiniWnd::OnFinalRelease()
  891. {
  892. if (m_hWnd != NULL)
  893. DestroyWindow();
  894. CCmdTarget::OnFinalRelease();
  895. }