ViewManager.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. // VViewManager.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "resource.h" // main symbols
  5. #include "ViewManager.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. #define ID_VIEWTAB 1005
  12. #define ID_DEFDOCTIPS _T("A new unsaved file")
  13. #define ID_DEFCAPTION _T("Open File Tabs Bar")
  14. #define ID_TABHEIGHT 26
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CVViewManager
  17. IMPLEMENT_DYNAMIC(CViewManager, CControlBar)
  18. CViewManager::CViewManager()
  19. {
  20. m_bClosing = FALSE;
  21. m_nLMargin = 10;
  22. m_nDockID = 0;
  23. }
  24. CViewManager::~CViewManager()
  25. {
  26. m_arViews.RemoveAll();
  27. m_arViewTitles.RemoveAll();
  28. }
  29. BEGIN_MESSAGE_MAP(CViewManager, CControlBar)
  30. ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnViewManagerToolTip)
  31. //{{AFX_MSG_MAP(CViewManager)
  32. ON_WM_SIZE()
  33. ON_WM_CREATE()
  34. ON_WM_RBUTTONDOWN()
  35. ON_WM_WINDOWPOSCHANGING()
  36. //}}AFX_MSG_MAP
  37. END_MESSAGE_MAP()
  38. void CViewManager::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
  39. {
  40. CMDIFrameWnd* pFrame = static_cast<CMDIFrameWnd *>(AfxGetApp()->m_pMainWnd);
  41. if (pFrame == NULL)
  42. return; // this is not meant for us...
  43. // Get the active MDI child window.
  44. CMDIChildWnd* pChild = static_cast<CMDIChildWnd *>(pFrame->GetActiveFrame());
  45. // Get the active view attached to the active MDI child window.
  46. CView* pActiveView = reinterpret_cast<CView *>(pChild->GetActiveView());
  47. if (pActiveView == NULL) //...Is there a view anyway?
  48. {
  49. //...since there is no view hide the tab control, otherwise it looks...guess!
  50. m_ViewTabCtrl.ShowWindow(SW_HIDE);
  51. return;
  52. }
  53. else
  54. {
  55. //...we might have hidden the tab control, show it now
  56. if (!m_ViewTabCtrl.IsWindowVisible())
  57. m_ViewTabCtrl.ShowWindow(SW_SHOW);
  58. }
  59. // Now, we go...
  60. int iSel = -1;
  61. CString strWin;
  62. for (int t = 0; t < m_arViewTitles.GetSize(); t++)
  63. {
  64. CView* pViewAt = static_cast<CView *>(m_arViews.GetAt(t));
  65. pViewAt->GetParent()->GetWindowText(strWin);
  66. // ...if there is window title change since the last update set the new title
  67. if (strWin != m_arViewTitles.GetAt(t))
  68. SetViewName(strWin, pViewAt);
  69. // ...find the active view from the view list
  70. if (pActiveView == static_cast<CView *>(m_arViews.GetAt(t)))
  71. iSel = t;
  72. }
  73. m_ViewTabCtrl.SetCurSel(iSel); // set the tab for the active view
  74. // Be polite! update the dialog controls added to the CSizingControlBar
  75. UpdateDialogControls(pTarget, bDisableIfNoHndler);
  76. }
  77. ////////////////////////////////////////////////////////////////////////////
  78. // CViewManager operations
  79. void CViewManager::AddView(const TCHAR* csName, CView* pView)
  80. {
  81. if (m_bClosing)
  82. return;
  83. CString cs(csName);
  84. m_arViews.Add(pView);
  85. m_arViewTitles.Add(cs);
  86. if (m_ViewTabCtrl.GetSafeHwnd())
  87. {
  88. TCITEM tci;
  89. tci.mask = TCIF_TEXT | TCIF_PARAM | TCIF_IMAGE;
  90. tci.pszText = cs.LockBuffer();
  91. tci.lParam = reinterpret_cast<LPARAM>(pView);
  92. tci.iImage = 0; //TODO
  93. m_ViewTabCtrl.InsertItem(m_ViewTabCtrl.GetItemCount(), &tci);
  94. cs.UnlockBuffer();
  95. }
  96. }
  97. void CViewManager::RemoveView(CView* pView)
  98. {
  99. if (m_bClosing || m_arViews.GetSize() <= 0)
  100. return;
  101. int nTabs;
  102. if (m_ViewTabCtrl.GetSafeHwnd())
  103. {
  104. for (nTabs = 0; nTabs < m_ViewTabCtrl.GetItemCount(); nTabs++)
  105. {
  106. TCITEM tci;
  107. tci.mask = TCIF_PARAM;
  108. m_ViewTabCtrl.GetItem(nTabs, &tci);
  109. if (tci.lParam == reinterpret_cast<LPARAM>(pView))
  110. {
  111. m_ViewTabCtrl.DeleteItem(nTabs);
  112. break;
  113. }
  114. }
  115. }
  116. for (nTabs = 0; nTabs < m_arViews.GetSize(); nTabs++)
  117. {
  118. if (static_cast<CView *>(m_arViews.GetAt(nTabs)) == pView)
  119. {
  120. m_arViewTitles.RemoveAt(nTabs);
  121. m_arViews.RemoveAt(nTabs);
  122. return;
  123. }
  124. }
  125. }
  126. void CViewManager::RemoveAll()
  127. {
  128. m_arViews.RemoveAll();
  129. m_arViewTitles.RemoveAll();
  130. }
  131. void CViewManager::SetViewName(const TCHAR* cs, CView* pView)
  132. {
  133. if (m_bClosing || m_arViews.GetSize() <= 0)
  134. return;
  135. int nTabs;
  136. CString csName(cs);
  137. if (m_ViewTabCtrl.GetSafeHwnd())
  138. {
  139. for (nTabs = 0; nTabs < m_ViewTabCtrl.GetItemCount(); nTabs++)
  140. {
  141. TCITEM tci;
  142. tci.mask = TCIF_PARAM;
  143. m_ViewTabCtrl.GetItem(nTabs, &tci);
  144. if (tci.lParam == reinterpret_cast<LPARAM>(pView))
  145. {
  146. tci.mask = TCIF_PARAM | TCIF_TEXT;
  147. tci.pszText = csName.LockBuffer();
  148. m_ViewTabCtrl.SetItem(nTabs, &tci);
  149. csName.UnlockBuffer();
  150. m_ViewTabCtrl.Invalidate();
  151. break;
  152. }
  153. }
  154. }
  155. for (nTabs = 0; nTabs < m_arViews.GetSize(); nTabs++)
  156. {
  157. if (static_cast<CView *>(m_arViews.GetAt(nTabs)) == pView)
  158. {
  159. m_arViewTitles.SetAt(nTabs, csName);
  160. return;
  161. }
  162. }
  163. }
  164. int CViewManager::GetWindowNum()
  165. {
  166. return m_arViews.GetSize();
  167. }
  168. void CViewManager::OnActivateView(const BOOL bActivate, CView* pView)
  169. {
  170. if (bActivate)
  171. {
  172. if (m_ViewTabCtrl.GetSafeHwnd())
  173. {
  174. for (int nTabs = 0; nTabs < m_ViewTabCtrl.GetItemCount(); nTabs++)
  175. {
  176. TCITEM tci;
  177. tci.mask = TCIF_PARAM;
  178. m_ViewTabCtrl.GetItem(nTabs, &tci);
  179. if (tci.lParam == reinterpret_cast<LPARAM>(pView))
  180. {
  181. m_ViewTabCtrl.SetCurSel(nTabs);
  182. m_ViewTabCtrl.Invalidate();
  183. break;
  184. }
  185. }
  186. }
  187. }
  188. }
  189. /////////////////////////////////////////////////////////////////////////////
  190. // CViewManager message handlers
  191. void CViewManager::OnSize(UINT nType, int cx, int cy)
  192. {
  193. CControlBar::OnSize(nType, cx, cy);
  194. CRect rect, rcClient;
  195. if (m_ViewTabCtrl.GetSafeHwnd())
  196. {
  197. DWORD dwStyle = m_ViewTabCtrl.GetStyle();
  198. if (dwStyle & TCS_BOTTOM)
  199. {
  200. GetClientRect(rect);
  201. GetClientRect(rcClient);
  202. int nxOffset = GetSystemMetrics(SM_CXSIZEFRAME);
  203. m_ViewTabCtrl.SetWindowPos(&wndTop, rcClient.left + nxOffset + m_nLMargin,
  204. rcClient.top, rect.Width() - nxOffset * 5 - m_nLMargin,
  205. ID_TABHEIGHT, SWP_SHOWWINDOW);
  206. m_sizeMRU = CSize(cx, cy);
  207. }
  208. else
  209. {
  210. GetClientRect(rect);
  211. int nxOffset = GetSystemMetrics(SM_CXSIZEFRAME);
  212. m_ViewTabCtrl.SetWindowPos(&wndTop, nxOffset + m_nLMargin, 3,
  213. rect.Width() - nxOffset * 5 - m_nLMargin, ID_TABHEIGHT, SWP_SHOWWINDOW);
  214. m_sizeMRU = CSize(cx, cy);
  215. }
  216. }
  217. }
  218. int CViewManager::OnCreate(LPCREATESTRUCT lpCreateStruct)
  219. {
  220. if (CControlBar::OnCreate(lpCreateStruct) == -1)
  221. return -1;
  222. m_ViewTabImages.Create(16, 16, ILC_MASK, 5, 5);
  223. m_ViewTabCtrl.Create(WS_CHILD | WS_VISIBLE | WS_EX_NOPARENTNOTIFY |
  224. // TCS_BUTTONS | TCS_FLATBUTTONS | // pLaY with this!
  225. TCS_TOOLTIPS | TCS_SINGLELINE | TCS_FOCUSNEVER | TCS_FORCELABELLEFT,
  226. CRect(0, 0, 0, 0), this, ID_VIEWTAB);
  227. TabCtrl_SetExtendedStyle(m_ViewTabCtrl.m_hWnd, TCS_EX_FLATSEPARATORS);
  228. m_ViewTabCtrl.SetImageList(&m_ViewTabImages);
  229. // Build the image list here
  230. HICON hIcon = AfxGetApp()->LoadStandardIcon(IDI_APPLICATION);
  231. // HICON hIcon = AfxGetApp()->LoadIcon(IDR_DEMOTYPE);
  232. m_ViewTabImages.Add(hIcon);
  233. // Enable tooltips for all controls
  234. EnableToolTips(TRUE);
  235. return 0;
  236. }
  237. void CViewManager::OnRButtonDown(UINT nFlags, CPoint point)
  238. {
  239. // TODO: Add your message handler code here and/or call default
  240. POINT ptScreen = point;
  241. // Convert the mouse point to screen coordinates since that is what is used by
  242. // the TrackPopupMenu() function.
  243. ClientToScreen(&ptScreen);
  244. CControlBar::OnRButtonDown(nFlags, point);
  245. }
  246. //
  247. // This function adds a title entry to a popup menu
  248. //
  249. void AddMenuTitle(CMenu* popup, LPCSTR title)
  250. {
  251. // insert a separator item at the top
  252. popup->InsertMenu(0, MF_BYPOSITION | MF_SEPARATOR, 0, title);
  253. // insert title item
  254. // note: item is not selectable (disabled) but not grayed
  255. popup->InsertMenu(0, MF_BYPOSITION | MF_STRING | MF_DISABLED, 0, title);
  256. SetMenuDefaultItem(popup->m_hMenu, 0, TRUE);
  257. }
  258. BOOL CViewManager::OnViewManagerToolTip(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
  259. {
  260. UNREFERENCED_PARAMETER(id); // clear that level 4 warning...
  261. *pResult = 0;
  262. TCHITTESTINFO hti;
  263. TOOLTIPTEXT *pTTT = reinterpret_cast<TOOLTIPTEXT *>(pNMHDR);
  264. UINT nID = pNMHDR->idFrom;
  265. // if there are some dialog controls, progress the tooltips
  266. if (pTTT->uFlags & TTF_IDISHWND)
  267. {
  268. // idFrom is actually the HWND of the tool
  269. nID = ::GetDlgCtrlID((HWND)nID);
  270. if (nID)
  271. {
  272. pTTT->lpszText = MAKEINTRESOURCE(nID);
  273. pTTT->hinst = ::AfxGetResourceHandle();
  274. return TRUE;
  275. }
  276. }
  277. // Now, address the view tab tooltips
  278. hti.pt = CPoint(GetMessagePos());
  279. m_ViewTabCtrl.ScreenToClient(&hti.pt);
  280. return FALSE;
  281. }
  282. BOOL CViewManager::CreateViewManager(CMDIFrameWnd *pMDIFrameWnd, UINT uID)
  283. {
  284. if (!Create(ID_DEFCAPTION, pMDIFrameWnd, m_sizeDefault, uID))
  285. {
  286. TRACE0(_T("Failed to create Tab bar\n"));
  287. return FALSE; // fail to create
  288. }
  289. SetBarStyle(GetBarStyle() | CBRS_TOP |
  290. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  291. EnableDocking(CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM);
  292. pMDIFrameWnd->DockControlBar(this);
  293. return TRUE;
  294. }
  295. BOOL CViewManager::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd,
  296. CSize sizeDefault, UINT nID, DWORD dwStyle)
  297. {
  298. // must have a parent
  299. ASSERT_VALID(pParentWnd);
  300. // cannot be both fixed and dynamic
  301. // (CBRS_SIZE_DYNAMIC is used for resizng when floating)
  302. ASSERT (!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)));
  303. m_dwStyle = dwStyle & CBRS_ALL; // save the control bar styles
  304. m_sizeDefault = sizeDefault; // set fixed size
  305. m_sizeMRU = sizeDefault;
  306. // register and create the window - skip CControlBar::Create()
  307. CString strWndclass = ::AfxRegisterWndClass(CS_DBLCLKS,
  308. ::LoadCursor(NULL, IDC_ARROW), ::GetSysColorBrush(COLOR_BTNFACE), 0);
  309. dwStyle &= ~CBRS_ALL;
  310. dwStyle |= WS_CLIPCHILDREN | CCS_NOPARENTALIGN | CCS_NOMOVEY | CCS_NORESIZE;
  311. if (!CWnd::Create(strWndclass, lpszWindowName, dwStyle,
  312. CRect(0, 0, 0, 0), pParentWnd, nID))
  313. return FALSE;
  314. return TRUE;
  315. }
  316. CSize CViewManager::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  317. {
  318. ASSERT_VALID(this);
  319. ASSERT(::IsWindow(m_hWnd));
  320. if (bStretch) // if not docked stretch to fit
  321. return CSize(bHorz ? 32767 : m_sizeDefault.cx, bHorz ? m_sizeDefault.cy : 32767);
  322. CClientDC dc(NULL);
  323. HFONT hFont = reinterpret_cast<HFONT>(SendMessage(WM_GETFONT));
  324. HFONT hOldFont = NULL;
  325. if (hFont != NULL)
  326. hOldFont = reinterpret_cast<HFONT>(dc.SelectObject(hFont));
  327. TEXTMETRIC tm;
  328. VERIFY(dc.GetTextMetrics(&tm));
  329. if (hOldFont != NULL)
  330. dc.SelectObject(hOldFont);
  331. // get border information
  332. CSize size;
  333. CRect rcInside, rcWnd;
  334. rcInside.SetRectEmpty();
  335. CalcInsideRect(rcInside, bHorz);
  336. GetParentFrame()->GetWindowRect(&rcWnd);
  337. size.cx = rcWnd.Width();
  338. size.cy = tm.tmHeight + tm.tmInternalLeading/* - 1 */+
  339. ::GetSystemMetrics(SM_CYBORDER) * 5 - rcInside.Height();
  340. return size;
  341. }
  342. CSize CViewManager::CalcDynamicLayout(int nLength, DWORD dwMode)
  343. {
  344. UNREFERENCED_PARAMETER(nLength); // clear that level 4 warning...
  345. if (dwMode & LM_HORZDOCK)
  346. {
  347. ASSERT(dwMode & LM_HORZ);
  348. return CalcFixedLayout(dwMode & LM_STRETCH, dwMode & LM_HORZ);
  349. }
  350. if (m_sizeMRU.cx > m_sizeDefault.cx)
  351. return m_sizeMRU;
  352. else
  353. return m_sizeDefault;
  354. }
  355. void CViewManager::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
  356. {
  357. lpwndpos->flags |= SWP_FRAMECHANGED;
  358. CControlBar::OnWindowPosChanging(lpwndpos);
  359. UINT nOldDockID = m_nDockID;
  360. m_nDockID = GetParent()->GetDlgCtrlID();
  361. if (nOldDockID == m_nDockID)
  362. return;
  363. else
  364. {
  365. DWORD dwStyle = m_ViewTabCtrl.GetStyle();
  366. switch(m_nDockID)
  367. {
  368. case AFX_IDW_DOCKBAR_TOP:
  369. if (dwStyle & TCS_BOTTOM)
  370. {
  371. DWORD dwNewStyle = dwStyle & ~TCS_BOTTOM;
  372. m_ViewTabCtrl.ModifyStyle(dwStyle, dwNewStyle);
  373. }
  374. break;
  375. case AFX_IDW_DOCKBAR_BOTTOM:
  376. if ((dwStyle & TCS_BOTTOM) == 0)
  377. {
  378. DWORD dwNewStyle = dwStyle | TCS_BOTTOM;
  379. m_ViewTabCtrl.ModifyStyle(dwStyle, dwNewStyle);
  380. }
  381. break;
  382. case AFX_IDW_DOCKBAR_LEFT:
  383. break;
  384. case AFX_IDW_DOCKBAR_RIGHT:
  385. break;
  386. default:
  387. DWORD dwNewStyle = dwStyle & ~TCS_BOTTOM;
  388. m_ViewTabCtrl.ModifyStyle(dwStyle, dwNewStyle);
  389. break;
  390. }
  391. }
  392. }
  393. void CViewManager::DoPaint(CDC* pDC)
  394. {
  395. CRect rect;
  396. GetClientRect(rect);
  397. // clean background
  398. COLORREF clr = ::GetSysColor(COLOR_BTNFACE);
  399. pDC->FillSolidRect(rect, clr);
  400. // draw the gripper
  401. DrawGripper(pDC);
  402. // It is better to let the underlining control bar take the last shot
  403. CControlBar::DoPaint(pDC);
  404. }
  405. void CViewManager::DrawGripper(CDC* pDC)
  406. {
  407. if( (m_dwStyle & CBRS_FLOATING) || m_dwDockStyle == 0 )
  408. return;
  409. COLORREF clrBtnHilight = ::GetSysColor(COLOR_BTNHILIGHT);
  410. COLORREF clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
  411. CRect rcGrip;
  412. GetWindowRect(&rcGrip);
  413. ScreenToClient(&rcGrip);
  414. rcGrip.OffsetRect(-rcGrip.left, -rcGrip.top);
  415. if(m_dwStyle & CBRS_ORIENT_HORZ)
  416. {
  417. // gripper at left
  418. rcGrip.DeflateRect(4, 4);
  419. rcGrip.right = rcGrip.left + 3;
  420. pDC->Draw3dRect(rcGrip, clrBtnHilight, clrBtnShadow);
  421. rcGrip.OffsetRect(3, 0);
  422. pDC->Draw3dRect(rcGrip, clrBtnHilight, clrBtnShadow);
  423. }
  424. else
  425. {
  426. // gripper at top
  427. rcGrip.DeflateRect(4, 4);
  428. rcGrip.bottom = rcGrip.top + 3;
  429. pDC->Draw3dRect(rcGrip, clrBtnHilight, clrBtnShadow);
  430. rcGrip.OffsetRect(0, 3);
  431. pDC->Draw3dRect(rcGrip, clrBtnHilight, clrBtnShadow);
  432. }
  433. }