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

对话框与窗口

开发平台:

Visual C++

  1. // XTMDIWndTab.cpp : implementation file
  2. //
  3. // This file is a part of the XTREME CONTROLS 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/XTPVC80Helpers.h"
  23. #include "Common/XTPSystemHelpers.h"
  24. #include "XTGlobal.h"
  25. #include "XTVC50Helpers.h"
  26. #include "XTTabCtrlButtons.h"
  27. #include "XTTabBase.h"
  28. #include "XTMDIWndTab.h"
  29. #ifdef _DEBUG
  30. #define new DEBUG_NEW
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CXTMDIClientWnd
  36. CXTMDIClientWnd::CXTMDIClientWnd(CXTMDIWndTab* pMDIWndTab)
  37. {
  38. ASSERT_VALID(pMDIWndTab);
  39. m_pMDIWndTab = pMDIWndTab;
  40. m_iBorderGap = pMDIWndTab->m_iBorderGap + ::GetSystemMetrics(SM_CXSIZEFRAME);
  41. }
  42. CXTMDIClientWnd::~CXTMDIClientWnd()
  43. {
  44. }
  45. BEGIN_MESSAGE_MAP(CXTMDIClientWnd, CWnd)
  46. //{{AFX_MSG_MAP(CXTMDIClientWnd)
  47. //}}AFX_MSG_MAP
  48. ON_MESSAGE(WM_MDICREATE, OnMDICreate)
  49. ON_MESSAGE(WM_MDIDESTROY, OnMDIDestroy)
  50. ON_MESSAGE(WM_MDIACTIVATE, OnMDIActivate)
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CXTMDIClientWnd message handlers
  54. LRESULT CXTMDIClientWnd::OnMDICreate(WPARAM /*wParam*/, LPARAM /*lParam*/)
  55. {
  56. LRESULT lResult = Default();
  57. m_pMDIWndTab->OnMDICreate((HWND)lResult);
  58. return lResult;
  59. }
  60. LRESULT CXTMDIClientWnd::OnMDIDestroy(WPARAM wParam, LPARAM /*lParam*/)
  61. {
  62. LRESULT lResult = Default();
  63. m_pMDIWndTab->OnMDIDestroy((HWND)wParam);
  64. return lResult;
  65. }
  66. LRESULT CXTMDIClientWnd::OnMDIActivate(WPARAM wParam, LPARAM /*lParam*/)
  67. {
  68. LRESULT lResult = Default();
  69. m_pMDIWndTab->OnMDIActivate((HWND)wParam);
  70. return lResult;
  71. }
  72. void CXTMDIClientWnd::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
  73. {
  74. if (::IsWindow(m_pMDIWndTab->m_hWnd) && m_pMDIWndTab->IsWindowVisible())
  75. {
  76. m_pMDIWndTab->MoveWindow(lpClientRect);
  77. DWORD dwStyle = m_pMDIWndTab->GetStyle();
  78. CRect rcTab;
  79. m_pMDIWndTab->GetItemRect(m_pMDIWndTab->GetCurSel(), &rcTab);
  80. int cy = rcTab.Height() * m_pMDIWndTab->GetRowCount();
  81. int cx = rcTab.Width () * m_pMDIWndTab->GetRowCount();
  82. // vertical tabs
  83. if (dwStyle & TCS_VERTICAL)
  84. {
  85. // Right
  86. if (dwStyle & TCS_RIGHT)
  87. {
  88. lpClientRect->top += m_iBorderGap;
  89. lpClientRect->left += m_iBorderGap;
  90. lpClientRect->right -= cx + m_iBorderGap + 2;
  91. lpClientRect->bottom -= m_iBorderGap;
  92. }
  93. // Left
  94. else
  95. {
  96. lpClientRect->top += m_iBorderGap;
  97. lpClientRect->left += cx + m_iBorderGap + 2;
  98. lpClientRect->right -= m_iBorderGap;
  99. lpClientRect->bottom -= m_iBorderGap;
  100. }
  101. }
  102. // horizontal tabs
  103. else
  104. {
  105. // Bottom
  106. if (dwStyle & TCS_BOTTOM)
  107. {
  108. lpClientRect->top += m_iBorderGap;
  109. lpClientRect->left += m_iBorderGap;
  110. lpClientRect->right -= m_iBorderGap;
  111. lpClientRect->bottom -= cy + m_iBorderGap + 2;
  112. }
  113. // Top
  114. else
  115. {
  116. lpClientRect->top += cy + m_iBorderGap + 2;
  117. lpClientRect->left += m_iBorderGap;
  118. lpClientRect->right -= m_iBorderGap;
  119. lpClientRect->bottom -= m_iBorderGap;
  120. }
  121. }
  122. }
  123. CWnd::CalcWindowRect(lpClientRect, nAdjustType);
  124. }
  125. /////////////////////////////////////////////////////////////////////////////
  126. // CXTMDIWndTab
  127. CXTMDIWndTab::CXTMDIWndTab()
  128. {
  129. m_bNoIcons = FALSE;
  130. m_iBorderGap = 5;
  131. m_nPos = 0;
  132. m_nDefCmd = 0;
  133. m_popupMenuID = 0;
  134. m_hActiveChild = NULL;
  135. m_pMDIClientWnd = NULL;
  136. m_pMDIFrameWnd = NULL;
  137. m_bXPBorder = false;
  138. m_dwInitSignature = 1;
  139. ImplAttach(this);
  140. }
  141. CXTMDIWndTab::~CXTMDIWndTab()
  142. {
  143. SAFE_DELETE (m_pMDIClientWnd);
  144. while (!m_arMDIChildern.IsEmpty())
  145. {
  146. MDICHILD* pMDIChild = m_arMDIChildern.RemoveHead();
  147. SAFE_DELETE(pMDIChild);
  148. }
  149. }
  150. IMPLEMENT_THEME_REFRESH(CXTMDIWndTab, CTabCtrl)
  151. IMPLEMENT_DYNAMIC(CXTMDIWndTab, CTabCtrl)
  152. BEGIN_MESSAGE_MAP(CXTMDIWndTab, CTabCtrl)
  153. //{{AFX_MSG_MAP(CXTMDIWndTab)
  154. ON_WM_NCCALCSIZE()
  155. ON_WM_NCPAINT()
  156. ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelchange)
  157. ON_WM_DESTROY()
  158. ON_WM_RBUTTONDOWN()
  159. //}}AFX_MSG_MAP
  160. ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
  161. ON_COMMAND(XT_IDC_TAB_CLOSE, OnTabClose)
  162. ON_TABCTRL_REFLECT()
  163. END_MESSAGE_MAP()
  164. /////////////////////////////////////////////////////////////////////////////
  165. // CXTMDIWndTab message handlers
  166. bool CXTMDIWndTab::Init()
  167. {
  168. if (!CXTMDIWndTabBase::Init())
  169. return false;
  170. ShowNavButtons(xtNavBtnShowAll);
  171. int cx = ::GetSystemMetrics(SM_CXSMICON);
  172. int cy = ::GetSystemMetrics(SM_CYSMICON);
  173. if (!m_imageList.Create(cx, cy, ILC_COLOR16 | ILC_MASK, 0, 1))
  174. {
  175. TRACE0("Unable to create CXTMDIWndTab image list.n");
  176. return FALSE;
  177. }
  178. SetImageList(&m_imageList);
  179. InitializeFont();
  180. return true;
  181. }
  182. BOOL CXTMDIWndTab::Install(CMDIFrameWnd* pMDIFrameWnd, DWORD dwStyle/*= TCS_BOTTOM | TCS_HOTTRACK*/, BOOL bNoIcons/*= FALSE*/)
  183. {
  184. ASSERT_VALID(pMDIFrameWnd);                // must be valid.
  185. ASSERT_KINDOF(CMDIFrameWnd, pMDIFrameWnd); // must be MDI frame window.
  186. m_bNoIcons = bNoIcons;
  187. m_pMDIFrameWnd = pMDIFrameWnd;
  188. m_iBorderGap = GetSafeTheme()->GetTheme() != xtThemeDefault ? 1 : 5;
  189. dwStyle |= WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN;
  190. if (!Create(dwStyle, CRect(0, 0, 0, 0), m_pMDIFrameWnd, AFX_IDC_TAB_CONTROL))
  191. {
  192. TRACE0("Unable to create CXTMDIWndTab control.n");
  193. return FALSE;
  194. }
  195. m_pMDIClientWnd = new CXTMDIClientWnd(this);
  196. ASSERT(m_pMDIClientWnd != NULL);
  197. if (!m_pMDIClientWnd->SubclassWindow(m_pMDIFrameWnd->m_hWndMDIClient))
  198. return FALSE;
  199. // Retrieve the current active MDI child window.
  200. CMDIChildWnd* pActiveChild = (CMDIChildWnd*)m_pMDIFrameWnd->MDIGetActive();
  201. if (pActiveChild != NULL)
  202. {
  203. // Get the first top-level window in the list.
  204. CMDIChildWnd* pChildFrame = (CMDIChildWnd*)pActiveChild->GetWindow(GW_HWNDLAST);
  205. while (pChildFrame != NULL)
  206. {
  207. // Insert the tab and get the next frame on the window manager's list
  208. InsertTabWnd(pChildFrame, FALSE);
  209. pChildFrame = (CMDIChildWnd*)pChildFrame->GetWindow(GW_HWNDPREV);
  210. }
  211. }
  212. // Force parent frame to re-adjust layout.
  213. m_pMDIFrameWnd->RecalcLayout();
  214. return TRUE;
  215. }
  216. BOOL CXTMDIWndTab::UnInstall()
  217. {
  218. // Remove all of the items from the child array.
  219. while (!m_arMDIChildern.IsEmpty())
  220. {
  221. MDICHILD* pMDIChild = m_arMDIChildern.RemoveHead();
  222. SAFE_DELETE(pMDIChild);
  223. }
  224. CXTTabCtrlButtons* pNavBtns = GetButtons();
  225. if (pNavBtns && pNavBtns->GetSafeHwnd())
  226. {
  227. pNavBtns->UnSubclassTabButtons();
  228. }
  229. if (::IsWindow(m_hWnd) && m_pMDIFrameWnd)
  230. {
  231. // Unsubclass the MDI client and free the dynamic memory.
  232. m_pMDIClientWnd->UnsubclassWindow();
  233. SAFE_DELETE (m_pMDIClientWnd);
  234. // Force parent frame to re-adjust layout.
  235. m_pMDIFrameWnd->RecalcLayout();
  236. // Destroy this window.
  237. return DestroyWindow();
  238. }
  239. return FALSE;
  240. }
  241. void CXTMDIWndTab::InsertTabWnd(CMDIChildWnd* pChildWnd, BOOL bRecalcLayout/*= TRUE*/)
  242. {
  243. ASSERT_VALID(pChildWnd); // must be valid.
  244. // Try to locate the icon for the MDI window by calling WM_GETICON
  245. // first, this will give us the correct icon if the user has called
  246. // SetIcon(...) for the child frame.
  247. HICON hIcon = (HICON)::SendMessage(pChildWnd->m_hWnd, WM_GETICON, FALSE, 0);
  248. // If the icon returned is NULL, then try using GCLP_HICONSM to get the
  249. // document icon for the child frame
  250. if (hIcon == NULL)
  251. {
  252. hIcon = (HICON)(ULONG_PTR)::GetClassLongPtr(pChildWnd->m_hWnd, GCLP_HICONSM);
  253. }
  254. // If no icon was found, then use the default windows logo icon.
  255. if (hIcon == NULL)
  256. {
  257. hIcon = AfxGetApp()->LoadStandardIcon(IDI_WINLOGO);
  258. }
  259. m_imageList.Add(hIcon);
  260. // Get the window text for the frame.
  261. CXTStringHelper strWindowText = GetChildWndText(pChildWnd->GetSafeHwnd());
  262. int iItem = GetItemCount();
  263. MDICHILD* pMDIChild = new MDICHILD;
  264. ASSERT(pMDIChild != NULL);
  265. pMDIChild->iItem = iItem;
  266. pMDIChild->hWnd = pChildWnd->GetSafeHwnd();
  267. pMDIChild->strItem = strWindowText;
  268. m_arMDIChildern.AddTail(pMDIChild);
  269. if (GetSafeTheme()->GetTheme() != xtThemeDefault)
  270. {
  271. OnAddPadding(strWindowText);
  272. }
  273. // Insert the new item into the tab control.
  274. TC_ITEM tci;
  275. tci.mask = TCIF_IMAGE | TCIF_PARAM | TCIF_TEXT;
  276. tci.pszText = (TCHAR*)(LPCTSTR)strWindowText;
  277. tci.cchTextMax = strWindowText.GetLength();
  278. tci.iImage = m_imageList.GetImageCount()-1;
  279. tci.lParam = (LPARAM)pMDIChild;
  280. if (m_bNoIcons)
  281. {
  282. tci.iImage = -1;
  283. }
  284. InsertItem(iItem, &tci);
  285. if (m_pMDIFrameWnd->MDIGetActive() == pChildWnd)
  286. {
  287. SetCurSel(iItem);
  288. }
  289. // defer request to complete initialization
  290. RecalcLayout(bRecalcLayout);
  291. }
  292. void CXTMDIWndTab::RecalcLayout(BOOL bDelayRecalc)
  293. {
  294. // refresh labels
  295. RefreshTabLabels();
  296. // Recalc frame layout.
  297. if (bDelayRecalc)
  298. {
  299. m_pMDIFrameWnd->DelayRecalcLayout();
  300. }
  301. }
  302. void CXTMDIWndTab::RefreshIndexes()
  303. {
  304. int iItem;
  305. for (iItem = 0; iItem < GetItemCount(); ++iItem)
  306. {
  307. TC_ITEM tci;
  308. tci.mask = TCIF_PARAM;
  309. if (GetItem(iItem, &tci))
  310. {
  311. MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
  312. ASSERT(pMDIChild != NULL);
  313. if (pMDIChild) pMDIChild->iItem = iItem;
  314. }
  315. }
  316. }
  317. void CXTMDIWndTab::OnMDICreate(HWND hWnd)
  318. {
  319. CMDIChildWnd* pActiveChild = (CMDIChildWnd*)CWnd::FromHandle(hWnd);
  320. if (pActiveChild != NULL)
  321. {
  322. InsertTabWnd(pActiveChild);
  323. }
  324. RefreshIndexes();
  325. }
  326. void CXTMDIWndTab::OnMDIDestroy(HWND hWnd)
  327. {
  328. // Loop through all of the tabs to find the view that has closed.
  329. int iItem;
  330. for (iItem = 0; iItem < GetItemCount(); ++iItem)
  331. {
  332. // Get the item data for this tab.
  333. TC_ITEM tci;
  334. tci.mask = TCIF_PARAM;
  335. if (GetItem(iItem, &tci))
  336. {
  337. MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
  338. ASSERT(pMDIChild != NULL);
  339. // If it is the closed window remove it and exit loop.
  340. if (pMDIChild && (hWnd == pMDIChild->hWnd))
  341. {
  342. POSITION pos = m_arMDIChildern.Find(pMDIChild);
  343. if (pos)
  344. {
  345. m_arMDIChildern.RemoveAt(pos);
  346. SAFE_DELETE(pMDIChild);
  347. }
  348. DeleteItem(iItem);
  349. break;
  350. }
  351. }
  352. }
  353. RefreshIndexes();
  354. RecalcLayout(TRUE);
  355. }
  356. void CXTMDIWndTab::OnMDIActivate(HWND hWnd)
  357. {
  358. // Loop through all of the tabs to find the view that has activated.
  359. int iItem;
  360. for (iItem = 0; iItem < GetItemCount(); ++iItem)
  361. {
  362. // Get the item data for this tab.
  363. TC_ITEM tci;
  364. tci.mask = TCIF_PARAM;
  365. if (GetItem(iItem, &tci))
  366. {
  367. MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
  368. ASSERT(pMDIChild != NULL);
  369. // If it is the activated window select it and exit loop.
  370. if (pMDIChild && (hWnd == pMDIChild->hWnd))
  371. {
  372. SetCurSel(iItem);
  373. break;
  374. }
  375. }
  376. }
  377. }
  378. bool CXTMDIWndTab::SetTabIcon(int iIndex, HICON& hIcon)
  379. {
  380. TC_ITEM tci;
  381. tci.mask = TCIF_PARAM;
  382. if (GetItem(iIndex, &tci))
  383. {
  384. MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
  385. ASSERT(pMDIChild != NULL);
  386. if (!pMDIChild)
  387. return false;
  388. return SetTabIcon(pMDIChild->hWnd, hIcon);
  389. }
  390. return false;
  391. }
  392. bool CXTMDIWndTab::SetTabIcon(HWND hChildWnd, HICON& hIcon)
  393. {
  394. if (!hIcon || !::IsWindow(hChildWnd))
  395. {
  396. return false;
  397. }
  398. m_mapTabIcons.SetAt(hChildWnd, hIcon);
  399. return true;
  400. }
  401. bool CXTMDIWndTab::SetTabLabel(int iIndex, CString& strLabel)
  402. {
  403. TC_ITEM tci;
  404. tci.mask = TCIF_PARAM;
  405. if (GetItem(iIndex, &tci))
  406. {
  407. MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
  408. ASSERT(pMDIChild != NULL);
  409. if (!pMDIChild)
  410. return false;
  411. return SetTabLabel(pMDIChild->hWnd, strLabel);
  412. }
  413. return false;
  414. }
  415. bool CXTMDIWndTab::SetTabLabel(HWND hChildWnd, CString& strLabel)
  416. {
  417. if (strLabel.IsEmpty() || !::IsWindow(hChildWnd))
  418. {
  419. return false;
  420. }
  421. m_mapTabLabels.SetAt(hChildWnd, strLabel);
  422. return true;
  423. }
  424. CString CXTMDIWndTab::GetChildWndText(HWND hWnd) const
  425. {
  426. // Check to see if the user has defined a label for the tab first.
  427. CString strTitle;
  428. if (m_mapTabLabels.Lookup(hWnd, strTitle))
  429. {
  430. return strTitle;
  431. }
  432. // Get a pointer to the frame window.
  433. CMDIChildWnd* pChildFrame = (CMDIChildWnd*)CWnd::FromHandle(hWnd);
  434. if (!::IsWindow(pChildFrame->GetSafeHwnd()))
  435. {
  436. return _T("");
  437. }
  438. // Get the window text for the frame and use it for the tab label.
  439. pChildFrame->GetWindowText(strTitle);
  440. // If the string is empty the document's title.
  441. if (strTitle.IsEmpty())
  442. {
  443. CWnd* pChildWnd = pChildFrame->GetWindow(GW_CHILD);
  444. while (pChildWnd)
  445. {
  446. if (pChildWnd->IsKindOf(RUNTIME_CLASS(CView)))
  447. {
  448. // Get a pointer to the view's document.
  449. CDocument* pDoc = ((CView*)pChildWnd)->GetDocument();
  450. if (pDoc == NULL)
  451. {
  452. return _T("");
  453. }
  454. // Set the return string value
  455. strTitle = pDoc->GetTitle();
  456. // Reset the frames title
  457. pChildFrame->SetWindowText(strTitle);
  458. // Return the document title.
  459. return strTitle;
  460. }
  461. pChildWnd = pChildWnd->GetWindow(GW_HWNDNEXT);
  462. }
  463. }
  464. // Return the MDI frame window's title.
  465. return strTitle;
  466. }
  467. BOOL CXTMDIWndTab::RefreshActiveSel()
  468. {
  469. // Get the active MDI window, if NULL return FALSE.
  470. HWND hWndActiveChild = m_pMDIFrameWnd->MDIGetActive()->GetSafeHwnd();
  471. if (hWndActiveChild == NULL)
  472. {
  473. m_hActiveChild = NULL;
  474. return FALSE;
  475. }
  476. // Loop through all of the tabs to find the view that has activated.
  477. bool bSelectionChanged = false;
  478. if (POSITION pos = m_arMDIChildern.GetHeadPosition())
  479. {
  480. do
  481. {
  482. MDICHILD* pMDIChild = m_arMDIChildern.GetNext(pos);
  483. ASSERT(pMDIChild != NULL);
  484. // We have found the handle to the active MDI window,
  485. // lets see if the tab is selected.
  486. if (pMDIChild && (pMDIChild->hWnd == hWndActiveChild))
  487. {
  488. // If the active child pointer does not match, then
  489. // make sure that the tab is selected then save the pointer.
  490. bSelectionChanged = hWndActiveChild != m_hActiveChild;
  491. if (bSelectionChanged)
  492. {
  493. SetCurSel(pMDIChild->iItem);
  494. m_hActiveChild = hWndActiveChild;
  495. }
  496. }
  497. }
  498. while (pos != NULL && !bSelectionChanged);
  499. }
  500. return bSelectionChanged;
  501. }
  502. void CXTMDIWndTab::RefreshTabLabels()
  503. {
  504. // Loop through all of the tabs to find the view that has activated.
  505. POSITION pos = m_arMDIChildern.GetHeadPosition();
  506. while (pos != NULL)
  507. {
  508. bool bSetItem = false;
  509. MDICHILD* pMDIChild = m_arMDIChildern.GetNext(pos);
  510. ASSERT(pMDIChild != NULL);
  511. if (!pMDIChild)
  512. continue;
  513. // Get the window text for the child frame and the tab item.
  514. CXTStringHelper strWindowText = GetChildWndText(pMDIChild->hWnd);
  515. TCHAR szText[_MAX_PATH];
  516. szText[0] = 0;
  517. TC_ITEM tci;
  518. tci.mask = TCIF_TEXT | TCIF_IMAGE;
  519. tci.cchTextMax = _countof(szText);
  520. tci.pszText = szText;
  521. // Get the item data for the tab.
  522. if (GetItem(pMDIChild->iItem, &tci))
  523. {
  524. CString strTabLabel = szText;
  525. if (GetSafeTheme()->GetTheme() != xtThemeDefault)
  526. {
  527. OnAddPadding(strWindowText);
  528. }
  529. // If they do not match then update the tab item label.
  530. if (strTabLabel != strWindowText)
  531. {
  532. STRCPY_S(szText, _MAX_PATH, strWindowText);
  533. tci.cchTextMax = strWindowText.GetLength();
  534. bSetItem = true;
  535. }
  536. if (!m_bNoIcons)
  537. {
  538. // Check to see if the user set the icon for the tab label.
  539. HICON hIcon = 0;
  540. if (!m_mapTabIcons.Lookup(pMDIChild->hWnd, hIcon))
  541. {
  542. // The user may have set the icon for the child by calling WM_SETICON.  If
  543. // WM_GETICON returns an icon we need to make sure the tab icon has been updated.
  544. hIcon = (HICON)::SendMessage(pMDIChild->hWnd, WM_GETICON, FALSE, 0);
  545. // Insert the icon into map to avoid failed Lookup().
  546. m_mapTabIcons.SetAt(pMDIChild->hWnd, hIcon);
  547. }
  548. // Replace the image in image list ONLY when Lookup() failed.
  549. if ((hIcon != NULL) && (tci.iImage != -1))
  550. {
  551. bSetItem = true;
  552. m_imageList.Replace(tci.iImage, hIcon);
  553. }
  554. }
  555. if (bSetItem)
  556. {
  557. VERIFY(SetItem(pMDIChild->iItem, &tci));
  558. }
  559. }
  560. }
  561. }
  562. void CXTMDIWndTab::OnIdleUpdateCmdUI()
  563. {
  564. if (m_pMDIFrameWnd)
  565. {
  566. RefreshActiveSel();
  567. RefreshTabLabels();
  568. }
  569. }
  570. void CXTMDIWndTab::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
  571. {
  572. RECT& rc = lpncsp->rgrc[0];
  573. if (rc.bottom - rc.top > m_iBorderGap * 2)
  574. {
  575. rc.top += m_iBorderGap;
  576. rc.bottom -= m_iBorderGap;
  577. }
  578. else
  579. {
  580. rc.top = rc.bottom;
  581. }
  582. if (rc.right - rc.left > m_iBorderGap * 2)
  583. {
  584. rc.left += m_iBorderGap;
  585. rc.right -= m_iBorderGap;
  586. }
  587. else
  588. {
  589. rc.left = rc.right;
  590. }
  591. CTabCtrl::OnNcCalcSize(bCalcValidRects, lpncsp);
  592. }
  593. void CXTMDIWndTab::OnNcPaint()
  594. {
  595. CWindowDC dc(this);
  596. CRect rectClient;
  597. GetClientRect(rectClient);
  598. CRect rectWindow;
  599. GetWindowRect(rectWindow);
  600. rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
  601. if (rectWindow.Width() > rectClient.Width())
  602. {
  603. dc.DrawEdge(rectWindow, BDR_SUNKENOUTER, BF_RECT);
  604. }
  605. }
  606. void CXTMDIWndTab::OnSelchange(NMHDR* /*pNMHDR*/, LRESULT* pResult)
  607. {
  608. // Get the item data for the currently selected tab.
  609. TC_ITEM tci;
  610. tci.mask = TCIF_PARAM;
  611. if (GetItem(GetCurSel(), &tci))
  612. {
  613. MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
  614. ASSERT(pMDIChild != NULL);
  615. if (!pMDIChild)
  616. return;
  617. // Get the pointer to the currently selected tab window.
  618. CWnd* pActiveWnd = CWnd::FromHandle(pMDIChild->hWnd);
  619. ASSERT_VALID(pActiveWnd);
  620. // Activate the new tab window.
  621. m_pMDIFrameWnd->MDIActivate(pActiveWnd);
  622. }
  623. *pResult = 0;
  624. }
  625. void CXTMDIWndTab::OnDestroy()
  626. {
  627. CTabCtrl::OnDestroy();
  628. // Delete the image list.
  629. m_imageList.DeleteImageList();
  630. // Set the active and parent windows to NULL.
  631. m_hActiveChild = NULL;
  632. m_pMDIFrameWnd = NULL;
  633. }
  634. int CXTMDIWndTab::TabFromPoint(CPoint point) const
  635. {
  636. TCHITTESTINFO tch;
  637. memset(&tch, 0, sizeof(TCHITTESTINFO));
  638. if (point == CPoint(0, 0))
  639. {
  640. CPoint pt;
  641. GetCursorPos(&pt);
  642. ScreenToClient(&pt);
  643. tch.pt = pt;
  644. }
  645. else
  646. {
  647. tch.pt = point;
  648. }
  649. return HitTest(&tch);
  650. }
  651. CMDIChildWnd* CXTMDIWndTab::GetFrameWnd(int iIndex) const
  652. {
  653. if (iIndex == -1)
  654. iIndex = m_iHitTest;
  655. TC_ITEM tci;
  656. tci.mask = TCIF_PARAM;
  657. if (GetItem(iIndex, &tci))
  658. {
  659. MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
  660. ASSERT(pMDIChild != NULL);
  661. if (!pMDIChild)
  662. return NULL;
  663. return DYNAMIC_DOWNCAST(CMDIChildWnd, CWnd::FromHandle(pMDIChild->hWnd));
  664. }
  665. return NULL;
  666. }
  667. CMDIChildWnd* CXTMDIWndTab::GetFrameWnd(CPoint point) const
  668. {
  669. return GetFrameWnd(TabFromPoint(point));
  670. }
  671. void CXTMDIWndTab::OnRButtonDown(UINT /*nFlags*/, CPoint point)
  672. {
  673. // Get the tab index based upon the cursor position.
  674. m_iHitTest = TabFromPoint(point);
  675. if (m_iHitTest != -1)
  676. {
  677. if (m_popupMenuID != 0)
  678. {
  679. CPoint pt = point;
  680. ClientToScreen(&pt);
  681. CMenu popupMenu;
  682. VERIFY(popupMenu.LoadMenu(m_popupMenuID));
  683. CMenu* pPopup = popupMenu.GetSubMenu(m_nPos);
  684. ASSERT(pPopup != NULL);
  685. if (!pPopup)
  686. return;
  687. if (m_nDefCmd != 0)
  688. {
  689. ::SetMenuDefaultItem(pPopup->m_hMenu, m_nDefCmd, FALSE);
  690. }
  691. CWnd* pWndPopupOwner = GetOwner();
  692. ASSERT_VALID(pWndPopupOwner);
  693. pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  694. pt.x, pt.y, pWndPopupOwner);
  695. }
  696. }
  697. }
  698. void CXTMDIWndTab::InitializeFont()
  699. {
  700. HGDIOBJ hFont = XTAuxData().font.GetSafeHandle();
  701. // if the tabs are vertical, use the vertical menu font.
  702. if ((GetStyle() & TCS_VERTICAL) == TCS_VERTICAL)
  703. hFont = XTAuxData().fontVert.GetSafeHandle();
  704. if (hFont != NULL)
  705. {
  706. if (XTOSVersionInfo()->IsWin95())
  707. PostMessage(WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
  708. else
  709. SendMessage(WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
  710. }
  711. }
  712. void CXTMDIWndTab::OnTabClose()
  713. {
  714. if (m_pMDIFrameWnd)
  715. {
  716. CMDIChildWnd* pActiveChild = (CMDIChildWnd*)m_pMDIFrameWnd->MDIGetActive();
  717. if (pActiveChild != NULL)
  718. {
  719. pActiveChild->SendMessage(WM_CLOSE);
  720. }
  721. }
  722. }