You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

891 lines
20 KiB
C++

2 years ago
// XTPMDIWndTab.cpp : implementation file
//
// This file is a part of the XTREME CONTROLS MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Common/XTPVC80Helpers.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPColorManager.h"
#include "../Defines.h"
#include "../Util/XTPGlobal.h"
#include "../Util/XTPControlTheme.h"
#include "XTPTabBase.h"
#include "XTPTabCtrlButtons.h"
#include "XTPMDIWndTab.h"
#include "XTPTabBaseTheme.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CXTPMDIClientWnd
CXTPMDIClientWnd::CXTPMDIClientWnd(CXTPMDIWndTab* pMDIWndTab)
{
ASSERT_VALID(pMDIWndTab);
m_pMDIWndTab = pMDIWndTab;
m_iBorderGap = pMDIWndTab->m_iBorderGap + ::GetSystemMetrics(SM_CXSIZEFRAME);
}
CXTPMDIClientWnd::~CXTPMDIClientWnd()
{
}
BEGIN_MESSAGE_MAP(CXTPMDIClientWnd, CWnd)
//{{AFX_MSG_MAP(CXTPMDIClientWnd)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MDICREATE, OnMDICreate)
ON_MESSAGE(WM_MDIDESTROY, OnMDIDestroy)
ON_MESSAGE(WM_MDIACTIVATE, OnMDIActivate)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXTPMDIClientWnd message handlers
LRESULT CXTPMDIClientWnd::OnMDICreate(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
LRESULT lResult = Default();
m_pMDIWndTab->OnMDICreate((HWND)lResult);
return lResult;
}
LRESULT CXTPMDIClientWnd::OnMDIDestroy(WPARAM wParam, LPARAM /*lParam*/)
{
LRESULT lResult = Default();
m_pMDIWndTab->OnMDIDestroy((HWND)wParam);
return lResult;
}
LRESULT CXTPMDIClientWnd::OnMDIActivate(WPARAM wParam, LPARAM /*lParam*/)
{
LRESULT lResult = Default();
m_pMDIWndTab->OnMDIActivate((HWND)wParam);
return lResult;
}
void CXTPMDIClientWnd::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
{
if (::IsWindow(m_pMDIWndTab->m_hWnd) && m_pMDIWndTab->IsWindowVisible())
{
m_pMDIWndTab->MoveWindow(lpClientRect);
DWORD dwStyle = m_pMDIWndTab->GetStyle();
CRect rcTab;
m_pMDIWndTab->GetItemRect(m_pMDIWndTab->GetCurSel(), &rcTab);
int cy = rcTab.Height() * m_pMDIWndTab->GetRowCount();
int cx = rcTab.Width () * m_pMDIWndTab->GetRowCount();
// vertical tabs
if (dwStyle & TCS_VERTICAL)
{
// Right
if (dwStyle & TCS_RIGHT)
{
lpClientRect->top += m_iBorderGap;
lpClientRect->left += m_iBorderGap;
lpClientRect->right -= cx + m_iBorderGap + 2;
lpClientRect->bottom -= m_iBorderGap;
}
// Left
else
{
lpClientRect->top += m_iBorderGap;
lpClientRect->left += cx + m_iBorderGap + 2;
lpClientRect->right -= m_iBorderGap;
lpClientRect->bottom -= m_iBorderGap;
}
}
// horizontal tabs
else
{
// Bottom
if (dwStyle & TCS_BOTTOM)
{
lpClientRect->top += m_iBorderGap;
lpClientRect->left += m_iBorderGap;
lpClientRect->right -= m_iBorderGap;
lpClientRect->bottom -= cy + m_iBorderGap + 2;
}
// Top
else
{
lpClientRect->top += cy + m_iBorderGap + 2;
lpClientRect->left += m_iBorderGap;
lpClientRect->right -= m_iBorderGap;
lpClientRect->bottom -= m_iBorderGap;
}
}
}
CWnd::CalcWindowRect(lpClientRect, nAdjustType);
}
/////////////////////////////////////////////////////////////////////////////
// CXTPMDIWndTab
CXTPMDIWndTab::CXTPMDIWndTab()
{
m_bNoIcons = FALSE;
m_iBorderGap = 5;
m_nPos = 0;
m_nDefCmd = 0;
m_popupMenuID = 0;
m_hActiveChild = NULL;
m_pMDIClientWnd = NULL;
m_pMDIFrameWnd = NULL;
m_bXPBorder = false;
m_dwInitSignature = 1;
ImplAttach(this);
}
CXTPMDIWndTab::~CXTPMDIWndTab()
{
SAFE_DELETE (m_pMDIClientWnd);
while (!m_arMDIChildern.IsEmpty())
{
MDICHILD* pMDIChild = m_arMDIChildern.RemoveHead();
SAFE_DELETE(pMDIChild);
}
}
IMPLEMENT_DYNAMIC(CXTPMDIWndTab, CTabCtrl)
BEGIN_MESSAGE_MAP(CXTPMDIWndTab, CTabCtrl)
//{{AFX_MSG_MAP(CXTPMDIWndTab)
ON_WM_NCCALCSIZE()
ON_WM_NCPAINT()
ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelchange)
ON_WM_DESTROY()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
ON_COMMAND(XTP_IDC_TAB_CLOSE, OnTabClose)
ON_TABCTRL_REFLECT()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXTPMDIWndTab message handlers
BOOL CXTPMDIWndTab::Init()
{
if (!CXTPMDIWndTabBase::Init())
return FALSE;
ShowNavButtons(xtpNavBtnShowAll);
int cx = ::GetSystemMetrics(SM_CXSMICON);
int cy = ::GetSystemMetrics(SM_CYSMICON);
if (!m_imageList.Create(cx, cy, ILC_COLOR16 | ILC_MASK, 0, 1))
{
TRACE0("Unable to create CXTPMDIWndTab image list.\n");
return FALSE;
}
SetImageList(&m_imageList);
InitializeFont();
return TRUE;
}
BOOL CXTPMDIWndTab::Install(CMDIFrameWnd* pMDIFrameWnd, DWORD dwStyle/*= TCS_BOTTOM | TCS_HOTTRACK*/, BOOL bNoIcons/*= FALSE*/)
{
ASSERT_VALID(pMDIFrameWnd); // must be valid.
ASSERT_KINDOF(CMDIFrameWnd, pMDIFrameWnd); // must be MDI frame window.
m_bNoIcons = bNoIcons;
m_pMDIFrameWnd = pMDIFrameWnd;
m_iBorderGap = m_pTheme->GetThemeStyle() != xtpControlThemeOffice2000 ? 1 : 5;
dwStyle |= WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN;
if (!Create(dwStyle, CRect(0, 0, 0, 0), m_pMDIFrameWnd, AFX_IDC_TAB_CONTROL))
{
TRACE0("Unable to create CXTPMDIWndTab control.\n");
return FALSE;
}
m_pMDIClientWnd = new CXTPMDIClientWnd(this);
ASSERT(m_pMDIClientWnd != NULL);
if (!m_pMDIClientWnd->SubclassWindow(m_pMDIFrameWnd->m_hWndMDIClient))
return FALSE;
// Retrieve the current active MDI child window.
CMDIChildWnd* pActiveChild = (CMDIChildWnd*)m_pMDIFrameWnd->MDIGetActive();
if (pActiveChild != NULL)
{
// Get the first top-level window in the list.
CMDIChildWnd* pChildFrame = (CMDIChildWnd*)pActiveChild->GetWindow(GW_HWNDLAST);
while (pChildFrame != NULL)
{
// Insert the tab and get the next frame on the window manager's list
InsertTabWnd(pChildFrame, FALSE);
pChildFrame = (CMDIChildWnd*)pChildFrame->GetWindow(GW_HWNDPREV);
}
}
// Force parent frame to re-adjust layout.
m_pMDIFrameWnd->RecalcLayout();
return TRUE;
}
BOOL CXTPMDIWndTab::UnInstall()
{
// Remove all of the items from the child array.
while (!m_arMDIChildern.IsEmpty())
{
MDICHILD* pMDIChild = m_arMDIChildern.RemoveHead();
SAFE_DELETE(pMDIChild);
}
CXTPTabCtrlButtons* pNavBtns = GetButtons();
if (pNavBtns && pNavBtns->GetSafeHwnd())
{
pNavBtns->UnSubclassTabButtons();
}
if (::IsWindow(m_hWnd) && m_pMDIFrameWnd)
{
// Unsubclass the MDI client and free the dynamic memory.
m_pMDIClientWnd->UnsubclassWindow();
SAFE_DELETE (m_pMDIClientWnd);
// Force parent frame to re-adjust layout.
m_pMDIFrameWnd->RecalcLayout();
// Destroy this window.
return DestroyWindow();
}
return FALSE;
}
void CXTPMDIWndTab::InsertTabWnd(CMDIChildWnd* pChildWnd, BOOL bRecalcLayout/*= TRUE*/)
{
ASSERT_VALID(pChildWnd); // must be valid.
// Try to locate the icon for the MDI window by calling WM_GETICON
// first, this will give us the correct icon if the user has called
// SetIcon(...) for the child frame.
HICON hIcon = (HICON)::SendMessage(pChildWnd->m_hWnd, WM_GETICON, FALSE, 0);
// If the icon returned is NULL, then try using GCLP_HICONSM to get the
// document icon for the child frame
if (hIcon == NULL)
{
hIcon = (HICON)(ULONG_PTR)::GetClassLongPtr(pChildWnd->m_hWnd, GCLP_HICONSM);
}
// If no icon was found, then use the default windows logo icon.
if (hIcon == NULL)
{
hIcon = AfxGetApp()->LoadStandardIcon(IDI_WINLOGO);
}
m_imageList.Add(hIcon);
// Get the window text for the frame.
CString strWindowText = GetChildWndText(pChildWnd->GetSafeHwnd());
int iItem = GetItemCount();
MDICHILD* pMDIChild = new MDICHILD;
ASSERT(pMDIChild != NULL);
pMDIChild->iItem = iItem;
pMDIChild->hWnd = pChildWnd->GetSafeHwnd();
pMDIChild->strItem = strWindowText;
m_arMDIChildern.AddTail(pMDIChild);
if (m_pTheme->GetThemeStyle() != xtpControlThemeOffice2000)
{
OnAddPadding(strWindowText);
}
// Insert the new item into the tab control.
TC_ITEM tci;
tci.mask = TCIF_IMAGE | TCIF_PARAM | TCIF_TEXT;
tci.pszText = (TCHAR*)(LPCTSTR)strWindowText;
tci.cchTextMax = strWindowText.GetLength();
tci.iImage = m_imageList.GetImageCount()-1;
tci.lParam = (LPARAM)pMDIChild;
if (m_bNoIcons)
{
tci.iImage = -1;
}
InsertItem(iItem, &tci);
if (m_pMDIFrameWnd->MDIGetActive() == pChildWnd)
{
SetCurSel(iItem);
}
// defer request to complete initialization
RecalcLayout(bRecalcLayout);
}
void CXTPMDIWndTab::RecalcLayout(BOOL bDelayRecalc)
{
// refresh labels
RefreshTabLabels();
// Recalc frame layout.
if (bDelayRecalc)
{
m_pMDIFrameWnd->DelayRecalcLayout();
}
else
{
m_pMDIFrameWnd->RecalcLayout();
}
}
void CXTPMDIWndTab::RefreshIndexes()
{
int iItem;
for (iItem = 0; iItem < GetItemCount(); ++iItem)
{
TC_ITEM tci;
tci.mask = TCIF_PARAM;
if (GetItem(iItem, &tci))
{
MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
ASSERT(pMDIChild != NULL);
if (pMDIChild) pMDIChild->iItem = iItem;
}
}
}
void CXTPMDIWndTab::OnMDICreate(HWND hWnd)
{
CMDIChildWnd* pActiveChild = (CMDIChildWnd*)CWnd::FromHandle(hWnd);
if (pActiveChild != NULL)
{
InsertTabWnd(pActiveChild);
}
RefreshIndexes();
}
void CXTPMDIWndTab::OnMDIDestroy(HWND hWnd)
{
// Loop through all of the tabs to find the view that has closed.
int iItem;
for (iItem = 0; iItem < GetItemCount(); ++iItem)
{
// Get the item data for this tab.
TC_ITEM tci;
tci.mask = TCIF_PARAM;
if (GetItem(iItem, &tci))
{
MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
ASSERT(pMDIChild != NULL);
// If it is the closed window remove it and exit loop.
if (pMDIChild && (hWnd == pMDIChild->hWnd))
{
POSITION pos = m_arMDIChildern.Find(pMDIChild);
if (pos)
{
m_arMDIChildern.RemoveAt(pos);
SAFE_DELETE(pMDIChild);
}
DeleteItem(iItem);
break;
}
}
}
RefreshIndexes();
RecalcLayout(TRUE);
}
void CXTPMDIWndTab::OnMDIActivate(HWND hWnd)
{
// Loop through all of the tabs to find the view that has activated.
int iItem;
for (iItem = 0; iItem < GetItemCount(); ++iItem)
{
// Get the item data for this tab.
TC_ITEM tci;
tci.mask = TCIF_PARAM;
if (GetItem(iItem, &tci))
{
MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
ASSERT(pMDIChild != NULL);
// If it is the activated window select it and exit loop.
if (pMDIChild && (hWnd == pMDIChild->hWnd))
{
SetCurSel(iItem);
break;
}
}
}
}
bool CXTPMDIWndTab::SetTabIcon(int iIndex, HICON& hIcon)
{
TC_ITEM tci;
tci.mask = TCIF_PARAM;
if (GetItem(iIndex, &tci))
{
MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
ASSERT(pMDIChild != NULL);
if (!pMDIChild)
return false;
return SetTabIcon(pMDIChild->hWnd, hIcon);
}
return false;
}
bool CXTPMDIWndTab::SetTabIcon(HWND hChildWnd, HICON& hIcon)
{
if (!hIcon || !::IsWindow(hChildWnd))
{
return false;
}
m_mapTabIcons.SetAt(hChildWnd, hIcon);
return true;
}
bool CXTPMDIWndTab::SetTabLabel(int iIndex, CString& strLabel)
{
TC_ITEM tci;
tci.mask = TCIF_PARAM;
if (GetItem(iIndex, &tci))
{
MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
ASSERT(pMDIChild != NULL);
if (!pMDIChild)
return false;
return SetTabLabel(pMDIChild->hWnd, strLabel);
}
return false;
}
bool CXTPMDIWndTab::SetTabLabel(HWND hChildWnd, CString& strLabel)
{
if (strLabel.IsEmpty() || !::IsWindow(hChildWnd))
{
return false;
}
m_mapTabLabels.SetAt(hChildWnd, strLabel);
return true;
}
CString CXTPMDIWndTab::GetChildWndText(HWND hWnd) const
{
// Check to see if the user has defined a label for the tab first.
CString strTitle;
if (m_mapTabLabels.Lookup(hWnd, strTitle))
{
return strTitle;
}
// Get a pointer to the frame window.
CMDIChildWnd* pChildFrame = (CMDIChildWnd*)CWnd::FromHandle(hWnd);
if (!::IsWindow(pChildFrame->GetSafeHwnd()))
{
return _T("");
}
// Get the window text for the frame and use it for the tab label.
pChildFrame->GetWindowText(strTitle);
// If the string is empty the document's title.
if (strTitle.IsEmpty())
{
CWnd* pChildWnd = pChildFrame->GetWindow(GW_CHILD);
while (pChildWnd)
{
if (pChildWnd->IsKindOf(RUNTIME_CLASS(CView)))
{
// Get a pointer to the view's document.
CDocument* pDoc = ((CView*)pChildWnd)->GetDocument();
if (pDoc == NULL)
{
return _T("");
}
// Set the return string value
strTitle = pDoc->GetTitle();
// Reset the frames title
pChildFrame->SetWindowText(strTitle);
// Return the document title.
return strTitle;
}
pChildWnd = pChildWnd->GetWindow(GW_HWNDNEXT);
}
}
// Return the MDI frame window's title.
return strTitle;
}
BOOL CXTPMDIWndTab::RefreshActiveSel()
{
// Get the active MDI window, if NULL return FALSE.
HWND hWndActiveChild = m_pMDIFrameWnd->MDIGetActive()->GetSafeHwnd();
if (hWndActiveChild == NULL)
{
m_hActiveChild = NULL;
return FALSE;
}
// Loop through all of the tabs to find the view that has activated.
bool bSelectionChanged = false;
if (POSITION pos = m_arMDIChildern.GetHeadPosition())
{
do
{
MDICHILD* pMDIChild = m_arMDIChildern.GetNext(pos);
ASSERT(pMDIChild != NULL);
// We have found the handle to the active MDI window,
// lets see if the tab is selected.
if (pMDIChild && (pMDIChild->hWnd == hWndActiveChild))
{
// If the active child pointer does not match, then
// make sure that the tab is selected then save the pointer.
bSelectionChanged = hWndActiveChild != m_hActiveChild;
if (bSelectionChanged)
{
SetCurSel(pMDIChild->iItem);
m_hActiveChild = hWndActiveChild;
}
}
}
while (pos != NULL && !bSelectionChanged);
}
return bSelectionChanged;
}
void CXTPMDIWndTab::RefreshTabLabels()
{
// Loop through all of the tabs to find the view that has activated.
POSITION pos = m_arMDIChildern.GetHeadPosition();
while (pos != NULL)
{
bool bSetItem = false;
MDICHILD* pMDIChild = m_arMDIChildern.GetNext(pos);
ASSERT(pMDIChild != NULL);
if (!pMDIChild)
continue;
// Get the window text for the child frame and the tab item.
CString strWindowText = GetChildWndText(pMDIChild->hWnd);
TCHAR szText[_MAX_PATH];
szText[0] = 0;
TC_ITEM tci;
tci.mask = TCIF_TEXT | TCIF_IMAGE;
tci.cchTextMax = _countof(szText);
tci.pszText = szText;
// Get the item data for the tab.
if (GetItem(pMDIChild->iItem, &tci))
{
CString strTabLabel = szText;
if (m_pTheme->GetThemeStyle() != xtpControlThemeOffice2000)
{
OnAddPadding(strWindowText);
}
// If they do not match then update the tab item label.
if (strTabLabel != strWindowText)
{
STRCPY_S(szText, _MAX_PATH, strWindowText);
tci.cchTextMax = strWindowText.GetLength();
bSetItem = true;
}
if (!m_bNoIcons)
{
// Check to see if the user set the icon for the tab label.
HICON hIcon = 0;
if (!m_mapTabIcons.Lookup(pMDIChild->hWnd, hIcon))
{
// The user may have set the icon for the child by calling WM_SETICON. If
// WM_GETICON returns an icon we need to make sure the tab icon has been updated.
hIcon = (HICON)::SendMessage(pMDIChild->hWnd, WM_GETICON, FALSE, 0);
// Insert the icon into map to avoid failed Lookup().
m_mapTabIcons.SetAt(pMDIChild->hWnd, hIcon);
}
// Replace the image in image list ONLY when Lookup() failed.
if ((hIcon != NULL) && (tci.iImage != -1))
{
bSetItem = true;
m_imageList.Replace(tci.iImage, hIcon);
}
}
if (bSetItem)
{
VERIFY(SetItem(pMDIChild->iItem, &tci));
}
}
}
}
void CXTPMDIWndTab::OnIdleUpdateCmdUI()
{
if (m_pMDIFrameWnd)
{
RefreshActiveSel();
RefreshTabLabels();
}
}
void CXTPMDIWndTab::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
RECT& rc = lpncsp->rgrc[0];
if (rc.bottom - rc.top > m_iBorderGap * 2)
{
rc.top += m_iBorderGap;
rc.bottom -= m_iBorderGap;
}
else
{
rc.top = rc.bottom;
}
if (rc.right - rc.left > m_iBorderGap * 2)
{
rc.left += m_iBorderGap;
rc.right -= m_iBorderGap;
}
else
{
rc.left = rc.right;
}
CTabCtrl::OnNcCalcSize(bCalcValidRects, lpncsp);
}
void CXTPMDIWndTab::OnNcPaint()
{
CWindowDC dc(this);
CRect rectClient;
GetClientRect(rectClient);
CRect rectWindow;
GetWindowRect(rectWindow);
rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
if (rectWindow.Width() > rectClient.Width())
{
dc.DrawEdge(rectWindow, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
int nBorder = (rectWindow.Width() - rectClient.Width()) / 2;
if (nBorder > 0)
{
dc.FillSolidRect(rectWindow.left, rectWindow.top, rectWindow.Width(), nBorder, GetSysColor(COLOR_3DFACE));
dc.FillSolidRect(rectWindow.left, rectWindow.top, nBorder, rectWindow.Height(), GetSysColor(COLOR_3DFACE));
dc.FillSolidRect(rectWindow.left, rectWindow.bottom - nBorder, rectWindow.Width(), nBorder, GetSysColor(COLOR_3DFACE));
dc.FillSolidRect(rectWindow.right - nBorder, rectWindow.top, nBorder, rectWindow.Height(), GetSysColor(COLOR_3DFACE));
}
}
}
void CXTPMDIWndTab::OnSelchange(NMHDR* /*pNMHDR*/, LRESULT* pResult)
{
// Get the item data for the currently selected tab.
TC_ITEM tci;
tci.mask = TCIF_PARAM;
if (GetItem(GetCurSel(), &tci))
{
MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
ASSERT(pMDIChild != NULL);
if (!pMDIChild)
return;
// Get the pointer to the currently selected tab window.
CWnd* pActiveWnd = CWnd::FromHandle(pMDIChild->hWnd);
ASSERT_VALID(pActiveWnd);
// Activate the new tab window.
m_pMDIFrameWnd->MDIActivate(pActiveWnd);
}
*pResult = 0;
}
void CXTPMDIWndTab::OnDestroy()
{
CTabCtrl::OnDestroy();
// Delete the image list.
m_imageList.DeleteImageList();
// Set the active and parent windows to NULL.
m_hActiveChild = NULL;
m_pMDIFrameWnd = NULL;
}
int CXTPMDIWndTab::TabFromPoint(CPoint point) const
{
TCHITTESTINFO tch;
memset(&tch, 0, sizeof(TCHITTESTINFO));
if (point == CPoint(0, 0))
{
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
tch.pt = pt;
}
else
{
tch.pt = point;
}
return HitTest(&tch);
}
CMDIChildWnd* CXTPMDIWndTab::GetFrameWnd(int iIndex) const
{
if (iIndex == -1)
iIndex = m_iHitTest;
TC_ITEM tci;
tci.mask = TCIF_PARAM;
if (GetItem(iIndex, &tci))
{
MDICHILD* pMDIChild = (MDICHILD*)tci.lParam;
ASSERT(pMDIChild != NULL);
if (!pMDIChild)
return NULL;
return DYNAMIC_DOWNCAST(CMDIChildWnd, CWnd::FromHandle(pMDIChild->hWnd));
}
return NULL;
}
CMDIChildWnd* CXTPMDIWndTab::GetFrameWnd(CPoint point) const
{
return GetFrameWnd(TabFromPoint(point));
}
void CXTPMDIWndTab::OnRButtonDown(UINT /*nFlags*/, CPoint point)
{
// Get the tab index based upon the cursor position.
m_iHitTest = TabFromPoint(point);
if (m_iHitTest != -1)
{
if (m_popupMenuID != 0)
{
CPoint pt = point;
ClientToScreen(&pt);
CMenu popupMenu;
VERIFY(popupMenu.LoadMenu(m_popupMenuID));
CMenu* pPopup = popupMenu.GetSubMenu(m_nPos);
ASSERT(pPopup != NULL);
if (!pPopup)
return;
if (m_nDefCmd != 0)
{
::SetMenuDefaultItem(pPopup->m_hMenu, m_nDefCmd, FALSE);
}
CWnd* pWndPopupOwner = GetOwner();
ASSERT_VALID(pWndPopupOwner);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
pt.x, pt.y, pWndPopupOwner);
}
}
}
void CXTPMDIWndTab::InitializeFont()
{
HGDIOBJ hFont = XTPAuxData().font.GetSafeHandle();
// if the tabs are vertical, use the vertical menu font.
if ((GetStyle() & TCS_VERTICAL) == TCS_VERTICAL)
hFont = XTPAuxData().fontVert.GetSafeHandle();
if (hFont != NULL)
{
if (XTPSystemVersion()->IsWin95())
PostMessage(WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
else
SendMessage(WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
}
}
void CXTPMDIWndTab::OnTabClose()
{
if (m_pMDIFrameWnd)
{
CMDIChildWnd* pActiveChild = (CMDIChildWnd*)m_pMDIFrameWnd->MDIGetActive();
if (pActiveChild != NULL)
{
pActiveChild->SendMessage(WM_CLOSE);
}
}
}