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

对话框与窗口

开发平台:

Visual C++

  1. // XTPTabClientWnd.cpp : implementation of the CXTPTabClientWnd class.
  2. //
  3. // This file is a part of the XTREME COMMANDBARS 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/XTPResourceManager.h"
  23. #include "Common/XTPImageManager.h"
  24. #include "Common/XTPDrawHelpers.h"
  25. #include "Common/XTPToolTipContext.h"
  26. #include "Common/Resource.h"
  27. #include "TabManager/XTPTabManager.h"
  28. #include "XTPCommandBarsDefines.h"
  29. #include "XTPTabClientWnd.h"
  30. #include "XTPMouseManager.h"
  31. #include "XTPPaintManager.h"
  32. #include "XTPPopupBar.h"
  33. #include "XTPToolBar.h"
  34. #include "XTPCommandBars.h"
  35. #include "XTPFrameWnd.h"
  36. #include "XTPControls.h"
  37. #include "XTPControlExt.h"
  38. #ifdef _DEBUG
  39. #define new DEBUG_NEW
  40. #undef THIS_FILE
  41. static char THIS_FILE[] = __FILE__;
  42. #endif
  43. #ifndef OIC_WINLOGO
  44. #define OIC_WINLOGO         32517
  45. #endif
  46. #define xtpTabNavigateButtonActiveFiles 4
  47. #define ACTION_CANCEL       0
  48. #define ACTION_POPUP        1
  49. #define ACTION_ATTACH       2
  50. #define ACTION_INSERTHORIZ  3
  51. #define ACTION_INSERTVERT   4
  52. class CXTPTabClientWnd::CNavigateButtonActiveFiles : public CXTPTabManagerNavigateButton
  53. {
  54. public:
  55. CNavigateButtonActiveFiles(CXTPTabManager* pManager, CXTPTabClientWnd* pTabClientWnd)
  56. : CXTPTabManagerNavigateButton(pManager, xtpTabNavigateButtonActiveFiles, xtpTabNavigateButtonNone)
  57. {
  58. m_bHiddenTabs = FALSE;
  59. m_pTabClientWnd = pTabClientWnd;
  60. XTPResourceManager()->LoadString(&m_strToolTip, XTP_IDS_TABNAVIGATEBUTTON_ACTIVEFILES);
  61. }
  62. void DrawEntry(CDC* pDC, CRect rc)
  63. {
  64. CPoint pt(rc.CenterPoint().x, rc.CenterPoint().y + 1);
  65. CPoint pts[] =
  66. {
  67. CPoint(pt.x - 4, pt.y - 1), CPoint(pt.x - 1, pt.y + 2) , CPoint(pt.x, pt.y + 2), CPoint(pt.x + 3, pt.y - 1)
  68. };
  69. pDC->Polygon(pts, 4);
  70. if (m_bHiddenTabs)
  71. {
  72. pDC->Rectangle(pt.x - 4, pt.y - 5, pt.x + 4, pt.y - 3);
  73. }
  74. }
  75. void Reposition(CRect& rcNavigateButtons)
  76. {
  77. CRect rc = m_pManager->GetAppearanceSet()->GetHeaderMargin();
  78. m_bHiddenTabs = m_pManager->GetItemsLength() > m_pManager->GetRectLength(rcNavigateButtons) - rc.left - rc.right - GetSize().cx;
  79. CXTPTabManagerNavigateButton::Reposition(rcNavigateButtons);
  80. }
  81. void PerformClick(HWND hWnd, CPoint /*pt*/)
  82. {
  83. CXTPCommandBars* pCommandBars = m_pTabClientWnd->GetCommandBars();
  84. if (!pCommandBars || pCommandBars->IsCustomizeMode())
  85. return;
  86. m_bPressed = TRUE;
  87. m_pManager->RedrawControl(NULL, FALSE);
  88. CPoint pt(m_rcButton.left, m_rcButton.bottom);
  89. m_pTabClientWnd->WorkspaceToScreen(&pt);
  90. CRect rcExclude(pt.x, pt.y - m_rcButton.Height(), pt.x + m_rcButton.Width(), pt.y);
  91. CXTPPopupBar* pPopupBar = CXTPPopupBar::CreatePopupBar(pCommandBars);
  92. CXTPImageManager* pImageManager = new CXTPImageManager();
  93. pPopupBar->SetImageManager(pImageManager);
  94. int nIconId = 0;
  95. HICON hIconLast = 0;
  96. for (int nIndex = 0; nIndex < m_pManager->GetItemCount(); nIndex++)
  97. {
  98. CXTPTabManagerItem* pItem = m_pManager->GetItem(nIndex);
  99. CString pCaption = pItem->GetCaption();
  100. CXTPControl* pControl = pPopupBar->GetControls()->Add(xtpControlButton, nIndex + 1, _T(""), nIndex, TRUE);
  101. HICON hIcon = m_pTabClientWnd->GetItemIcon(pItem);
  102. if (hIconLast != hIcon)
  103. {
  104. nIconId++;
  105. pImageManager->SetIcon(CXTPImageManagerIconHandle(hIcon, FALSE), nIconId);
  106. hIconLast = hIcon;
  107. }
  108. pControl->SetIconId(nIconId);
  109. pControl->SetCaption(CXTPControlWindowList::ConstructCaption(pCaption, 0));
  110. pControl->SetDescription(_T(""));
  111. }
  112. int nItem = pCommandBars->TrackPopupMenu(pPopupBar, TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, pt.x, pt.y, m_pTabClientWnd, &rcExclude);
  113. pPopupBar->InternalRelease();
  114. m_bPressed = FALSE;
  115. m_pManager->PerformMouseMove(hWnd, CPoint(-1, -1));
  116. m_pManager->RedrawControl(NULL, FALSE);
  117. if (nItem > 0)
  118. {
  119. CXTPTabManagerItem* pItem = m_pManager->GetItem(nItem - 1);
  120. if (pItem)
  121. {
  122. m_pTabClientWnd->MDIActivate(CWnd::FromHandle(pItem->GetHandle()));
  123. }
  124. }
  125. }
  126. protected:
  127. BOOL m_bHiddenTabs;
  128. CXTPTabClientWnd* m_pTabClientWnd;
  129. };
  130. class CXTPTabClientWnd::CTabClientDropTarget : public COleDropTarget
  131. {
  132. virtual DROPEFFECT OnDragOver(CWnd* /*pWnd*/, COleDataObject* /*pDataObject*/, DWORD /*dwKeyState*/, CPoint point)
  133. {
  134. ASSERT(m_pTabClientWnd);
  135. if (!m_pTabClientWnd || !m_pTabClientWnd->GetPaintManager()->m_bSelectOnDragOver)
  136. return DROPEFFECT_NONE;
  137. CXTPTabManagerItem* pItem = m_pTabClientWnd->HitTest(point);
  138. if (pItem && !pItem->IsSelected())
  139. {
  140. m_pTabClientWnd->MDIActivate(CWnd::FromHandle(pItem->GetHandle()));
  141. }
  142. return DROPEFFECT_NONE;
  143. }
  144. public:
  145. CXTPTabClientWnd* m_pTabClientWnd;
  146. };
  147. //////////////////////////////////////////////////////////////////////////
  148. // CWorkspace
  149. CXTPTabClientWnd::CWorkspace::CWorkspace()
  150. {
  151. m_pTabClientWnd = NULL;
  152. m_dHeight = 100;
  153. }
  154. CXTPTabClientWnd::CWorkspace::~CWorkspace()
  155. {
  156. }
  157. void CXTPTabClientWnd::CWorkspace::SetSelectedItem(CXTPTabManagerItem* pItem)
  158. {
  159. if (m_pSelected != pItem)
  160. {
  161. }
  162. CXTPTabManager::SetSelectedItem(pItem);
  163. }
  164. BOOL CXTPTabClientWnd::CWorkspace::IsMouseLocked() const
  165. {
  166. return CXTPTabManager::IsMouseLocked() || XTPMouseManager()->IsTrackedLock();
  167. }
  168. void CXTPTabClientWnd::CWorkspace::RedrawControl(LPCRECT lpRect, BOOL /*bAnimate*/)
  169. {
  170. if (!m_pTabClientWnd->m_bLockReposition)
  171. m_pTabClientWnd->InvalidateRect(lpRect, FALSE);
  172. }
  173. void CXTPTabClientWnd::CWorkspace::Reposition()
  174. {
  175. if (!m_pTabClientWnd)
  176. return;
  177. if (m_pTabClientWnd->m_bLockReposition)
  178. {
  179. m_pTabClientWnd->m_bForceToRecalc = TRUE;
  180. }
  181. else
  182. {
  183. m_pTabClientWnd->Reposition();
  184. }
  185. }
  186. BOOL CXTPTabClientWnd::CWorkspace::IsAllowReorder() const
  187. {
  188. return m_pTabClientWnd->m_bAllowReorder;
  189. }
  190. void CXTPTabClientWnd::CWorkspace::SetAllowReorder(BOOL bAllowReorder)
  191. {
  192. m_pTabClientWnd->m_bAllowReorder = bAllowReorder;
  193. }
  194. BOOL CXTPTabClientWnd::CWorkspace::IsDrawStaticFrame() const
  195. {
  196. return GetPaintManager()->m_bStaticFrame && !m_pTabClientWnd->m_bEnableGroups;
  197. }
  198. BOOL CXTPTabClientWnd::CWorkspace::DrawIcon(CDC* pDC, CPoint pt, CXTPTabManagerItem* pItem, BOOL bDraw, CSize& szIcon) const
  199. {
  200. if (GetPaintManager()->m_bShowIcons == FALSE)
  201. return FALSE;
  202. if (!bDraw)
  203. {
  204. return TRUE;
  205. }
  206. HICON hIcon = GetItemIcon(pItem);
  207. if (hIcon)
  208. {
  209. DrawIconEx(pDC->GetSafeHdc(), pt.x, pt.y, hIcon, szIcon.cx, szIcon.cy, 0, NULL, DI_NORMAL);
  210. }
  211. return TRUE;
  212. }
  213. CXTPTabPaintManager* CXTPTabClientWnd::CWorkspace::GetPaintManager() const
  214. {
  215. return m_pTabClientWnd ? m_pTabClientWnd->m_pPaintManager : NULL;
  216. }
  217. CString CXTPTabClientWnd::CWorkspace::GetItemTooltip(const CXTPTabManagerItem* pItem) const
  218. {
  219. return m_pTabClientWnd->GetItemTooltip(pItem);
  220. }
  221. // finds the tab item for specified window. Returns NULL if not found
  222. CXTPTabManagerItem* CXTPTabClientWnd::CWorkspace::FindItem(const HWND hWnd) const
  223. {
  224. // loop through all tab items
  225. for (int nIndex = 0; nIndex < GetItemCount(); nIndex++)
  226. {
  227. // check for window handle
  228. if (GetItem(nIndex)->GetHandle() == hWnd)
  229. {
  230. return GetItem(nIndex);
  231. }
  232. }
  233. return NULL;
  234. }
  235. // add new item into the tab control for specified MDIChild. If bRedraw is
  236. // set to TRUE then framework will be redrawn in order to show new item.
  237. CXTPTabManagerItem* CXTPTabClientWnd::CWorkspace::AddItem(const CWnd* pChildWnd)
  238. {
  239. ASSERT(pChildWnd != NULL);
  240. if (!pChildWnd)
  241. return NULL;
  242. ASSERT(::IsWindow(pChildWnd->GetSafeHwnd()));
  243. // make sure we add MDIChild window
  244. if ((pChildWnd->GetExStyle() & WS_EX_MDICHILD) == 0)
  245. return NULL;
  246. int nIndex = GetItemCount();
  247. switch (m_pTabClientWnd->GetNewTabPositon())
  248. {
  249. case xtpWorkspaceNewTabLeftMost:
  250. nIndex = 0;
  251. break;
  252. case xtpWorkspaceNewTabNextToActive:
  253. nIndex = GetCurSel() + 1;
  254. break;
  255. }
  256. // save information about new entry
  257. CXTPTabManagerItem* pItem = CXTPTabManager::AddItem(nIndex);
  258. pItem->SetCaption(m_pTabClientWnd->GetItemText(pChildWnd));
  259. return pItem;
  260. }
  261. BOOL CXTPTabClientWnd::CWorkspace::OnBeforeItemClick(CXTPTabManagerItem* pItem)
  262. {
  263. return m_pTabClientWnd->OnBeforeItemClick(pItem);
  264. }
  265. void CXTPTabClientWnd::CWorkspace::OnItemClick(CXTPTabManagerItem* pItem)
  266. {
  267. ASSERT(pItem);
  268. if (!pItem)
  269. return;
  270. CWnd* pWnd = CWnd::FromHandle(pItem->GetHandle());
  271. if (pWnd)
  272. {
  273. m_pTabClientWnd->MDIActivate(pWnd);
  274. CWnd* pFocus = GetFocus();
  275. BOOL bHasFocus = pFocus->GetSafeHwnd() &&
  276. (pFocus == pWnd || pWnd->IsChild(pFocus) || (pFocus->GetOwner()->GetSafeHwnd() && pWnd->IsChild(pFocus->GetOwner())));
  277. if (!bHasFocus)
  278. pWnd->SetFocus();
  279. }
  280. }
  281. CWnd* CXTPTabClientWnd::CWorkspace::GetWindow() const
  282. {
  283. return m_pTabClientWnd;
  284. }
  285. void CXTPTabClientWnd::CWorkspace::OnNavigateButtonClick(CXTPTabManagerNavigateButton* pButton)
  286. {
  287. if (pButton->GetID() != xtpTabNavigateButtonClose)
  288. return;
  289. CXTPTabManagerItem* pItem = pButton->GetItem() ? pButton->GetItem() : m_pSelected;
  290. if (!pItem)
  291. return;
  292. m_pTabClientWnd->PostMessage(WM_IDLEUPDATECMDUI);
  293. HWND hWnd = pItem->GetHandle();
  294. ::SendMessage(hWnd, WM_CLOSE, 0, 0);
  295. }
  296. void CXTPTabClientWnd::CWorkspace::OnRecalcLayout()
  297. {
  298. }
  299. HICON CXTPTabClientWnd::CWorkspace::GetItemIcon(const CXTPTabManagerItem* pItem) const
  300. {
  301. return m_pTabClientWnd->GetItemIcon(pItem);
  302. }
  303. COLORREF CXTPTabClientWnd::CWorkspace::GetItemColor(const CXTPTabManagerItem* pItem) const
  304. {
  305. COLORREF clr = m_pTabClientWnd->GetItemColor(pItem);
  306. if (clr != COLORREF_NULL)
  307. {
  308. if (clr >= xtpTabColorBlue && clr <= xtpTabColorMagenta)
  309. return CXTPTabPaintManager::GetOneNoteColor((XTPTabOneNoteColor)clr);
  310. return clr;
  311. }
  312. return CXTPTabManager::GetItemColor(pItem);
  313. }
  314. void CXTPTabClientWnd::CWorkspace::ReOrder(HWND hWnd, CPoint pt, CXTPTabManagerItem* pItem)
  315. {
  316. if (m_pTabClientWnd->GetWorkspaceCount() == 1 && pItem->GetTabManager()->GetItemCount() == 1)
  317. {
  318. OnItemClick(pItem);
  319. return;
  320. }
  321. if (m_pSelected != pItem)
  322. {
  323. m_pSelected = pItem;
  324. }
  325. m_pTabClientWnd->m_bLockReposition = TRUE;
  326. m_pTabClientWnd->SetActiveWorkspace(this);
  327. m_pTabClientWnd->m_bLockReposition = FALSE;
  328. if (GetPaintManager()->m_bHotTracking)
  329. m_pHighlighted = pItem;
  330. ::SetCapture(hWnd);
  331. Reposition();
  332. CArray<CRect, CRect&> arrRects;
  333. for (int j = 0; j < GetItemCount(); j++)
  334. {
  335. CRect rc = GetItem(j)->GetRect();
  336. arrRects.Add(rc);
  337. }
  338. BOOL bRefreshCursor = FALSE;
  339. BOOL bAccept = FALSE;
  340. for (;;)
  341. {
  342. MSG msg;
  343. VERIFY(::GetMessage(&msg, NULL, 0, 0));
  344. if (::GetCapture() != hWnd)
  345. {
  346. DispatchMessage (&msg);
  347. goto ExitLoop;
  348. }
  349. switch (msg.message)
  350. {
  351. case WM_MOUSEMOVE:
  352. {
  353. pt = CPoint((short signed)LOWORD(msg.lParam), (short signed)HIWORD(msg.lParam));
  354. if (m_rcHeaderRect.IsRectEmpty() || m_rcHeaderRect.PtInRect(pt))
  355. {
  356. if (bRefreshCursor)
  357. {
  358. m_pTabClientWnd->CancelLoop();
  359. ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
  360. bRefreshCursor = FALSE;
  361. }
  362. for (int i = 0; i < arrRects.GetSize(); i++)
  363. {
  364. if (i != pItem->GetIndex() && arrRects[i].PtInRect(pt))
  365. {
  366. CXTPTabManagerItem* p = pItem;
  367. m_arrItems[pItem->GetIndex()] = m_arrItems[i];
  368. m_arrItems[i] = p;
  369. OnItemsChanged();
  370. break;
  371. }
  372. }
  373. }
  374. else if (m_pTabClientWnd->m_bEnableGroups)
  375. {
  376. if (!bRefreshCursor)
  377. {
  378. m_pTabClientWnd->InitLoop();
  379. bRefreshCursor = TRUE;
  380. }
  381. m_pTabClientWnd->ReorderWorkspace(pt, pItem);
  382. }
  383. }
  384. break;
  385. case WM_KEYDOWN:
  386. if (msg.wParam != VK_ESCAPE)
  387. break;
  388. case WM_CANCELMODE:
  389. case WM_RBUTTONDOWN:
  390. goto ExitLoop;
  391. case WM_LBUTTONUP:
  392. bAccept = TRUE;
  393. goto ExitLoop;
  394. default:
  395. DispatchMessage (&msg);
  396. break;
  397. }
  398. }
  399. ExitLoop:
  400. ReleaseCapture();
  401. PerformMouseMove(hWnd, pt);
  402. OnItemClick(pItem);
  403. if (bRefreshCursor)
  404. {
  405. m_pTabClientWnd->CancelLoop();
  406. ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
  407. if (bAccept && m_pTabClientWnd->m_nFocusedAction != ACTION_CANCEL)
  408. {
  409. if (m_pTabClientWnd->m_nFocusedAction == ACTION_POPUP)
  410. m_pTabClientWnd->ContextMenu(pt);
  411. else  m_pTabClientWnd->DoWorkspaceCommand(pItem, m_pTabClientWnd->m_pFocusWorkspace, m_pTabClientWnd->m_nFocusedAction);
  412. }
  413. }
  414. pItem->GetTabManager()->EnsureVisible(pItem);
  415. }
  416. //////////////////////////////////////////////////////////////////////////
  417. // CSingleWorkspace
  418. CXTPTabClientWnd::CSingleWorkspace::~CSingleWorkspace()
  419. {
  420. DestroyWindow();
  421. }
  422. CWnd* CXTPTabClientWnd::CSingleWorkspace::GetWindow() const
  423. {
  424. return (CWnd*)this;
  425. }
  426. INT_PTR CXTPTabClientWnd::CSingleWorkspace::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  427. {
  428. return PerformToolHitTest(m_hWnd, point, pTI);
  429. }
  430. BOOL CXTPTabClientWnd::CSingleWorkspace::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  431. {
  432. if (m_pTabClientWnd)
  433. {
  434. m_pTabClientWnd->m_pToolTipContext->FilterToolTipMessage(this, message, wParam, lParam);
  435. }
  436. return CWnd::OnWndMsg(message, wParam, lParam, pResult);
  437. }
  438. BOOL CXTPTabClientWnd::CSingleWorkspace::PreTranslateMessage(MSG* pMsg)
  439. {
  440. if (pMsg->message == WM_LBUTTONDOWN ||
  441. pMsg->message == WM_RBUTTONDOWN ||
  442. pMsg->message == WM_MBUTTONDOWN ||
  443. pMsg->message == WM_LBUTTONDBLCLK ||
  444. pMsg->message == WM_RBUTTONDBLCLK)
  445. {
  446. if (GetParentFrame()->SendMessage(WM_XTP_PRETRANSLATEMOUSEMSG, (WPARAM)pMsg->message, pMsg->lParam))
  447. return TRUE;
  448. }
  449. return CWnd::PreTranslateMessage(pMsg);
  450. }
  451. void CXTPTabClientWnd::CSingleWorkspace::RedrawControl(LPCRECT lpRect, BOOL /*bAnimate*/)
  452. {
  453. if (!m_pTabClientWnd->m_bLockReposition)
  454. InvalidateRect(lpRect, FALSE);
  455. }
  456. BEGIN_MESSAGE_MAP(CXTPTabClientWnd::CSingleWorkspace, CWnd)
  457. { WM_LBUTTONDBLCLK, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, CPoint))&CXTPTabClientWnd::CSingleWorkspace::OnLButtonDblClk },
  458. { WM_PAINT, 0, 0, 0, AfxSig_vv, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&CXTPTabClientWnd::CSingleWorkspace::OnPaint },
  459. { WM_PRINTCLIENT, 0, 0, 0, AfxSig_lwl, (AFX_PMSG)(AFX_PMSGW)(LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))&CXTPTabClientWnd::CSingleWorkspace::OnPrintClient },
  460. { WM_ERASEBKGND, 0, 0, 0, AfxSig_bD, (AFX_PMSG)(AFX_PMSGW)(BOOL (AFX_MSG_CALL CWnd::*)(CDC*))&CXTPTabClientWnd::CSingleWorkspace::OnEraseBkgnd },
  461. { WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, CPoint))&CXTPTabClientWnd::CSingleWorkspace::OnLButtonDown },
  462. { WM_MOUSEMOVE, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, CPoint))&CXTPTabClientWnd::CSingleWorkspace::OnMouseMove },
  463. { WM_MOUSELEAVE, 0, 0, 0, AfxSig_vv, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&CXTPTabClientWnd::CSingleWorkspace::OnMouseLeave },
  464. { WM_RBUTTONDOWN, 0, 0, 0, AfxSig_vwp, (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, CPoint))&CXTPTabClientWnd::CSingleWorkspace::OnRButtonDown },
  465. END_MESSAGE_MAP()
  466. void CXTPTabClientWnd::CSingleWorkspace::OnRButtonDown(UINT /*nFlags*/, CPoint point)
  467. {
  468. UNREFERENCED_PARAMETER(point);
  469. }
  470. void CXTPTabClientWnd::CSingleWorkspace::OnPaint()
  471. {
  472. CPaintDC dcPaint(this);
  473. CXTPClientRect rc(this);
  474. CXTPBufferDC dc(dcPaint);
  475. if (m_pTabClientWnd)
  476. {
  477. CRect rectClient;
  478. m_pTabClientWnd->GetWindowRect(rectClient);
  479. ScreenToClient(&rectClient);
  480. dcPaint.ExcludeClipRect(rectClient);
  481. dc.ExcludeClipRect(rectClient);
  482. }
  483. GetPaintManager()->DrawTabControl(this, &dc, rc);
  484. }
  485. LRESULT CXTPTabClientWnd::CSingleWorkspace::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
  486. {
  487. CDC* pDC = CDC::FromHandle((HDC)wParam);
  488. if (pDC)
  489. {
  490. if (m_pTabClientWnd)
  491. {
  492. CRect rectClient;
  493. m_pTabClientWnd->GetWindowRect(rectClient);
  494. ScreenToClient(&rectClient);
  495. pDC->ExcludeClipRect(rectClient);
  496. }
  497. CXTPClientRect rc(this);
  498. GetPaintManager()->DrawTabControl(this, pDC, rc);
  499. }
  500. return TRUE;
  501. }
  502. BOOL CXTPTabClientWnd::CSingleWorkspace::OnEraseBkgnd(CDC* /*pDC*/)
  503. {
  504. return TRUE;
  505. }
  506. void CXTPTabClientWnd::CSingleWorkspace::OnLButtonDown(UINT /*nFlags*/, CPoint point)
  507. {
  508. m_pTabClientWnd->m_bLockUpdate = TRUE;
  509. m_pTabClientWnd->m_bDelayLock = TRUE;
  510. PerformClick(m_hWnd, point);
  511. }
  512. void CXTPTabClientWnd::CSingleWorkspace::OnLButtonDblClk(UINT nFlags, CPoint point)
  513. {
  514. OnLButtonDown(nFlags, point);
  515. }
  516. void CXTPTabClientWnd::CSingleWorkspace::OnMouseMove(UINT /*nFlags*/, CPoint point)
  517. {
  518. PerformMouseMove(m_hWnd, point);
  519. }
  520. void CXTPTabClientWnd::CSingleWorkspace::OnMouseLeave()
  521. {
  522. PerformMouseMove(m_hWnd, CPoint(-1, -1));
  523. }
  524. //////////////////////////////////////////////////////////////////////////
  525. // CXTPControlTabWorkspace
  526. IMPLEMENT_XTP_CONTROL(CXTPControlTabWorkspace, CXTPControlButton)
  527. CXTPControlTabWorkspace::CXTPControlTabWorkspace()
  528. {
  529. m_bForceRecalc = FALSE;
  530. m_nWidth = 220;
  531. SetFlags(xtpFlagSkipFocus | xtpFlagNoMovable);
  532. }
  533. CXTPControlTabWorkspace::~CXTPControlTabWorkspace()
  534. {
  535. }
  536. void CXTPControlTabWorkspace::RedrawControl(LPCRECT lpRect, BOOL bAnimate)
  537. {
  538. m_pParent->Redraw(lpRect, bAnimate);
  539. }
  540. CXTPTabPaintManager* CXTPControlTabWorkspace::GetPaintManager() const
  541. {
  542. return CWorkspace::GetPaintManager();
  543. }
  544. CWnd* CXTPControlTabWorkspace::GetWindow() const
  545. {
  546. return (CWnd*)GetParent();
  547. }
  548. void CXTPControlTabWorkspace::OnMouseMove(CPoint point)
  549. {
  550. CXTPControl::OnMouseMove(point);
  551. if (!m_pTabClientWnd)
  552. return;
  553. PerformMouseMove(m_pParent->m_hWnd, point);
  554. }
  555. void CXTPControlTabWorkspace::OnRecalcLayout()
  556. {
  557. m_bForceRecalc = TRUE;
  558. m_pParent->OnRecalcLayout();
  559. RedrawControl(GetRect(), FALSE);
  560. }
  561. XTPTabPosition CXTPControlTabWorkspace::GetPosition() const
  562. {
  563. switch (m_pParent->GetPosition())
  564. {
  565. case xtpBarLeft: return xtpTabPositionLeft;
  566. case xtpBarRight: return xtpTabPositionRight;
  567. case xtpBarBottom: return xtpTabPositionBottom;
  568. }
  569. return xtpTabPositionTop;
  570. }
  571. void CXTPControlTabWorkspace::OnRemoved()
  572. {
  573. if (m_pTabClientWnd && m_pTabClientWnd->m_pTabWorkspace == this)
  574. {
  575. m_pTabClientWnd->m_pTabWorkspace = NULL;
  576. m_pTabClientWnd->m_arrWorkspace.RemoveAll();
  577. }
  578. }
  579. void CXTPControlTabWorkspace::SetRect(CRect rcControl)
  580. {
  581. if (rcControl == CXTPControl::m_rcControl && !m_bForceRecalc)
  582. return;
  583. m_bForceRecalc = FALSE;
  584. CXTPControl::SetRect(rcControl);
  585. CXTPTabPaintManager* pPaintManager = GetPaintManager();
  586. if (!pPaintManager)
  587. return;
  588. CClientDC dc(m_pParent);
  589. pPaintManager->RepositionTabControl(this, &dc, rcControl);
  590. }
  591. void CXTPControlTabWorkspace::Draw(CDC* pDC)
  592. {
  593. CXTPTabPaintManager* pPaintManager = GetPaintManager();
  594. if (!pPaintManager)
  595. {
  596. CXTPControlButton::Draw(pDC);
  597. return;
  598. }
  599. pPaintManager->DrawTabControl(this, pDC, GetRect());
  600. }
  601. CSize CXTPControlTabWorkspace::GetSize(CDC* pDC)
  602. {
  603. CXTPTabPaintManager* pPaintManager = GetPaintManager();
  604. if (!pPaintManager)
  605. return CXTPControl::GetSize(pDC);
  606. int nHeight = pPaintManager->GetAppearanceSet()->GetHeaderHeight(this);
  607. if (pPaintManager->m_bStaticFrame) nHeight += 2;
  608. return IsVerticalPosition(m_pParent->GetPosition()) ? CSize(nHeight, m_nWidth) : CSize(m_nWidth, nHeight);
  609. }
  610. INT_PTR CXTPControlTabWorkspace::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  611. {
  612. if (!m_pTabClientWnd)
  613. return -1;
  614. CXTPTabManagerItem* pItem = HitTest(point);
  615. if (pItem)
  616. {
  617. if (GetPaintManager()->m_toolBehaviour == xtpTabToolTipNever)
  618. return 0;
  619. if (GetPaintManager()->m_toolBehaviour == xtpTabToolTipShrinkedOnly && !pItem->IsItemShrinked())
  620. return 0;
  621. CString strTip = GetItemTooltip(pItem);
  622. if (strTip.IsEmpty())
  623. return 0;
  624. INT_PTR nHit = pItem->GetIndex();
  625. CXTPToolTipContext::FillInToolInfo(pTI, GetParent()->GetSafeHwnd(), pItem->GetRect(), nHit, strTip);
  626. return nHit;
  627. }
  628. return 0;
  629. }
  630. void CXTPControlTabWorkspace::OnClick(BOOL bKeyboard, CPoint point)
  631. {
  632. if (!m_pTabClientWnd)
  633. {
  634. CXTPControlButton::OnClick(bKeyboard, point);
  635. return;
  636. }
  637. if (!bKeyboard)
  638. {
  639. m_pTabClientWnd->m_bLockUpdate = TRUE;
  640. m_pTabClientWnd->m_bDelayLock = TRUE;
  641. PerformClick(m_pParent->m_hWnd, point);
  642. }
  643. }
  644. /////////////////////////////////////////////////////////////////////////////
  645. // CXTPTabClientWnd
  646. IMPLEMENT_DYNAMIC(CXTPTabClientWnd, CWnd)
  647. CXTPTabClientWnd::CXTPTabClientWnd()
  648. {
  649. m_pParentFrame = NULL;
  650. m_bAllowReorder = TRUE;
  651. m_pPaintManager = new CXTPTabPaintManager();
  652. m_pPaintManager->m_bBoldSelected = TRUE;
  653. m_themeCommandBars = xtpThemeOffice2000;
  654. m_bAutoTheme = TRUE;
  655. m_bLockUpdate = FALSE;
  656. m_bLockReposition = FALSE;
  657. m_bForceToRecalc = FALSE;
  658. m_pActiveWorkspace = NULL;
  659. m_bHorizSplitting = TRUE;
  660. m_bRefreshed = FALSE;
  661. m_bThemedBackColor = TRUE;
  662. m_bUpdateContents = FALSE;
  663. m_bRightToLeft = FALSE;
  664. m_bUseSplitterTracker = TRUE;
  665. m_bIgnoreFlickersOnActivate = FALSE;
  666. m_nSplitterSize = 5;
  667. m_pDC = NULL;
  668. m_hCursorHoriz = XTPResourceManager()->LoadCursor(XTP_IDC_HSPLITBAR);
  669. m_hCursorVert = XTPResourceManager()->LoadCursor(XTP_IDC_VSPLITBAR);
  670. m_hCursorNew = XTPResourceManager()->LoadCursor(XTP_IDC_WORKSPACE_NEW);
  671. m_hCursorDelete = XTPResourceManager()->LoadCursor(XTP_IDC_WORKSPACE_DELETE);
  672. m_bShowWorkspace = TRUE;
  673. m_pTabWorkspace = NULL;
  674. m_bEnableGroups = FALSE;
  675. m_bUserWorkspace = FALSE;
  676. m_nMsgUpdateSkinState = RegisterWindowMessage(_T("WM_SKINFRAMEWORK_UPDATESTATE"));
  677. m_nMsgQuerySkinState = RegisterWindowMessage(_T("WM_SKINFRAMEWORK_QUERYSTATE"));
  678. CImageList il;
  679. il.Create(XTP_IDB_WORKSPACE_ICONS, 16, 1, RGB(0, 255, 0));
  680. UINT nIDs[] =
  681. {
  682. XTP_ID_WORKSPACE_NEWHORIZONTAL, XTP_ID_WORKSPACE_NEWVERTICAL
  683. };
  684. XTPImageManager()->SetIcons(il, nIDs, 2, CSize(16, 16));
  685. m_dwFlags = 0;
  686. m_pDropTarget = new CTabClientDropTarget();
  687. m_pDropTarget->m_pTabClientWnd = this;
  688. m_pToolTipContext = new CXTPToolTipContext;
  689. m_bDelayLock = FALSE;
  690. m_newTabPosition = xtpWorkspaceNewTabRightMost;
  691. m_afterCloseTabPosition = xtpWorkspaceActivateTopmost;
  692. }
  693. CXTPTabClientWnd::~CXTPTabClientWnd()
  694. {
  695. CMDTARGET_RELEASE(m_pPaintManager);
  696. if (m_pTabWorkspace != NULL)
  697. {
  698. m_pTabWorkspace->m_pTabClientWnd = NULL;
  699. m_pTabWorkspace->DeleteAllItems();
  700. }
  701. else
  702. {
  703. for (int i = 0; i < GetWorkspaceCount(); i++)
  704. {
  705. delete GetWorkspace(i);
  706. }
  707. }
  708. SAFE_DELETE(m_pDropTarget);
  709. CMDTARGET_RELEASE(m_pToolTipContext);
  710. }
  711. BOOL CXTPTabClientWnd::IsLayoutRTL() const
  712. {
  713. if (GetParentFrame()->GetExStyle() & WS_EX_LAYOUTRTL)
  714. return TRUE;
  715. return m_bRightToLeft;
  716. }
  717. #ifndef WS_EX_NOINHERITLAYOUT
  718. #define WS_EX_NOINHERITLAYOUT   0x00100000L
  719. #endif
  720. void CXTPTabClientWnd::SetLayoutRTL(BOOL bRightToLeft)
  721. {
  722. if (!XTPSystemVersion()->IsLayoutRTLSupported())
  723. return;
  724. if (m_bUserWorkspace)
  725. return;
  726. m_bRightToLeft = bRightToLeft;
  727. if (!m_bEnableGroups && GetWorkspaceCount() == 1)
  728. {
  729. ((CSingleWorkspace*)GetWorkspace(0))->ModifyStyleEx(m_bRightToLeft ? 0 : WS_EX_LAYOUTRTL,
  730. m_bRightToLeft ? WS_EX_LAYOUTRTL : 0);
  731. }
  732. if (m_bEnableGroups)
  733. {
  734. ModifyStyleEx(m_bRightToLeft ? 0 : WS_EX_LAYOUTRTL,
  735. m_bRightToLeft ? WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT : 0);
  736. }
  737. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);
  738. m_pParentFrame->DelayRecalcLayout();
  739. }
  740. CXTPTabManagerItem* CXTPTabClientWnd::FindItem(const HWND hWnd) const
  741. {
  742. // loop through all tab items
  743. for (int nIndex = 0; nIndex < GetWorkspaceCount(); nIndex++)
  744. {
  745. CXTPTabManagerItem* pItem = GetWorkspace(nIndex)->FindItem(hWnd);
  746. if (pItem)
  747. return pItem;
  748. }
  749. return NULL;
  750. }
  751. BOOL CXTPTabClientWnd::OnBeforeItemClick(CXTPTabManagerItem* pItem)
  752. {
  753. UNREFERENCED_PARAMETER(pItem);
  754. return TRUE;
  755. }
  756. CWnd* CXTPTabClientWnd::MDIGetActive()
  757. {
  758. return (GetParentFrame()->MDIGetActive());
  759. }
  760. void CXTPTabClientWnd::MDIActivate(CWnd* pWnd)
  761. {
  762. if (!pWnd || !::IsWindow(pWnd->GetSafeHwnd()))
  763. return;
  764. SendMessage(WM_MDIACTIVATE, (WPARAM)pWnd->m_hWnd, 0);
  765. if (pWnd->GetStyle() & WS_MINIMIZE)
  766. {
  767. pWnd->SendMessage(WM_SYSCOMMAND, (WPARAM)SC_RESTORE, 0L);
  768. }
  769. }
  770. CString CXTPTabClientWnd::GetItemTooltip(const CXTPTabManagerItem* pItem) const
  771. {
  772. CString strTooltip = pItem->m_strToolTip;
  773. if (!strTooltip.IsEmpty())
  774. return strTooltip;
  775. CMDIChildWnd* pChild = DYNAMIC_DOWNCAST(CMDIChildWnd, CWnd::FromHandle(pItem->GetHandle()));
  776. if (pChild)
  777. {
  778. strTooltip = (LPCTSTR)pChild->SendMessage(WM_XTP_GETWINDOWTOOLTIP, (WPARAM)pItem);
  779. if (!strTooltip.IsEmpty())
  780. return strTooltip;
  781. if (pChild->GetActiveDocument())
  782. strTooltip = pChild->GetActiveDocument()->GetPathName();
  783. if (!strTooltip.IsEmpty())
  784. return strTooltip;
  785. }
  786. return pItem->GetCaption();
  787. }
  788. CString CXTPTabClientWnd::GetItemText(const CWnd* pChildWnd) const
  789. {
  790. ASSERT(pChildWnd != NULL);
  791. if (!pChildWnd)
  792. return _T("");
  793. ASSERT(pChildWnd->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)));
  794. CString sWindowText = (LPCTSTR)((CWnd*)pChildWnd)->
  795. SendMessage(WM_XTP_GETWINDOWTEXT);
  796. if (sWindowText.IsEmpty())
  797. {
  798. CDocument* pDoc = ((CMDIChildWnd*)pChildWnd)->GetActiveDocument();
  799. if (pDoc != NULL)
  800. sWindowText = pDoc->GetTitle();
  801. if (sWindowText.IsEmpty())
  802. CXTPDrawHelpers::GetWindowCaption(pChildWnd->GetSafeHwnd(), sWindowText);
  803. }
  804. return sWindowText;
  805. }
  806. COLORREF CXTPTabClientWnd::GetItemColor(const CXTPTabManagerItem* pItem) const
  807. {
  808. COLORREF clr = (COLORREF)::SendMessage(pItem->GetHandle(), WM_XTP_GETTABCOLOR, 0, 0);
  809. if (clr != 0)
  810. {
  811. return clr;
  812. }
  813. return COLORREF_NULL;
  814. }
  815. HICON CXTPTabClientWnd::GetItemIcon(const CXTPTabManagerItem* pItem) const
  816. {
  817. HWND hWnd = pItem->GetHandle();
  818. HICON hIcon;
  819. hIcon = (HICON)::SendMessage(hWnd, WM_XTP_GETTABICON, 0, 0);
  820. if (!hIcon) hIcon = (HICON)::SendMessage(hWnd, WM_GETICON, ICON_SMALL, 0);
  821. if (!hIcon) hIcon = (HICON)::SendMessage(hWnd, WM_GETICON, ICON_BIG, 0);
  822. if (!hIcon) hIcon = (HICON)(ULONG_PTR)::GetClassLongPtr(hWnd, GCLP_HICONSM);
  823. if (!hIcon) hIcon = (HICON)(ULONG_PTR)::GetClassLongPtr(hWnd, GCLP_HICON);
  824. return hIcon ? hIcon : AfxGetApp()->LoadOEMIcon(OIC_WINLOGO);
  825. }
  826. BEGIN_MESSAGE_MAP(CXTPTabClientWnd, CWnd)
  827. //{{AFX_MSG_MAP(CXTPTabClientWnd)
  828. ON_MESSAGE(WM_MDIACTIVATE, OnMDIActivate)
  829. ON_MESSAGE(WM_MDINEXT, OnMDINext)
  830. ON_MESSAGE(WM_MDICREATE, OnMDICreate)
  831. ON_MESSAGE(WM_MDIDESTROY, OnMDIDestroy)
  832. ON_WM_SIZE()
  833. ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
  834. ON_WM_PAINT()
  835. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  836. ON_WM_ERASEBKGND()
  837. ON_WM_NCPAINT()
  838. ON_WM_NCCALCSIZE()
  839. ON_WM_NCACTIVATE()
  840. ON_WM_LBUTTONDBLCLK()
  841. ON_WM_PAINT()
  842. ON_WM_ERASEBKGND()
  843. ON_WM_LBUTTONDOWN()
  844. ON_WM_MOUSEMOVE()
  845. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  846. ON_WM_SYSCOLORCHANGE()
  847. ON_WM_SETCURSOR()
  848. ON_WM_RBUTTONDOWN()
  849. ON_COMMAND_RANGE(XTP_ID_WORKSPACE_MOVEPREVIOUS, XTP_ID_WORKSPACE_NEWVERTICAL, OnWorkspaceCommand)
  850. ON_UPDATE_COMMAND_UI_RANGE(XTP_ID_WORKSPACE_MOVEPREVIOUS, XTP_ID_WORKSPACE_NEWVERTICAL, OnUpdateWorkspaceCommand)
  851. //}}AFX_MSG_MAP
  852. END_MESSAGE_MAP()
  853. CXTPTabClientWnd::CWorkspace* CXTPTabClientWnd::CreateWorkspace()
  854. {
  855. if (m_pTabWorkspace != NULL)
  856. return m_pTabWorkspace;
  857. if (m_bUserWorkspace)
  858. return NULL;
  859. if (m_bEnableGroups)
  860. return new CWorkspace();
  861. return new CSingleWorkspace();
  862. }
  863. CXTPTabClientWnd::CWorkspace*  CXTPTabClientWnd::AddWorkspace(int nIndex)
  864. {
  865. if (m_pDropTarget) m_pDropTarget->Revoke();
  866. CWorkspace* pWorkspace = CreateWorkspace();
  867. if (!pWorkspace)
  868. return NULL;
  869. if (m_bEnableGroups)
  870. {
  871. if (m_pDropTarget) m_pDropTarget->Register(this);
  872. }
  873. else if (!m_bUserWorkspace)
  874. {
  875. VERIFY(((CSingleWorkspace*)pWorkspace)->Create(AfxRegisterWndClass(CS_DBLCLKS, AfxGetApp()->LoadStandardCursor(IDC_ARROW)), _T(""), WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE, CXTPEmptyRect(), m_pParentFrame, 0));
  876. if (m_pDropTarget) m_pDropTarget->Register((CSingleWorkspace*)pWorkspace);
  877. if (IsLayoutRTL())
  878. {
  879. ((CSingleWorkspace*)pWorkspace)->ModifyStyleEx(0, WS_EX_LAYOUTRTL);
  880. }
  881. }
  882. if (nIndex == -1) nIndex = GetWorkspaceCount();
  883. m_arrWorkspace.InsertAt(nIndex, pWorkspace);
  884. pWorkspace->m_pTabClientWnd = this;
  885. pWorkspace->SetActive(FALSE);
  886. pWorkspace->SetItemMetrics(CSize(70, 18), 0, CSize(220, 0));
  887. pWorkspace->GetNavigateButtons()->InsertAt(2, new CNavigateButtonActiveFiles(pWorkspace, this));
  888. UpdateFlags(pWorkspace);
  889. m_bForceToRecalc = TRUE;
  890. return pWorkspace;
  891. }
  892. BOOL CXTPTabClientWnd::Attach(CXTPMDIFrameWnd* pParentFrame,
  893. BOOL bEnableGroups /*= FALSE*/)
  894. {
  895. ASSERT(GetWorkspaceCount() == 0);
  896. ASSERT(pParentFrame != NULL);
  897. if (!pParentFrame)
  898. return FALSE;
  899. ASSERT(::IsWindow(pParentFrame->GetSafeHwnd()));
  900. m_bEnableGroups = bEnableGroups;
  901. // check if already attached
  902. if (IsAttached())
  903. {
  904. TRACE(_T("CXTPTabClientWnd::Attach: window has already been attached. Call Detach() function before !n"));
  905. return FALSE;
  906. }
  907. // make sure the specified window is/derived from CMDIFrameWnd class
  908. if (!pParentFrame->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)))
  909. {
  910. TRACE(_T("CXTPTabClientWnd::Attach: specified frame window is not of CMDIFrameWnd class (or derived)!n"));
  911. return FALSE;
  912. }
  913. // try to sublass MDIClient window
  914. if (!SubclassWindow(pParentFrame->m_hWndMDIClient))
  915. {
  916. TRACE(_T("CXTPTabClientWnd::Attach: failed to subclass MDI Client windown"));
  917. return FALSE;
  918. }
  919. SendMessage(m_nMsgUpdateSkinState);
  920. // save the pointer to parent MDIFrame
  921. m_pParentFrame = pParentFrame;
  922. CheckCommandBarsTheme();
  923. GetPaintManager()->RefreshMetrics();
  924. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER);
  925. // update the size and position of the tab control and MDIClient window
  926. Reposition();
  927. if (bEnableGroups)
  928. {
  929. ::SetClassLong(m_hWnd, GCL_STYLE, ::GetClassLong(m_hWnd, GCL_STYLE) | CS_DBLCLKS);
  930. }
  931. // populate tab control with MDIChild windows if any exist at the moment
  932. UpdateContents();
  933. return TRUE;
  934. }
  935. void CXTPTabClientWnd::EnableToolTips(XTPTabToolTipBehaviour behaviour /*= xtpTabToolTipAlways*/)
  936. {
  937. m_pPaintManager->EnableToolTips(behaviour);
  938. }
  939. void CXTPTabClientWnd::ShowWorkspace(BOOL bShow)
  940. {
  941. if (m_bShowWorkspace == bShow)
  942. return;
  943. if (!m_bEnableGroups && !m_bUserWorkspace)
  944. {
  945. if (GetWorkspaceCount() == 1 && ((CSingleWorkspace*)GetWorkspace(0))->m_hWnd)
  946. {
  947. ((CSingleWorkspace*)GetWorkspace(0))->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  948. }
  949. m_bShowWorkspace = bShow;
  950. UpdateContents();
  951. Reposition();
  952. }
  953. }
  954. BOOL CXTPTabClientWnd::Detach()
  955. {
  956. // check if any attached
  957. if (!IsAttached())
  958. {
  959. TRACE(_T("CXTPTabClientWnd::Attach: there is nothing to detach! Window hasn't been attached!n"));
  960. return FALSE;
  961. }
  962. if (m_pDropTarget) m_pDropTarget->Revoke();
  963. if (m_pTabWorkspace)
  964. {
  965. m_pTabWorkspace->m_pTabClientWnd = NULL;
  966. m_pTabWorkspace->DeleteAllItems();
  967. }
  968. else
  969. {
  970. for (int i = 0; i < GetWorkspaceCount(); i++)
  971. {
  972. delete GetWorkspace(i);
  973. }
  974. }
  975. m_arrWorkspace.RemoveAll();
  976. m_pActiveWorkspace = NULL;
  977. HWND hWnd = m_hWnd;
  978. // unsubclass MDIClient window
  979. UnsubclassWindow();
  980. // update the size and position of the MDIClient window
  981. if (::IsWindow(m_pParentFrame->GetSafeHwnd()))
  982. m_pParentFrame->RecalcLayout();
  983. m_pParentFrame = NULL;
  984. ::SendMessage(hWnd, m_nMsgUpdateSkinState, 0, 0);
  985. return TRUE;
  986. }
  987. INT_PTR CXTPTabClientWnd::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  988. {
  989. if (XTPMouseManager()->IsTrackedLock())
  990. return -1;
  991. if (!m_bShowWorkspace)
  992. return -1;
  993. for (int i = 0; i < GetWorkspaceCount(); i++)
  994. {
  995. if (GetWorkspace(i)->GetControlRect().PtInRect(point))
  996. {
  997. return GetWorkspace(i)->PerformToolHitTest(m_hWnd, point, pTI);
  998. }
  999. }
  1000. return -1;
  1001. }
  1002. void CXTPTabClientWnd::CheckCommandBarsTheme()
  1003. {
  1004. if (!m_bAutoTheme)
  1005. return;
  1006. CXTPCommandBars* pCommandBars = GetCommandBars();
  1007. if (!pCommandBars)
  1008. return;
  1009. XTPPaintTheme themeCommandBars = pCommandBars->GetPaintManager()->BaseTheme();
  1010. if (m_themeCommandBars != themeCommandBars)
  1011. {
  1012. m_pPaintManager->m_bStaticFrame = FALSE;
  1013. m_pPaintManager->m_clientFrame = xtpTabFrameBorder;
  1014. m_pPaintManager->m_bOneNoteColors = FALSE;
  1015. m_pPaintManager->m_bHotTracking = FALSE;
  1016. m_pPaintManager->m_rcButtonMargin.SetRect(0, 0, 0, 0);
  1017. m_pPaintManager->m_bClearTypeTextQuality = pCommandBars->GetPaintManager()->m_bClearTypeTextQuality;
  1018. switch (themeCommandBars)
  1019. {
  1020. case xtpThemeOfficeXP:
  1021. m_pPaintManager->SetAppearance(xtpTabAppearanceVisualStudio);
  1022. m_pPaintManager->m_bStaticFrame = TRUE;
  1023. m_pPaintManager->m_clientFrame = xtpTabFrameSingleLine;
  1024. break;
  1025. case xtpThemeOffice2007:
  1026. m_pPaintManager->m_bDisableLunaColors = FALSE;
  1027. m_pPaintManager->m_bOneNoteColors = TRUE;
  1028. m_pPaintManager->m_bHotTracking = TRUE;
  1029. m_pPaintManager->SetAppearance(xtpTabAppearancePropertyPage2003);
  1030. m_pPaintManager->SetColor(xtpTabColorOffice2007);
  1031. break;
  1032. case xtpThemeRibbon:
  1033. m_pPaintManager->m_bDisableLunaColors = FALSE;
  1034. m_pPaintManager->m_bOneNoteColors = FALSE;
  1035. m_pPaintManager->m_bHotTracking = TRUE;
  1036. if (pCommandBars->GetMenuBar() && pCommandBars->GetMenuBar()->GetType() == xtpBarTypeRibbon)
  1037. {
  1038. m_pPaintManager->SetAppearance(xtpTabAppearancePropertyPageAccess2007);
  1039. m_pPaintManager->m_rcButtonMargin.SetRect(3, 0, 3, 0);
  1040. }
  1041. else
  1042. {
  1043. m_pPaintManager->SetAppearance(xtpTabAppearancePropertyPage2007);
  1044. m_pPaintManager->m_rcButtonMargin.SetRect(2, 2, 2, 2);
  1045. }
  1046. break;
  1047. case xtpThemeOffice2003:
  1048. m_pPaintManager->m_bDisableLunaColors = FALSE;
  1049. m_pPaintManager->m_bOneNoteColors = TRUE;
  1050. m_pPaintManager->m_bHotTracking = TRUE;
  1051. m_pPaintManager->SetAppearance(xtpTabAppearancePropertyPage2003);
  1052. break;
  1053. case xtpThemeNativeWinXP:
  1054. m_pPaintManager->SetAppearance(xtpTabAppearancePropertyPage);
  1055. m_pPaintManager->SetColor(xtpTabColorWinXP);
  1056. m_pPaintManager->m_bHotTracking = TRUE;
  1057. break;
  1058. case xtpThemeWhidbey:
  1059. m_pPaintManager->m_bStaticFrame = TRUE;
  1060. m_pPaintManager->m_clientFrame = xtpTabFrameSingleLine;
  1061. m_pPaintManager->m_bDisableLunaColors = TRUE;
  1062. m_pPaintManager->SetAppearance(xtpTabAppearancePropertyPage2003);
  1063. m_pPaintManager->SetColor(xtpTabColorWhidbey);
  1064. break;
  1065. case xtpThemeVisualStudio2008:
  1066. m_pPaintManager->m_bStaticFrame = FALSE;
  1067. m_pPaintManager->m_clientFrame = xtpTabFrameBorder;
  1068. m_pPaintManager->m_bDisableLunaColors = TRUE;
  1069. m_pPaintManager->m_bHotTracking = TRUE;
  1070. m_pPaintManager->SetAppearance(xtpTabAppearancePropertyPage2003);
  1071. m_pPaintManager->SetColor(xtpTabColorVisualStudio2008);
  1072. break;
  1073. default:
  1074. m_pPaintManager->SetAppearance(xtpTabAppearancePropertyPage);
  1075. break;
  1076. }
  1077. m_pPaintManager->RefreshMetrics();
  1078. m_themeCommandBars = themeCommandBars;
  1079. Refresh();
  1080. }
  1081. }
  1082. int CXTPTabClientWnd::GetWorkspaceCount() const
  1083. {
  1084. return (int)m_arrWorkspace.GetSize();
  1085. }
  1086. CXTPTabClientWnd::CWorkspace* CXTPTabClientWnd::GetWorkspace(int nIndex) const
  1087. {
  1088. return m_arrWorkspace[nIndex];
  1089. }
  1090. void CXTPTabClientWnd::OnIdleUpdateCmdUI()
  1091. {
  1092. if (m_bDelayLock)
  1093. {
  1094. m_bDelayLock = FALSE;
  1095. m_bLockUpdate = FALSE;
  1096. }
  1097. UpdateContents();
  1098. }
  1099. CXTPTabManagerItem* CXTPTabClientWnd::AddItem(CWnd* pChildWnd)
  1100. {
  1101. #ifdef _DEBUG
  1102. if (m_bEnableGroups)
  1103. {
  1104. ASSERT((pChildWnd->GetStyle() & WS_MAXIMIZE) == 0);
  1105. }
  1106. #endif
  1107. if (GetWorkspaceCount() == 0)
  1108. AddWorkspace();
  1109. if (GetWorkspaceCount() == 0)
  1110. return NULL;
  1111. CWorkspace* pActiveWorkspace = m_pActiveWorkspace ? m_pActiveWorkspace : m_arrWorkspace[GetWorkspaceCount() - 1];
  1112. return pActiveWorkspace->AddItem(pChildWnd);
  1113. }
  1114. void CXTPTabClientWnd::SetActiveWorkspace(CWorkspace* pWorkspace)
  1115. {
  1116. if (m_pActiveWorkspace != pWorkspace)
  1117. {
  1118. if (m_pActiveWorkspace)
  1119. m_pActiveWorkspace->SetActive(FALSE);
  1120. m_pActiveWorkspace = pWorkspace;
  1121. m_pActiveWorkspace->SetActive(TRUE);
  1122. }
  1123. }
  1124. void CXTPTabClientWnd::WorkspaceToScreen(LPPOINT lpPoint) const
  1125. {
  1126. if (m_bEnableGroups)
  1127. {
  1128. ClientToScreen(lpPoint);
  1129. }
  1130. else if (GetWorkspaceCount() != 0)
  1131. {
  1132. CWorkspace* pWorkspace = GetWorkspace(0);
  1133. pWorkspace->GetWindow()->ClientToScreen(lpPoint);
  1134. }
  1135. }
  1136. void CXTPTabClientWnd::ScreenToWorkspace(LPPOINT lpPoint) const
  1137. {
  1138. if (m_bEnableGroups)
  1139. {
  1140. ScreenToClient(lpPoint);
  1141. }
  1142. else if (GetWorkspaceCount() != 0)
  1143. {
  1144. CWorkspace* pWorkspace = GetWorkspace(0);
  1145. pWorkspace->GetWindow()->ScreenToClient(lpPoint);
  1146. }
  1147. }
  1148. void CXTPTabClientWnd::Refresh(BOOL bRecalcLayout)
  1149. {
  1150. if (!IsAttached())
  1151. return;
  1152. if (m_bRefreshed)
  1153. return;
  1154. m_bRefreshed = TRUE;
  1155. UpdateContents();
  1156. if (GetWorkspaceCount() != 0)
  1157. {
  1158. CPoint pt;
  1159. GetCursorPos(&pt);
  1160. ScreenToWorkspace(&pt);
  1161. if (m_bEnableGroups)
  1162. {
  1163. OnMouseMove(0, pt);
  1164. }
  1165. else if (!m_bUserWorkspace)
  1166. {
  1167. ((CSingleWorkspace*)GetWorkspace(0))->OnMouseMove(0, pt);
  1168. }
  1169. }
  1170. Invalidate(FALSE);
  1171. if (bRecalcLayout)
  1172. {
  1173. if (m_bEnableGroups)
  1174. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
  1175. CXTPCommandBars* pCommandBars = GetCommandBars();
  1176. if (pCommandBars)
  1177. pCommandBars->RecalcFrameLayout();
  1178. }
  1179. m_bRefreshed = FALSE;
  1180. }
  1181. void CXTPTabClientWnd::UpdateContents()
  1182. {
  1183. if (m_hWnd == 0)
  1184. return;
  1185. if (!m_bShowWorkspace)
  1186. return;
  1187. if (m_bLockUpdate)
  1188. return;
  1189. // check MDI windows
  1190. CFrameWnd* pFrameWnd = GetParentFrame();
  1191. if (pFrameWnd == NULL)
  1192. return;
  1193. if (m_bUpdateContents)
  1194. return;
  1195. m_bUpdateContents = TRUE;
  1196. CheckCommandBarsTheme();
  1197. m_bLockReposition = TRUE;
  1198. // get pointer to currently active MDIChild
  1199. CWnd* pActiveChildWnd = MDIGetActive();
  1200. CXTPTabManagerItem* pActiveItem = NULL, *pNewItem = NULL;
  1201. int i;
  1202. for (i = 0; i < GetWorkspaceCount(); i++)
  1203. {
  1204. for (int nIndex = 0; nIndex < GetWorkspace(i)->GetItemCount(); nIndex++)
  1205. GetWorkspace(i)->GetItem(nIndex)->m_bFound = FALSE;
  1206. }
  1207. // start enumerating from currently active MDIChild
  1208. CWnd* pChildWnd = GetWindow(GW_CHILD);
  1209. // enumerate all child windows
  1210. while (pChildWnd)
  1211. {
  1212. // see if can find
  1213. CXTPTabManagerItem* pFoundItem = FindItem(pChildWnd->GetSafeHwnd());
  1214. if (pFoundItem != NULL)
  1215. {
  1216. if ((pChildWnd->GetStyle() & WS_VISIBLE) == WS_VISIBLE)
  1217. {
  1218. // update text if necessary
  1219. pFoundItem->SetCaption(GetItemText(pChildWnd));
  1220. }
  1221. else
  1222. {
  1223. pFoundItem->Remove();
  1224. pFoundItem = NULL;
  1225. }
  1226. }
  1227. else
  1228. {
  1229. if ((pChildWnd->GetStyle() & WS_VISIBLE) == WS_VISIBLE)
  1230. {
  1231. // add item
  1232. pNewItem = pFoundItem = AddItem(pChildWnd);
  1233. if (pNewItem)
  1234. {
  1235. pFoundItem->m_hWnd = pChildWnd->GetSafeHwnd();
  1236. pFrameWnd->SendMessage(WM_XTP_NEWTABITEM, (WPARAM)pNewItem);
  1237. pNewItem->GetTabManager()->SetSelectedItem(pNewItem);
  1238. }
  1239. }
  1240. }
  1241. if (pFoundItem)
  1242. {
  1243. pFoundItem->m_bFound = TRUE;
  1244. if (pChildWnd == pActiveChildWnd)
  1245. pActiveItem = pFoundItem;
  1246. }
  1247. // get next MDIChild
  1248. pChildWnd = pChildWnd->GetWindow(GW_HWNDNEXT);
  1249. }
  1250. for (i = GetWorkspaceCount() - 1; i >= 0; i--)
  1251. {
  1252. CWorkspace* pWorkspace = GetWorkspace(i);
  1253. for (int nIndex = pWorkspace->GetItemCount() - 1; nIndex >= 0; nIndex--)
  1254. {
  1255. CXTPTabManagerItem* pItem = pWorkspace->GetItem(nIndex);
  1256. if (!pItem->m_bFound)
  1257. {
  1258. pItem->Remove();
  1259. }
  1260. }
  1261. if (pWorkspace->GetItemCount() == 0)
  1262. {
  1263. if (pWorkspace == m_pActiveWorkspace)
  1264. m_pActiveWorkspace = NULL;
  1265. CWorkspace* pWorkcpaceGrow = i == 0 ? (GetWorkspaceCount() > 1 ? GetWorkspace(i + 1): NULL) : GetWorkspace(i - 1);
  1266. if (pWorkcpaceGrow)
  1267. {
  1268. pWorkcpaceGrow->m_dHeight += pWorkspace->m_dHeight + m_nSplitterSize;
  1269. }
  1270. if (pWorkspace != m_pTabWorkspace) delete pWorkspace;
  1271. m_arrWorkspace.RemoveAt(i);
  1272. m_bForceToRecalc = TRUE;
  1273. if (m_bEnableGroups)
  1274. {
  1275. Invalidate(FALSE);
  1276. }
  1277. }
  1278. }
  1279. // set the active item
  1280. if (pActiveItem != NULL)
  1281. {
  1282. if (pActiveItem->GetTabManager()->GetSelectedItem() != pActiveItem)
  1283. {
  1284. pActiveItem->GetTabManager()->SetSelectedItem(pActiveItem);
  1285. }
  1286. SetActiveWorkspace((CWorkspace*)pActiveItem->GetTabManager());
  1287. }
  1288. m_bLockReposition = FALSE;
  1289. if (m_bForceToRecalc)
  1290. {
  1291. // update the size and position of the tab control and MDIClient window
  1292. if (::IsWindow(GetParentFrame()->GetSafeHwnd()))
  1293. {
  1294. Reposition();
  1295. }
  1296. if (pNewItem)
  1297. pNewItem->GetTabManager()->EnsureVisible(pNewItem);
  1298. m_bForceToRecalc = FALSE;
  1299. }
  1300. m_bUpdateContents = FALSE;
  1301. }
  1302. /////////////////////////////////////////////////////////////////////////////
  1303. // CXTPTabClientWnd message handlers
  1304. // handler for WM_MDIACTIVATE message. Will select corresponding
  1305. // tab control item
  1306. LRESULT CXTPTabClientWnd::OnMDIActivate(WPARAM /*wParam*/, LPARAM /*lParam*/)
  1307. {
  1308. LRESULT lResult = 0;
  1309. if (m_bEnableGroups || m_bIgnoreFlickersOnActivate || !m_bShowWorkspace)
  1310. {
  1311. lResult = Default();
  1312. }
  1313. else
  1314. {
  1315. SetRedraw(FALSE);
  1316. lResult = Default();
  1317. SetRedraw(TRUE);
  1318. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);
  1319. }
  1320. UpdateContents();
  1321. return lResult;
  1322. }
  1323. // handler for WM_MDICREATE message. Will add new item into the
  1324. // tab control
  1325. LRESULT CXTPTabClientWnd::OnMDICreate(WPARAM /*wParam*/, LPARAM /*lParam*/)
  1326. {
  1327. LRESULT lResult = Default();
  1328. if (lResult && m_bEnableGroups)
  1329. {
  1330. CWnd* pWnd = CWnd::FromHandle((HWND)lResult);
  1331. if (pWnd)
  1332. {
  1333. pWnd->ModifyStyle(WS_BORDER | WS_DLGFRAME | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, 0);
  1334. pWnd->ModifyStyleEx(WS_EX_CLIENTEDGE, 0);
  1335. pWnd->MoveWindow(0, 0, 0, 0);
  1336. }
  1337. }
  1338. UpdateContents();
  1339. return lResult;
  1340. }
  1341. void CXTPTabClientWnd::ActivateNextItem(CXTPTabManagerItem* pItem)
  1342. {
  1343. if (!pItem)
  1344. return;
  1345. CXTPTabManagerItem* pItemActivate = pItem->GetTabManager()->GetItem(pItem->GetIndex() + 1);
  1346. if (!pItemActivate)
  1347. {
  1348. pItemActivate = pItem->GetTabManager()->GetItem(pItem->GetIndex() - 1);
  1349. }
  1350. if (!pItemActivate)
  1351. return;
  1352. HWND hWndActivate = pItemActivate->GetHandle();
  1353. if (!hWndActivate)
  1354. return;
  1355. ::BringWindowToTop(hWndActivate);
  1356. }
  1357. // handler for WM_MDIDESTROY message. Will remove the correspondent item
  1358. // from the tab control
  1359. LRESULT CXTPTabClientWnd::OnMDIDestroy(WPARAM wParam, LPARAM /*lParam*/)
  1360. {
  1361. if (m_afterCloseTabPosition == xtpWorkspaceActivateNextToClosed)
  1362. ActivateNextItem(FindItem((HWND)wParam));
  1363. LRESULT lResult = Default();
  1364. UpdateContents();
  1365. return lResult;
  1366. }
  1367. LRESULT CXTPTabClientWnd::OnMDINext(WPARAM /*wParam*/, LPARAM /*lParam*/)
  1368. {
  1369. LRESULT lResult = Default();
  1370. UpdateContents();
  1371. return lResult;
  1372. }
  1373. BOOL CXTPTabClientWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  1374. {
  1375. if (nHitTest == HTCLIENT && m_bEnableGroups)
  1376. {
  1377. CPoint point;
  1378. GetCursorPos(&point);
  1379. ScreenToClient(&point);
  1380. for (int nIndex = 0; nIndex < GetWorkspaceCount(); nIndex++)
  1381. {
  1382. CWorkspace* pWorkspace = GetWorkspace(nIndex);
  1383. if (pWorkspace->m_rcSplitter.PtInRect(point))
  1384. {
  1385. SetCursor(!m_bHorizSplitting ? m_hCursorHoriz : m_hCursorVert);
  1386. return TRUE;
  1387. }
  1388. }
  1389. }
  1390. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  1391. }
  1392. void CXTPTabClientWnd::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
  1393. {
  1394. if (GetWorkspaceCount() == 0 || !m_bShowWorkspace || m_bUserWorkspace)
  1395. {
  1396. CWnd::CalcWindowRect(lpClientRect, nAdjustType);
  1397. return;
  1398. }
  1399. if (!m_bEnableGroups)
  1400. {
  1401. CSingleWorkspace* pWorkspace = (CSingleWorkspace*)GetWorkspace(0);
  1402. // now do the laying out
  1403. HDWP dwh = BeginDeferWindowPos(2);
  1404. // move tab window
  1405. if (::IsWindow(pWorkspace->m_hWnd) && (pWorkspace->GetStyle() & WS_VISIBLE) == WS_VISIBLE)
  1406. {
  1407. {
  1408. // move tab control
  1409. dwh = ::DeferWindowPos(dwh, pWorkspace->m_hWnd, NULL, lpClientRect->left,
  1410. lpClientRect->top,
  1411. lpClientRect->right-lpClientRect->left,
  1412. lpClientRect->bottom-lpClientRect->top, SWP_NOZORDER);
  1413. CClientDC dc(pWorkspace);
  1414. CRect rectTab(lpClientRect);
  1415. rectTab.OffsetRect(-rectTab.TopLeft());
  1416. GetPaintManager()->RepositionTabControl(pWorkspace, &dc, rectTab);
  1417. CRect rectTabAdjust(lpClientRect);
  1418. GetPaintManager()->AdjustClientRect(pWorkspace, rectTabAdjust);
  1419. *lpClientRect = rectTabAdjust;
  1420. pWorkspace->Invalidate(FALSE);
  1421. }
  1422. if (lpClientRect->bottom < lpClientRect->top ||
  1423. lpClientRect->right < lpClientRect->left)
  1424. ::memset(lpClientRect, 0, sizeof(RECT));
  1425. ::ShowWindow(pWorkspace->m_hWnd, SW_SHOWNA);
  1426. }
  1427. // move MDIClient window
  1428. dwh = ::DeferWindowPos(dwh, m_hWnd, NULL, lpClientRect->left, lpClientRect->top,
  1429. lpClientRect->right - lpClientRect->left,
  1430. lpClientRect->bottom - lpClientRect->top,
  1431. SWP_NOZORDER);
  1432. EndDeferWindowPos(dwh);
  1433. }
  1434. else
  1435. {
  1436. CClientDC dc(this);
  1437. CRect rcBorders(2, 2, -2, -2);
  1438. m_pPaintManager->GetAppearanceSet()->DrawWorkspacePart(NULL, rcBorders, xtpTabWorkspacePartWidth);
  1439. CRect rcClient(0, 0, lpClientRect->right-lpClientRect->left + rcBorders.Width(), lpClientRect->bottom-lpClientRect->top + rcBorders.Height());
  1440. int nIndex;
  1441. double dTotalHeight = 0;
  1442. int nWorkspaceCount = GetWorkspaceCount();
  1443. for (nIndex = 0; nIndex < nWorkspaceCount; nIndex++)
  1444. {
  1445. dTotalHeight += GetWorkspace(nIndex)->m_dHeight;
  1446. }
  1447. int nTotalHeight = (m_bHorizSplitting ? rcClient.Height() : rcClient.Width()) - m_nSplitterSize * (nWorkspaceCount - 1);
  1448. double dHeight = 0;
  1449. if ((int)dTotalHeight == 0) dTotalHeight = 1.0;
  1450. CRect rcWorkspace(rcClient);
  1451. for (nIndex = 0; nIndex < nWorkspaceCount; nIndex++)
  1452. {
  1453. CWorkspace* pWorkspace = GetWorkspace(nIndex);
  1454. CRect rc(rcClient);
  1455. if (nIndex != nWorkspaceCount - 1)
  1456. {
  1457. dHeight = dHeight += pWorkspace->m_dHeight;
  1458. int nHeight = int(dHeight * nTotalHeight / dTotalHeight) + m_nSplitterSize * nIndex;
  1459. if (m_bHorizSplitting)
  1460. {
  1461. pWorkspace->m_rcSplitter.SetRect(rc.left, rcWorkspace.top + nHeight, rc.right, rcWorkspace.top + nHeight + m_nSplitterSize);
  1462. rc.bottom = rcWorkspace.top + nHeight;
  1463. rcClient.top = rc.bottom + m_nSplitterSize;
  1464. }
  1465. else
  1466. {
  1467. pWorkspace->m_rcSplitter.SetRect(rcWorkspace.left + nHeight, rc.top, rcWorkspace.left + nHeight + m_nSplitterSize, rc.bottom);
  1468. rc.right = rcWorkspace.left + nHeight;
  1469. rcClient.left = rc.right + m_nSplitterSize;
  1470. }
  1471. }
  1472. else
  1473. {
  1474. pWorkspace->m_rcSplitter.SetRectEmpty();
  1475. }
  1476. GetPaintManager()->RepositionTabControl(pWorkspace, &dc, rc);
  1477. rc = pWorkspace->GetClientRect();
  1478. for (int i = 0; i < pWorkspace->GetItemCount(); i++)
  1479. {
  1480. HWND hWndChild = pWorkspace->GetItem(i)->m_hWnd;
  1481. ::MoveWindow(hWndChild, rc.left, rc.top, rc.Width(), rc.Height(), TRUE);
  1482. }
  1483. }
  1484. Invalidate(FALSE);
  1485. //UpdateWindow();
  1486. }
  1487. CWnd::CalcWindowRect(lpClientRect, nAdjustType);
  1488. }
  1489. // update the size of the tab control and the MDIClient window
  1490. void CXTPTabClientWnd::OnSize(UINT nType, int cx, int cy)
  1491. {
  1492. CWnd::OnSize(nType, cx, cy);
  1493. }
  1494. BOOL CXTPTabClientWnd::OnEraseBkgnd(CDC*)
  1495. {
  1496. if (!m_bThemedBackColor && !m_bEnableGroups)
  1497. {
  1498. return (BOOL)Default();
  1499. }
  1500. return TRUE;
  1501. }
  1502. LRESULT CXTPTabClientWnd::OnPrintClient(WPARAM wParam, LPARAM)
  1503. {
  1504. if (!m_bThemedBackColor && !m_bEnableGroups)
  1505. {
  1506. return (LRESULT)Default();
  1507. }
  1508. CDC* pDC = CDC::FromHandle((HDC)wParam);
  1509. if (pDC)
  1510. {
  1511. CXTPClientRect rc(this);
  1512. OnDraw(pDC, rc);
  1513. }
  1514. return TRUE;
  1515. }
  1516. void CXTPTabClientWnd::OnFillBackground(CDC* pDC, CRect rc)
  1517. {
  1518. CXTPCommandBars* pCommandBars = GetCommandBars();
  1519. if (pCommandBars)
  1520. {
  1521. if (!m_bThemedBackColor)
  1522. DefWindowProc(WM_PAINT, (WPARAM)pDC->m_hDC, 0);
  1523. else
  1524. pDC->FillSolidRect(rc, pCommandBars->GetPaintManager()->GetXtremeColor(COLOR_APPWORKSPACE));
  1525. }
  1526. else
  1527. {
  1528. pDC->FillSolidRect(rc, GetSysColor(COLOR_APPWORKSPACE));
  1529. }
  1530. }
  1531. void CXTPTabClientWnd::OnDraw(CDC* pDC, CRect rc)
  1532. {
  1533. if (GetWorkspaceCount() == 0 || !m_bEnableGroups)
  1534. {
  1535. OnFillBackground(pDC, rc);
  1536. }
  1537. else
  1538. {
  1539. CRect rcClipBox;
  1540. pDC->GetClipBox(&rcClipBox);
  1541. for (int i = GetWorkspaceCount() - 1; i >= 0; i--)
  1542. {
  1543. CWorkspace* pWorkspace = GetWorkspace(i);
  1544. if (CRect().IntersectRect(rcClipBox, pWorkspace->m_rcControl))
  1545. {
  1546. GetPaintManager()->DrawTabControl(GetWorkspace(i), pDC, pWorkspace->m_rcControl);
  1547. }
  1548. if (!pWorkspace->m_rcSplitter.IsRectEmpty())
  1549. {
  1550. m_pPaintManager->GetAppearanceSet()->DrawWorkspacePart(pDC, pWorkspace->m_rcSplitter, m_bHorizSplitting ? xtpTabWorkspacePartHSplitter : xtpTabWorkspacePartVSplitter);
  1551. }
  1552. }
  1553. }
  1554. }
  1555. void CXTPTabClientWnd::OnPaint()
  1556. {
  1557. if (!m_bThemedBackColor && !m_bEnableGroups)
  1558. {
  1559. Default();
  1560. return;
  1561. }
  1562. CPaintDC dcPaint(this);
  1563. CXTPClientRect rc(this);
  1564. CXTPBufferDC dc(dcPaint);
  1565. OnDraw(&dc, rc);
  1566. }
  1567. void CXTPTabClientWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
  1568. {
  1569. if (m_bEnableGroups)
  1570. {
  1571. m_pPaintManager->GetAppearanceSet()->DrawWorkspacePart(NULL, &lpncsp->rgrc[0], xtpTabWorkspacePartWidth);
  1572. }
  1573. CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
  1574. }
  1575. BOOL CXTPTabClientWnd::OnNcActivate(BOOL bActive)
  1576. {
  1577. if (m_bEnableGroups)
  1578. return TRUE;
  1579. return CWnd::OnNcActivate(bActive);
  1580. }
  1581. void CXTPTabClientWnd::OnNcPaint()
  1582. {
  1583. if (!m_bEnableGroups)
  1584. {
  1585. Default();
  1586. return;
  1587. }
  1588. CWindowDC dcPaint(this);
  1589. CXTPWindowRect rc(this);
  1590. rc.OffsetRect(rc.TopLeft());
  1591. m_pPaintManager->GetAppearanceSet()->DrawWorkspacePart(&dcPaint, rc, xtpTabWorkspacePartBorder);
  1592. }
  1593. void CXTPTabClientWnd::OnRButtonDown(UINT nFlags, CPoint point)
  1594. {
  1595. CWnd::OnRButtonDown(nFlags, point);
  1596. }
  1597. void CXTPTabClientWnd::RepositionWorkspaces(CRect rc, CRect rcAvail, CWorkspace* pWorkspaceFirst, CWorkspace* pWorkspaceSecond)
  1598. {
  1599. double dTotal = pWorkspaceFirst->m_dHeight + pWorkspaceSecond->m_dHeight + m_nSplitterSize;
  1600. if (!m_bHorizSplitting)
  1601. {
  1602. double dDelta = double(rc.left - rcAvail.left) / rcAvail.Width();
  1603. pWorkspaceFirst->m_dHeight = GetExStyle() & WS_EX_LAYOUTRTL ? dTotal - dDelta * dTotal - m_nSplitterSize : dDelta * dTotal;
  1604. }
  1605. else
  1606. {
  1607. double dDelta = double(rc.top - rcAvail.top) / rcAvail.Height();
  1608. pWorkspaceFirst->m_dHeight = dDelta * dTotal;
  1609. }
  1610. pWorkspaceSecond->m_dHeight = dTotal - pWorkspaceFirst->m_dHeight - m_nSplitterSize;
  1611. }
  1612. void CXTPTabClientWnd::NormalizeWorkspaceSize()
  1613. {
  1614. for (int i = 0; i < GetWorkspaceCount(); i++)
  1615. {
  1616. CWorkspace* pWorkspace = GetWorkspace (i);
  1617. pWorkspace->m_dHeight = !m_bHorizSplitting ? pWorkspace->GetControlRect().Width() : pWorkspace->GetControlRect().Height();
  1618. }
  1619. }
  1620. void CXTPTabClientWnd::TrackSplitter(int nWorkspace, CPoint point)
  1621. {
  1622. ASSERT(nWorkspace >= 0 && nWorkspace < GetWorkspaceCount() - 1);
  1623. if (nWorkspace < 0 || nWorkspace >= GetWorkspaceCount() - 1)
  1624. return;
  1625. NormalizeWorkspaceSize();
  1626. CXTPSplitterTracker tracker;
  1627. CWorkspace* pWorkspaceFirst = m_arrWorkspace[nWorkspace];
  1628. CWorkspace* pWorkspaceSecond = m_arrWorkspace[nWorkspace + 1];
  1629. CRect rcFirst = pWorkspaceFirst->GetControlRect();
  1630. CRect rcSecond = pWorkspaceSecond->GetControlRect();
  1631. CRect rcAvail;
  1632. rcAvail.UnionRect(rcFirst, rcSecond);
  1633. CRect rc = pWorkspaceFirst->m_rcSplitter;
  1634. ClientToScreen(&rc);
  1635. ClientToScreen(&rcAvail);
  1636. ClientToScreen(&point);
  1637. if (m_bUseSplitterTracker)
  1638. {
  1639. if (tracker.Track(this, rcAvail, rc, point, !m_bHorizSplitting))
  1640. {
  1641. RepositionWorkspaces(rc, rcAvail, pWorkspaceFirst, pWorkspaceSecond);
  1642. GetParentFrame()->RecalcLayout();
  1643. }
  1644. }
  1645. else
  1646. {
  1647. CPoint ptOffset = !m_bHorizSplitting ? CPoint(rc.left - point.x, 0) :
  1648. CPoint(0, rc.top - point.y);
  1649. SetCapture();
  1650. while (CWnd::GetCapture() == this)
  1651. {
  1652. MSG msg;
  1653. while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
  1654. {
  1655. if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
  1656. return;
  1657. DispatchMessage(&msg);
  1658. }
  1659. if (!GetMessage(&msg, NULL, 0, 0))
  1660. break;
  1661. if (msg.message == WM_MOUSEMOVE)
  1662. {
  1663. point = CPoint(msg.lParam);
  1664. ClientToScreen(&point);
  1665. point += ptOffset;
  1666. point.x = max(min(point.x, rcAvail.right), rcAvail.left);
  1667. point.y = max(min(point.y, rcAvail.bottom), rcAvail.top);
  1668. if (!m_bHorizSplitting)
  1669. {
  1670. if (rc.left == point.x)
  1671. continue;
  1672. rc.OffsetRect(point.x - rc.left, 0);
  1673. }
  1674. else
  1675. {
  1676. if (rc.top == point.y)
  1677. continue;
  1678. rc.OffsetRect(0, point.y - rc.top);
  1679. }
  1680. RepositionWorkspaces(rc, rcAvail, pWorkspaceFirst, pWorkspaceSecond);
  1681. GetParentFrame()->RecalcLayout();
  1682. }
  1683. else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) break;
  1684. else if (msg.message == WM_LBUTTONUP) break;
  1685. else ::DispatchMessage(&msg);
  1686. }
  1687. if (CWnd::GetCapture() == this) ReleaseCapture();
  1688. }
  1689. }
  1690. void CXTPTabClientWnd::OnLButtonDown(UINT nFlags, CPoint point)
  1691. {
  1692. if (!m_bEnableGroups)
  1693. {
  1694. CWnd::OnLButtonDown(nFlags, point);
  1695. return;
  1696. }
  1697. m_bLockUpdate = TRUE;
  1698. m_bDelayLock = TRUE;
  1699. for (int i = 0; i < GetWorkspaceCount(); i++)
  1700. {
  1701. CWorkspace* pWorkspace = GetWorkspace(i);
  1702. if (pWorkspace->m_rcSplitter.PtInRect(point) && i < GetWorkspaceCount() - 1)
  1703. {
  1704. TrackSplitter(i, point);
  1705. break;
  1706. }
  1707. if (pWorkspace->GetControlRect().PtInRect(point))
  1708. {
  1709. if (!pWorkspace->IsActive())
  1710. {
  1711. CXTPTabManagerItem* pSelectedItem = pWorkspace->GetSelectedItem();
  1712. if (pSelectedItem) pWorkspace->OnItemClick(pSelectedItem);
  1713. }
  1714. pWorkspace->PerformClick(m_hWnd, point);
  1715. break;
  1716. }
  1717. }
  1718. }
  1719. void CXTPTabClientWnd::InitLoop()
  1720. {
  1721. // handle pending WM_PAINT messages
  1722. MSG msg;
  1723. while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
  1724. {
  1725. if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
  1726. return;
  1727. DispatchMessage(&msg);
  1728. }
  1729. // initialize state
  1730. m_rectLast.SetRectEmpty();
  1731. m_sizeLast.cx = m_sizeLast.cy = 0;
  1732. m_rcGroup.SetRectEmpty();
  1733. m_pFocusWorkspace = NULL;
  1734. // lock window update while dragging
  1735. ASSERT(m_pDC == NULL);
  1736. CWnd* pWnd = CWnd::GetDesktopWindow();
  1737. if (pWnd->LockWindowUpdate())
  1738. m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
  1739. else
  1740. m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
  1741. ASSERT(m_pDC != NULL);
  1742. }
  1743. void CXTPTabClientWnd::CancelLoop()
  1744. {
  1745. DrawFocusRect(TRUE);    // gets rid of focus rect
  1746. CWnd* pWnd = CWnd::GetDesktopWindow();
  1747. pWnd->UnlockWindowUpdate();
  1748. if (m_pDC != NULL)
  1749. {
  1750. pWnd->ReleaseDC(m_pDC);
  1751. m_pDC = NULL;
  1752. }
  1753. }
  1754. void CXTPTabClientWnd::DrawFocusRect(BOOL bRemoveRect)
  1755. {
  1756. ASSERT(m_pDC != NULL);
  1757. if (!m_pDC)
  1758. return;
  1759. // determine new rect and size
  1760. CBrush* pDitherBrush = CDC::GetHalftoneBrush();
  1761. CRect rect = m_rcGroup;
  1762. ClientToScreen(rect);
  1763. CSize size(GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
  1764. if (bRemoveRect)
  1765. size.cx = size.cy = 0;
  1766. // draw it and remember last size
  1767. m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
  1768. pDitherBrush, pDitherBrush);
  1769. m_rectLast = rect;
  1770. m_sizeLast = size;
  1771. }
  1772. void CXTPTabClientWnd::ReorderWorkspace(CPoint pt, CXTPTabManagerItem* pItem)
  1773. {
  1774. CXTPClientRect rc(this);
  1775. CRect rcGroup(0, 0, 0, 0);
  1776. m_pFocusWorkspace = NULL;
  1777. m_nFocusedAction = ACTION_CANCEL;
  1778. if (rc.PtInRect(pt))
  1779. {
  1780. m_nFocusedAction = ACTION_POPUP;
  1781. ::SetCursor(m_hCursorNew);
  1782. for (int i = 0; i < GetWorkspaceCount(); i++)
  1783. {
  1784. CWorkspace* pWorkspace = GetWorkspace(i);
  1785. BOOL bSelfAvail = pItem->GetTabManager() != pWorkspace || pWorkspace->GetItemCount() > 1;
  1786. if (pWorkspace->GetHeaderRect().PtInRect(pt))
  1787. {
  1788. rcGroup = pWorkspace->GetClientRect();
  1789. m_pFocusWorkspace = pWorkspace;
  1790. m_nFocusedAction = ACTION_ATTACH;
  1791. break;
  1792. }
  1793. if ((GetWorkspaceCount() == 1 || m_bHorizSplitting) && bSelfAvail)
  1794. {
  1795. int nOffset = pWorkspace->GetControlRect().bottom - pt.y;
  1796. if (nOffset > 0 && nOffset < 30)
  1797. {
  1798. rcGroup = pWorkspace->GetControlRect();
  1799. rcGroup.top = rcGroup.CenterPoint().y;
  1800. m_pFocusWorkspace = pWorkspace;
  1801. m_nFocusedAction = ACTION_INSERTHORIZ;
  1802. break;
  1803. }
  1804. }
  1805. if ((GetWorkspaceCount() == 1 || !m_bHorizSplitting) && bSelfAvail)
  1806. {
  1807. int nOffset = pWorkspace->GetControlRect().right - pt.x;
  1808. if (nOffset > 0 && nOffset < 30)
  1809. {
  1810. rcGroup = pWorkspace->GetControlRect();
  1811. rcGroup.left = rcGroup.CenterPoint().x;
  1812. m_pFocusWorkspace = pWorkspace;
  1813. m_nFocusedAction = ACTION_INSERTVERT;
  1814. break;
  1815. }
  1816. }
  1817. }
  1818. }
  1819. else
  1820. {
  1821. ::SetCursor(m_hCursorDelete);
  1822. }
  1823. if (m_rcGroup != rcGroup)
  1824. {
  1825. m_rcGroup = rcGroup;
  1826. DrawFocusRect();
  1827. }
  1828. }
  1829. int CXTPTabClientWnd::FindIndex(CXTPTabManager* pWorkspace) const
  1830. {
  1831. for (int i = 0; i < GetWorkspaceCount(); i++)
  1832. {
  1833. if (GetWorkspace(i) == pWorkspace)
  1834. return i;
  1835. }
  1836. return -1;
  1837. }
  1838. CXTPTabManagerItem* CXTPTabClientWnd::HitTest(CPoint pt) const
  1839. {
  1840. if (!m_bShowWorkspace)
  1841. return NULL;
  1842. for (int i = 0; i < GetWorkspaceCount(); i++)
  1843. {
  1844. CXTPTabManagerItem* pItem = GetWorkspace(i)->HitTest(pt);
  1845. if (pItem)
  1846. return pItem;
  1847. }
  1848. return NULL;
  1849. }
  1850. CXTPCommandBars* CXTPTabClientWnd::GetCommandBars() const
  1851. {
  1852. if (!m_pParentFrame)
  1853. return NULL;
  1854. return ((CXTPMDIFrameWnd*)m_pParentFrame)->GetCommandBars();
  1855. }
  1856. void CXTPTabClientWnd::ContextMenu(CPoint pt)
  1857. {
  1858. CXTPPopupBar* pPopupBar = CXTPPopupBar::CreatePopupBar(GetCommandBars());
  1859. ClientToScreen(&pt);
  1860. pPopupBar->GetControls()->Add(new CXTPControlWorkspaceActions, 0);
  1861. CXTPControl* pControl = pPopupBar->GetControls()->Add(xtpControlButton, XTP_ID_WORKSPACE_CANCEL);
  1862. pControl->SetBeginGroup(TRUE);
  1863. pControl->SetFlags(xtpFlagManualUpdate);
  1864. CXTPCommandBars::TrackPopupMenu(pPopupBar, 0, pt.x, pt.y, GetParentFrame());
  1865. pPopupBar->InternalRelease();
  1866. }
  1867. void CXTPTabClientWnd::OnWorkspaceCommand(UINT nID)
  1868. {
  1869. CXTPTabManagerItem* pItem = NULL;
  1870. if (!IsWorkspaceCommandEnabled(nID, &pItem))
  1871. return;
  1872. ASSERT(pItem);
  1873. if (!pItem)
  1874. return;
  1875. switch (nID)
  1876. {
  1877. case XTP_ID_WORKSPACE_NEWVERTICAL:
  1878. DoWorkspaceCommand(pItem, (CWorkspace*)pItem->GetTabManager(), ACTION_INSERTVERT);
  1879. break;
  1880. case XTP_ID_WORKSPACE_NEWHORIZONTAL:
  1881. DoWorkspaceCommand(pItem, (CWorkspace*)pItem->GetTabManager(), ACTION_INSERTHORIZ);
  1882. break;
  1883. case XTP_ID_WORKSPACE_MOVEPREVIOUS:
  1884. {
  1885. int nIndex = FindIndex(pItem->GetTabManager());
  1886. DoWorkspaceCommand(pItem, GetWorkspace(nIndex - 1), ACTION_ATTACH);
  1887. }
  1888. break;
  1889. case XTP_ID_WORKSPACE_MOVENEXT:
  1890. {
  1891. int nIndex = FindIndex(pItem->GetTabManager());
  1892. DoWorkspaceCommand(pItem, GetWorkspace(nIndex + 1), ACTION_ATTACH);
  1893. }
  1894. break;
  1895. }
  1896. }
  1897. void CXTPTabClientWnd::OnUpdateWorkspaceCommand(CCmdUI* pCmdUI)
  1898. {
  1899. pCmdUI->Enable(IsWorkspaceCommandEnabled(pCmdUI->m_nID));
  1900. }
  1901. BOOL CXTPTabClientWnd::IsWorkspaceCommandEnabled(UINT nID, CXTPTabManagerItem** ppItem)
  1902. {
  1903. if (!m_bEnableGroups)
  1904. return FALSE;
  1905. CWnd* pWnd = MDIGetActive();
  1906. if (!pWnd)
  1907. return FALSE;
  1908. CXTPTabManagerItem* pItem = FindItem(pWnd->GetSafeHwnd());
  1909. if (!pItem)
  1910. return FALSE;
  1911. if (ppItem)
  1912. *ppItem = pItem;
  1913. switch (nID)
  1914. {
  1915. case XTP_ID_WORKSPACE_NEWVERTICAL:
  1916. return (GetWorkspaceCount() == 1 || !m_bHorizSplitting) && pItem->GetTabManager()->GetItemCount() > 1;
  1917. case XTP_ID_WORKSPACE_NEWHORIZONTAL:
  1918. return (GetWorkspaceCount() == 1 || m_bHorizSplitting) && pItem->GetTabManager()->GetItemCount() > 1;
  1919. case XTP_ID_WORKSPACE_MOVEPREVIOUS:
  1920. return FindIndex(pItem->GetTabManager()) != 0;
  1921. case XTP_ID_WORKSPACE_MOVENEXT:
  1922. return FindIndex(pItem->GetTabManager()) != GetWorkspaceCount() - 1;
  1923. }
  1924. return TRUE;
  1925. }
  1926. void CXTPTabClientWnd::MDITile(BOOL bHorizontal)
  1927. {
  1928. if (!m_bEnableGroups || m_bUserWorkspace)
  1929. return;
  1930. if (GetItemCount() < 2)
  1931. return;
  1932. m_bLockUpdate = m_bLockReposition = TRUE;
  1933. CArray<CXTPTabManagerItem*, CXTPTabManagerItem*> arrItems;
  1934. while (GetWorkspaceCount() > 0)
  1935. {
  1936. CWorkspace* pWorkspace = GetWorkspace(0);
  1937. for (int j = 0; j < pWorkspace->GetItemCount(); j++)
  1938. {
  1939. CXTPTabManagerItem* pItem = pWorkspace->GetItem(j);
  1940. arrItems.Add(pItem);
  1941. pItem->InternalAddRef();
  1942. }
  1943. m_arrWorkspace.RemoveAt(0);
  1944. delete pWorkspace;
  1945. }
  1946. for (int i = 0; i < (int)arrItems.GetSize(); i++)
  1947. {
  1948. CXTPTabManagerItem* pItem = arrItems[i];
  1949. COLORREF clr = pItem->m_clrItem;
  1950. CWorkspace* pWorkspace = AddWorkspace(i);
  1951. pWorkspace->CXTPTabManager::AddItem(-1, pItem);
  1952. pItem->m_clrItem = clr;
  1953. pWorkspace->SetSelectedItem(pItem);
  1954. pWorkspace->m_dHeight = 100;
  1955. }
  1956. m_pActiveWorkspace = NULL;
  1957. m_bHorizSplitting = bHorizontal;
  1958. m_bLockUpdate = m_bLockReposition = FALSE;
  1959. m_bForceToRecalc = TRUE;
  1960. UpdateContents();
  1961. NormalizeWorkspaceSize();
  1962. }
  1963. void CXTPTabClientWnd::DoWorkspaceCommand(CXTPTabManagerItem* pItem, CWorkspace* pFocusWorkspace, int nAction)
  1964. {
  1965. m_bLockUpdate = m_bLockReposition = TRUE;
  1966. CWorkspace* pOldWorkspace = NULL;
  1967. switch (nAction)
  1968. {
  1969. case ACTION_ATTACH:
  1970. {
  1971. ASSERT(pFocusWorkspace);
  1972. if (!pFocusWorkspace)
  1973. return;
  1974. if (pFocusWorkspace != pItem->GetTabManager())
  1975. {
  1976. pOldWorkspace = (CWorkspace*)pItem->GetTabManager();
  1977. pItem->InternalAddRef();
  1978. pItem->Remove();
  1979. COLORREF clr = pItem->m_clrItem;
  1980. pFocusWorkspace->CXTPTabManager::AddItem(-1, pItem);
  1981. pItem->m_clrItem = clr;
  1982. }
  1983. pFocusWorkspace->SetSelectedItem(pItem);
  1984. break;
  1985. }
  1986. case ACTION_INSERTHORIZ:
  1987. case ACTION_INSERTVERT:
  1988. {
  1989. NormalizeWorkspaceSize();
  1990. ASSERT(pFocusWorkspace);
  1991. if (!pFocusWorkspace)
  1992. return;
  1993. pOldWorkspace = (CWorkspace*)pItem->GetTabManager();
  1994. pItem->InternalAddRef();
  1995. pItem->Remove();
  1996. COLORREF clr = pItem->m_clrItem;
  1997. int nIndex = FindIndex(pFocusWorkspace) + 1;
  1998. CWorkspace* pWorkspace = AddWorkspace(nIndex);
  1999. pWorkspace->CXTPTabManager::AddItem(-1, pItem);
  2000. pItem->m_clrItem = clr;
  2001. pWorkspace->SetSelectedItem(pItem);
  2002. pWorkspace->m_dHeight = (pFocusWorkspace->m_dHeight - m_nSplitterSize) / 2;
  2003. pFocusWorkspace->m_dHeight = pFocusWorkspace->m_dHeight - pWorkspace->m_dHeight - m_nSplitterSize;
  2004. m_bHorizSplitting = (nAction == ACTION_INSERTHORIZ);
  2005. break;
  2006. }
  2007. }
  2008. if (pOldWorkspace && pOldWorkspace->GetItemCount() > 1)
  2009. {
  2010. HWND hWndChild = ::GetWindow(m_hWnd, GW_CHILD);
  2011. while (hWndChild)
  2012. {
  2013. CXTPTabManagerItem* pItemOld = FindItem(hWndChild);
  2014. if (pItemOld && pItemOld->GetTabManager() == pOldWorkspace)
  2015. {
  2016. pOldWorkspace->SetSelectedItem(pItemOld);
  2017. break;
  2018. }
  2019. hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT);
  2020. }
  2021. }
  2022. m_bLockUpdate = m_bLockReposition = FALSE;
  2023. m_bForceToRecalc = TRUE;
  2024. UpdateContents();
  2025. }
  2026. void CXTPTabClientWnd::OnMouseMove(UINT nFlags, CPoint point)
  2027. {
  2028. if (m_bEnableGroups)
  2029. {
  2030. for (int i = 0; i < GetWorkspaceCount(); i++)
  2031. {
  2032. GetWorkspace(i)->PerformMouseMove(m_hWnd, point);
  2033. }
  2034. }
  2035. CWnd::OnMouseMove(nFlags, point);
  2036. }
  2037. void CXTPTabClientWnd::OnMouseLeave()
  2038. {
  2039. if (m_bEnableGroups)
  2040. {
  2041. for (int i = 0; i < GetWorkspaceCount(); i++)
  2042. {
  2043. GetWorkspace(i)->PerformMouseMove(m_hWnd, CPoint(-1, -1));
  2044. }
  2045. }
  2046. }
  2047. void CXTPTabClientWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
  2048. {
  2049. OnLButtonDown(nFlags, point);
  2050. }
  2051. void CXTPTabClientWnd::OnSysColorChange()
  2052. {
  2053. CWnd::OnSysColorChange();
  2054. GetPaintManager()->RefreshMetrics();
  2055. Refresh();
  2056. }
  2057. BOOL CXTPTabClientWnd::PreTranslateMessage(MSG* pMsg)
  2058. {
  2059. if (m_bEnableGroups)
  2060. {
  2061. if (pMsg->message == WM_LBUTTONDOWN ||
  2062. pMsg->message == WM_RBUTTONDOWN ||
  2063. pMsg->message == WM_MBUTTONDOWN ||
  2064. pMsg->message == WM_LBUTTONDBLCLK ||
  2065. pMsg->message == WM_RBUTTONDBLCLK)
  2066. {
  2067. if (pMsg->hwnd != m_hWnd)
  2068. return CWnd::PreTranslateMessage(pMsg);
  2069. if (GetParentFrame()->SendMessage(WM_XTP_PRETRANSLATEMOUSEMSG, (WPARAM)pMsg->message, pMsg->lParam))
  2070. return TRUE;
  2071. }
  2072. }
  2073. return CWnd::PreTranslateMessage(pMsg);
  2074. }
  2075. CXTPTabPaintManager* CXTPTabClientWnd::GetPaintManager() const
  2076. {
  2077. return m_pPaintManager;
  2078. }
  2079. void CXTPTabClientWnd::SetPaintManager(CXTPTabPaintManager* pPaintManager)
  2080. {
  2081. m_pPaintManager->InternalRelease();
  2082. m_pPaintManager = pPaintManager;
  2083. m_pPaintManager->RefreshMetrics();
  2084. m_themeCommandBars = xtpThemeCustom;
  2085. m_bAutoTheme = FALSE;
  2086. Refresh();
  2087. }
  2088. void CXTPTabClientWnd::SetAutoTheme(BOOL bAutoTheme /*= FALSE*/)
  2089. {
  2090. m_bAutoTheme = bAutoTheme;
  2091. }
  2092. BOOL CXTPTabClientWnd::GetAutoTheme() const
  2093. {
  2094. return m_bAutoTheme;
  2095. }
  2096. void CXTPTabClientWnd::UpdateFlags(CWorkspace* pWorkspace)
  2097. {
  2098. pWorkspace->FindNavigateButton(xtpTabNavigateButtonClose)->SetFlags(
  2099. m_dwFlags & xtpWorkspaceHideClose ? xtpTabNavigateButtonNone : xtpTabNavigateButtonAutomatic);
  2100. pWorkspace->FindNavigateButton(xtpTabNavigateButtonActiveFiles)->SetFlags(
  2101. m_dwFlags & xtpWorkspaceShowActiveFiles ? xtpTabNavigateButtonAlways : xtpTabNavigateButtonNone);
  2102. pWorkspace->FindNavigateButton(xtpTabNavigateButtonLeft)->SetFlags((m_dwFlags & xtpWorkspaceHideArrowsAlways) == xtpWorkspaceHideArrowsAlways ? xtpTabNavigateButtonNone :
  2103. m_dwFlags & xtpWorkspaceHideArrows ? xtpTabNavigateButtonAutomatic : xtpTabNavigateButtonAlways);
  2104. pWorkspace->FindNavigateButton(xtpTabNavigateButtonRight)->SetFlags((m_dwFlags & xtpWorkspaceHideArrowsAlways) == xtpWorkspaceHideArrowsAlways ? xtpTabNavigateButtonNone :
  2105. m_dwFlags & xtpWorkspaceHideArrows ? xtpTabNavigateButtonAutomatic : xtpTabNavigateButtonAlways);
  2106. if (m_dwFlags & xtpWorkspaceShowCloseTab || m_dwFlags & xtpWorkspaceShowCloseSelectedTab)
  2107. {
  2108. pWorkspace->ShowCloseItemButton(m_dwFlags & xtpWorkspaceShowCloseSelectedTab ?
  2109. xtpTabNavigateButtonAutomatic : xtpTabNavigateButtonAlways);
  2110. }
  2111. }
  2112. void CXTPTabClientWnd::SetFlags(DWORD dwFlags)
  2113. {
  2114. m_dwFlags = dwFlags;
  2115. for (int i = 0; i < GetWorkspaceCount(); i++)
  2116. UpdateFlags(GetWorkspace(i));
  2117. Reposition();
  2118. }
  2119. void CXTPTabClientWnd::Reposition()
  2120. {
  2121. m_bForceToRecalc = FALSE;
  2122. if (m_pTabWorkspace)
  2123. {
  2124. m_pTabWorkspace->OnRecalcLayout();
  2125. }
  2126. else if (!m_bUserWorkspace)
  2127. {
  2128. GetParentFrame()->RecalcLayout();
  2129. }
  2130. }
  2131. BOOL CXTPTabClientWnd::IsAllowReorder() const
  2132. {
  2133. return m_bAllowReorder;
  2134. }
  2135. void CXTPTabClientWnd::SetAllowReorder(BOOL bAllowReorder)
  2136. {
  2137. m_bAllowReorder = bAllowReorder;
  2138. }
  2139. CXTPTabManagerItem* CXTPTabClientWnd::GetSelectedItem () const
  2140. {
  2141. if (m_pActiveWorkspace)
  2142. return m_pActiveWorkspace->GetSelectedItem();
  2143. return NULL;
  2144. }
  2145. CXTPTabManagerItem* CXTPTabClientWnd::GetItem(int nIndex) const
  2146. {
  2147. for (int i = 0; i < GetWorkspaceCount(); i++)
  2148. {
  2149. CWorkspace* pWorkspace = GetWorkspace(i);
  2150. int nCount = pWorkspace->GetItemCount();
  2151. if (nIndex < nCount)
  2152. return pWorkspace->GetItem(nIndex);
  2153. nIndex -= nCount;
  2154. }
  2155. return NULL;
  2156. }
  2157. int CXTPTabClientWnd::GetItemCount() const
  2158. {
  2159. int nCount = 0;
  2160. for (int i = 0; i < GetWorkspaceCount(); i++)
  2161. nCount += GetWorkspace(i)->GetItemCount();
  2162. return nCount;
  2163. }
  2164. LRESULT CXTPTabClientWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  2165. {
  2166. if (m_bEnableGroups && IsAttached())
  2167. {
  2168. m_pToolTipContext->FilterToolTipMessage(this, message, wParam, lParam);
  2169. }
  2170. if (message == m_nMsgQuerySkinState && m_bEnableGroups && IsAttached())
  2171. {
  2172. return TRUE;
  2173. }
  2174. if (!m_bEnableGroups && (message == WM_MDIICONARRANGE || message == WM_MDICASCADE
  2175. || message == WM_MDITILE) && GetCommandBars())
  2176. {
  2177. XTPPaintTheme theme = GetCommandBars()->GetPaintManager()->BaseTheme();
  2178. if (theme == xtpThemeOffice2007 || theme == xtpThemeRibbon)
  2179. {
  2180. CArray<HWND, HWND&> arrChildren;
  2181. HWND hWnd = ::GetWindow(m_hWnd, GW_CHILD);
  2182. while (hWnd)
  2183. {
  2184. if ((GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_MDICHILD)
  2185. && ((GetWindowLong(hWnd, GWL_STYLE) & WS_CAPTION) != WS_CAPTION))
  2186. {
  2187. CWnd::ModifyStyle(hWnd, 0, WS_CAPTION, 0);
  2188. arrChildren.Add(hWnd);
  2189. }
  2190. hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
  2191. }
  2192. LRESULT lResult = CWnd::WindowProc(message, wParam, lParam);
  2193. for (int i = 0; i < (int)arrChildren.GetSize(); i++)
  2194. {
  2195. CWnd::ModifyStyle(arrChildren[i], WS_CAPTION, 0, 0);
  2196. }
  2197. return lResult;
  2198. }
  2199. }
  2200. return CWnd::WindowProc(message, wParam, lParam);
  2201. }
  2202. void CXTPTabClientWnd::SetTabWorkspace(CWorkspace* pWorkspace)
  2203. {
  2204. ASSERT(!m_bEnableGroups);
  2205. m_pTabWorkspace = pWorkspace;
  2206. m_bUserWorkspace = pWorkspace != NULL;
  2207. if (pWorkspace) pWorkspace->m_pTabClientWnd = this;
  2208. }