www.pudn.com > MapXgis.rar > OXTabClientWnd.cpp


// ========================================================================== 
//						Class Implementation :  
//		COXTabClientWnd & COXTabWorkspace & COXTabWorkspaceDropTarget 
// ========================================================================== 
 
// Source file : OXTabClientWnd.cpp 
 
// Copyright ?Dundas Software Ltd. 1997 - 1998, All Rights Reserved                       
 
// ////////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
//#include "SuperTel.h" 
#include "OXTabClientWnd.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
// Change tab on drag over handler 
DROPEFFECT COXTabWorkspaceDropTarget::OnDragOver(CWnd* pWnd,  
												 COleDataObject* pDataObject, 
												 DWORD dwKeyState,  
												 CPoint point) 
{ 
	UNREFERENCED_PARAMETER(pDataObject); 
	UNREFERENCED_PARAMETER(dwKeyState); 
 
	// get the pointer to tab control 
    COXTabWorkspace* pTabWorkspace=(COXTabWorkspace*)pWnd; 
    TC_HITTESTINFO hitTest; 
    hitTest.pt=point; 
     
	// find the drop target item  
    int nItem=pTabWorkspace->HitTest(&hitTest); 
 
	// if found ... 
    if(nItem>=0) 
    { 
		// get the pointer to corresponding MDIChild  
		CWnd* pChildWnd=pTabWorkspace->m_arrTab[nItem].pWnd; 
 
		if(::IsWindow(pChildWnd->GetSafeHwnd())) 
		{ 
			// activate it 
			pTabWorkspace->GetParentFrame()->MDIActivate(pChildWnd); 
		} 
    } 
 
    return DROPEFFECT_NONE; 
} 
 
 
COXTabWorkspace::COXTabWorkspace() 
{ 
	m_pTabClientWnd=NULL; 
	m_dwOffset=ID_TABOFFSET; 
	m_bAcceptDraggedObject=TRUE; 
} 
 
 
COXTabWorkspace::~COXTabWorkspace() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(COXTabWorkspace, CTabCtrl) 
	//{{AFX_MSG_MAP(COXTabWorkspace) 
	ON_WM_CREATE() 
	ON_WM_TIMER() 
	ON_NOTIFY_REFLECT_EX(TCN_SELCHANGE, OnSelchange) 
	ON_WM_LBUTTONDBLCLK() 
	ON_WM_NCCALCSIZE() 
	ON_WM_NCPAINT() 
	ON_WM_DESTROY() 
	ON_WM_CONTEXTMENU()	 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
int COXTabWorkspace::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if(CTabCtrl::OnCreate(lpCreateStruct)==-1) 
		return -1; 
	 
    // set status timer 
    if(SetTimer(IDT_MDI_STATUS_TIMER,500,NULL)==0) 
	{ 
		TRACE(_T("COXTabWorkspace::OnCreate: SetTimer() failed\n")); 
		return -1; 
	} 
     
	// create image list 
	 
    if(!m_imageList.Create(GetSystemMetrics(SM_CXSMICON), 
		GetSystemMetrics(SM_CYSMICON),ILC_COLOR8|ILC_MASK,4,4)) 
	{ 
		TRACE(_T("COXTabWorkspace::OnCreate: Create() image list failed\n")); 
		return -1; 
	} 
 
/*	if(!m_imageList.Create(IDB_BITMAP_TABCTRL,16,1,RGB(255,0,255))) 
	{ 
		TRACE(_T("COXTabWorkspace::OnCreate: Create() image list failed\n")); 
		return -1; 
	} 
*/ 
	// set default font 
	SendMessage(WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT)); 
 
	// set image list that will be in future populated with MDIChild 
	// window icons 
    SetImageList(&m_imageList); 
 
	// register drop-target 
	if(!m_dropTarget.Register(this)) 
	{ 
		TRACE(_T("COXTabWorkspace::OnCreate: failed to register the control with COleDropTarget\n")); 
		TRACE(_T("you've probably forgot to initialize OLE libraries using AfxOleInit function\n")); 
	} 
 
	return 0; 
} 
 
 
void COXTabWorkspace::OnNcCalcSize(BOOL bCalcValidRects,  
								   NCCALCSIZE_PARAMS FAR* lpncsp)  
{ 
	// TODO: Add your message handler code here and/or call default 
	 
	CTabCtrl::OnNcCalcSize(bCalcValidRects, lpncsp); 
 
	// add an offset 
	if(lpncsp->rgrc[0].bottom-lpncsp->rgrc[0].top>2*(int)m_dwOffset) 
	{ 
		lpncsp->rgrc[0].top+=m_dwOffset+1; 
		lpncsp->rgrc[0].bottom-=m_dwOffset-1; 
	} 
	else 
	{ 
		lpncsp->rgrc[0].top=lpncsp->rgrc[0].bottom; 
	} 
 
	if(lpncsp->rgrc[0].right-lpncsp->rgrc[0].left>2*(int)m_dwOffset) 
	{ 
		lpncsp->rgrc[0].left+=m_dwOffset+1; 
		lpncsp->rgrc[0].right-=m_dwOffset+1; 
	} 
	else 
	{ 
		lpncsp->rgrc[0].left=lpncsp->rgrc[0].right; 
	} 
} 
 
void COXTabWorkspace::OnNcPaint()  
{ 
	// TODO: Add your message handler code here 
	CWindowDC dc(this); 
	CRect rectClient; 
	GetClientRect(rectClient); 
	CRect rectWindow; 
	GetWindowRect(rectWindow); 
	ScreenToClient(rectWindow); 
	rectClient.OffsetRect(-rectWindow.left, -rectWindow.top); 
	if(rectClient.top=0) 
    { 
		// get the pointer to the MDIChild that will be activated 
		CWnd* pChildWnd=m_arrTab[GetCurSel()].pWnd; 
 
		if(::IsWindow(pChildWnd->GetSafeHwnd())) 
			GetParentFrame()->MDIActivate(pChildWnd); 
    } 
 
	// update the size and position of the tab control and MDIClient window 
	ASSERT(::IsWindow(GetParentFrame()->GetSafeHwnd())); 
	GetParentFrame()->RecalcLayout(); 
 
	*pResult = 0; 
 
	return FALSE; 
} 
 
 
////////////////////////////////////////////////////////////////////////////// 
// Description: Double click handler - maximizes / restores. 
////////////////////////////////////////////////////////////////////////////// 
void COXTabWorkspace::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
	TCHITTESTINFO HitTestInfo; 
	HitTestInfo.pt=point; 
	 
	int nTabIndex=HitTest(&HitTestInfo); 
 
	if(nTabIndex>=0)		 
	{ 
/*		if(HitTestInfo.flags&TCHT_ONITEMICON) 
		{ 
			TCITEM TabItem; 
			TabItem.mask=TCIF_IMAGE; 
			GetItem(nTabIndex,&TabItem); 
			if(TabItem.iImage==0||TabItem.iImage==1) 
			{ 
				CAACmdLineDoc *pDoc=STATIC_DOWNCAST(CAACmdLineDoc,((CAACmdLineFrame*)m_arrTab[nTabIndex].pWnd)->GetActiveDocument()); 
				pDoc->m_pNe->m_nState^=NE_STATE_LOG; 
			} 
 
		} 
*/		if(HitTestInfo.flags&TCHT_ONITEMLABEL) 
		{ 
			CWnd* pChildWnd=m_arrTab[nTabIndex].pWnd; 
			if(::IsWindow(pChildWnd->GetSafeHwnd())) 
			{ 
				BOOL bMaximize=FALSE; 
				CWnd* pActiveWnd=GetParentFrame()->MDIGetActive(&bMaximize); 
 
				// maximize or restore MDIChild window based on its current state 
				if(pActiveWnd==pChildWnd && bMaximize) 
					GetParentFrame()->MDIRestore(pChildWnd); 
				else 
					GetParentFrame()->MDIMaximize(pChildWnd); 
			} 
		} 
	} 
} 
 
void COXTabWorkspace::OnContextMenu(CWnd* pWnd, CPoint point)  
{ 
	// TODO: Add your message handler code here 
	CPoint ClientPos=point; 
	ScreenToClient(&ClientPos); 
	TCHITTESTINFO HitTestInfo; 
	HitTestInfo.pt=ClientPos; 
 
	int nTabIndex=HitTest(&HitTestInfo); 
	if(nTabIndex==-1) return; 
	 
	if(nTabIndex!=GetCurSel()) 
	{ 
		SetCurSel(nTabIndex); 
		// get the pointer to the MDIChild that will be activated 
		CWnd* pChildWnd=m_arrTab[GetCurSel()].pWnd; 
		if(::IsWindow(pChildWnd->GetSafeHwnd())) 
			GetParentFrame()->MDIActivate(pChildWnd); 
		// update the size and position of the tab control and MDIClient window 
		ASSERT(::IsWindow(GetParentFrame()->GetSafeHwnd())); 
		GetParentFrame()->RecalcLayout(); 
	} 
 
//	if(HitTestInfo.flags&TCHT_ONITEM) 
//	{ 
//		// Get TabItem ImageIndex		 
//		TCITEM TabItem; 
//		TabItem.mask=TCIF_IMAGE; 
//		GetItem(nTabIndex,&TabItem); 
// 
//		//Create Popup Menu  
//		CMenu menu; 
//		CMenu *pPopup; 
//		menu.LoadMenu(IDR_POPUP); 
// 
//		if(TabItem.iImage==0||TabItem.iImage==1) 
//		{ 
//			pPopup=menu.GetSubMenu(1); 
//			pPopup->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,AfxGetMainWnd()); 
//		} 
//		if(TabItem.iImage==2) 
//		{ 
//			pPopup=menu.GetSubMenu(2); 
//			pPopup->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,AfxGetMainWnd()); 
//		} 
//	} 
} 
 
void COXTabWorkspace::UpdateContents(BOOL bAddNewWindows/*=FALSE*/) 
{ 
	ASSERT(m_pTabClientWnd!=NULL); 
	 
    // check MDI windows 
    CMDIFrameWnd* pFrameWnd=GetParentFrame(); 
    if(pFrameWnd==NULL) 
		return; 
	 
	BOOL bRecalc=m_pTabClientWnd->m_bForceToRecalc; 
	 
	// get pointer to currently active MDIChild 
    CWnd* pActiveChildWnd=pFrameWnd->MDIGetActive(NULL); 
	 
    CMDIChildWnd* pChildWnd=NULL; 
    int nActiveIndex=-1; 
	 
	// start enumerating from currently active MDIChild 
    if(pActiveChildWnd!=NULL) 
		pChildWnd=(CMDIChildWnd*)pActiveChildWnd->GetWindow(GW_HWNDFIRST); 
	 
    // flag all current tabs as unfound (for debug purposes in order to check 
	// the integrity of the framework) 
#ifdef _DEBUG 
    for(int nIndex=0; nIndexGetSafeHwnd()); 
		 
		if(nFoundItem!=-1) 
		{ 
			if((pChildWnd->GetStyle()&WS_VISIBLE)==WS_VISIBLE) 
			{ 
				if(pChildWnd==pActiveChildWnd) 
					// found currently active MDIChild 
					nActiveIndex=nFoundItem; 
				 
#ifdef _DEBUG 
				m_arrTab[nFoundItem].bFound=TRUE; 
#endif 
				 
				// update text if necessary 
				if(m_arrTab[nFoundItem].sText!=sWindowText) 
				{ 
					m_arrTab[nFoundItem].sText=sWindowText; 
					 
					TC_ITEM tci; 
					tci.mask=TCIF_TEXT; 
					tci.pszText=(LPTSTR)(LPCTSTR)sWindowText; 
					SetItem(nFoundItem,&tci); 
					 
					bRecalc=TRUE; 
				} 
			} 
			else 
			{ 
				RemoveTabItem(pChildWnd,FALSE); 
				bRecalc=TRUE; 
			} 
		} 
		else if(bAddNewWindows) 
		{ 
			// add item 
			AddTabItem(pChildWnd,FALSE); 
			bRecalc=TRUE; 
		} 
		 
		// get next MDIChild 
		pChildWnd=(CMDIChildWnd*)pChildWnd->GetWindow(GW_HWNDNEXT); 
    } 
	 
#ifdef _DEBUG 
    for(nIndex=0; nIndex=0 && GetCurSel()!=nActiveIndex) 
	{ 
		SetCurSel(nActiveIndex); 
		bRecalc=TRUE; 
	} 
	 
	if(bRecalc) 
	{ 
		// update the size and position of the tab control and MDIClient window 
		if(::IsWindow(GetParentFrame()->GetSafeHwnd())) 
			GetParentFrame()->RecalcLayout(); 
		m_pTabClientWnd->m_bForceToRecalc=FALSE; 
	} 
} 
 
// retrieves pointer to the MDIFrame window 
CMDIFrameWnd* COXTabWorkspace::GetParentFrame() const  
{  
	ASSERT(m_pTabClientWnd!=NULL); 
	ASSERT(m_pTabClientWnd->IsAttached()); 
 
	// request MDIClient for the parent frame 
	CMDIFrameWnd* pParentFrame=m_pTabClientWnd->GetParentFrame(); 
	ASSERT(pParentFrame!=NULL); 
 
	return pParentFrame;  
} 
 
// finds the tab item for specified window. Returns -1 if not found 
int COXTabWorkspace::FindTabItem(const HWND hWnd) const 
{ 
	int nFoundItem=-1; 
	// loop through all tab items 
	for(int nIndex=0; nIndexGetSafeHwnd()==hWnd) 
		{ 
			// double check for window class name 
			TCHAR sWndClass[512]; 
			GetClassName(hWnd,sWndClass,sizeof(sWndClass)/sizeof(TCHAR)); 
			if(m_arrTab[nIndex].sWndClass==sWndClass) 
			{ 
				nFoundItem=nIndex; 
				break; 
			} 
		} 
	} 
 
	return nFoundItem; 
} 
 
//// add new item into the tab control for specified MDIChild. If bRedraw is 
//// set to TRUE then framework will be redrawn in order to show new item. 
//BOOL COXTabWorkspace::AddTabItem(const CWnd* pChildWnd,int nImageIndex/*=0*/,BOOL bRedraw/*=TRUE*/, 
//								 BOOL bOnlyVisible/*=TRUE*/) 
//{ 
//	ASSERT(pChildWnd!=NULL); 
//	ASSERT(::IsWindow(pChildWnd->GetSafeHwnd())); 
// 
//	// make sure we add MDIChild window 
//	if((pChildWnd->GetExStyle()&WS_EX_MDICHILD)==0) 
//		return FALSE; 
// 
//	// make sure it is visible at the moment 
//	if(bOnlyVisible && (pChildWnd->GetStyle()&WS_VISIBLE)==0) 
//		return FALSE; 
// 
//	// work out icon... 
//	TCHAR sWndClass[512]; 
//	WNDCLASSEX classInfo={ sizeof (WNDCLASSEX) }; 
//	GetClassName(pChildWnd->m_hWnd,sWndClass,sizeof(sWndClass)/sizeof(TCHAR)); 
//	GetClassInfoEx(AfxGetInstanceHandle(),sWndClass,&classInfo); 
//     
///*	HICON hIcon=(HICON)::GetClassLong(pChildWnd->m_hWnd,GCL_HICONSM); 
//	if(hIcon==NULL) 
//	{ 
//		CWnd* pWnd=(CWnd*)pChildWnd; 
//		hIcon=(HICON)pWnd->SendMessage(WM_GETICON,ICON_SMALL); 
//		if(hIcon==NULL) 
//		{ 
//			hIcon=(HICON)::GetClassLong(pChildWnd->m_hWnd,GCL_HICON); 
//			if(hIcon==NULL) 
//				hIcon=(HICON)pWnd->SendMessage(WM_GETICON,ICON_BIG); 
//		} 
//	} 
// 
//	int nImageIndex=-1; 
//	if(hIcon!=NULL) 
//	{ 
//		// check if we already included the specifyed item into the tab control 
//		// image list 
//		for(nImageIndex=0; nImageIndexGetSafeHwnd())); 
//		GetParentFrame()->RecalcLayout(); 
//	} 
// 
//	return TRUE; 
//} 
 
// add new item into the tab control for specified MDIChild. If bRedraw is 
// set to TRUE then framework will be redrawn in order to show new item. 
BOOL COXTabWorkspace::AddTabItem(const CWnd* pChildWnd, BOOL bRedraw/*=TRUE*/, 
								 BOOL bOnlyVisible/*=TRUE*/) 
{ 
	ASSERT(pChildWnd!=NULL); 
	ASSERT(::IsWindow(pChildWnd->GetSafeHwnd())); 
	 
	// make sure we add MDIChild window 
	if((pChildWnd->GetExStyle()&WS_EX_MDICHILD)==0) 
		return FALSE; 
	 
	// make sure it is visible at the moment 
	if(bOnlyVisible && (pChildWnd->GetStyle()&WS_VISIBLE)==0) 
		return FALSE; 
	 
	// work out icon... 
	TCHAR sWndClass[512]; 
	WNDCLASSEX classInfo={ sizeof (WNDCLASSEX) }; 
	GetClassName(pChildWnd->m_hWnd,sWndClass,sizeof(sWndClass)/sizeof(TCHAR)); 
	GetClassInfoEx(AfxGetInstanceHandle(),sWndClass,&classInfo); 
     
	HICON hIcon=(HICON)::GetClassLong(pChildWnd->m_hWnd,GCL_HICONSM); 
	if(hIcon==NULL) 
	{ 
		CWnd* pWnd=(CWnd*)pChildWnd; 
		hIcon=(HICON)pWnd->SendMessage(WM_GETICON,ICON_SMALL); 
		if(hIcon==NULL) 
		{ 
			hIcon=(HICON)::GetClassLong(pChildWnd->m_hWnd,GCL_HICON); 
			if(hIcon==NULL) 
				hIcon=(HICON)pWnd->SendMessage(WM_GETICON,ICON_BIG); 
		} 
	} 
	 
	int nImageIndex=-1; 
	if(hIcon!=NULL) 
	{ 
		// check if we already included the specifyed item into the tab control 
		// image list 
		for(nImageIndex=0; nImageIndexGetSafeHwnd())); 
		GetParentFrame()->RecalcLayout(); 
	} 
	 
	return TRUE; 
} 
 
// remove item from the tab control that corresponds to specified MDIChild 
BOOL COXTabWorkspace::RemoveTabItem(const CWnd* pChildWnd, BOOL bRedraw/*=TRUE*/) 
{ 
	ASSERT(pChildWnd!=NULL); 
	ASSERT(::IsWindow(pChildWnd->GetSafeHwnd())); 
	ASSERT((pChildWnd->GetExStyle()&WS_EX_MDICHILD)!=0); 
 
	// find the item 
	int nTabItem=FindTabItem(pChildWnd); 
 
	if(nTabItem==-1) 
		return FALSE; 
 
	// delete item 
	DeleteItem(nTabItem); 
	// remove entry from the internal array of created items 
	m_arrTab.RemoveAt(nTabItem); 
 
	// update the size and position of the tab control and MDIClient window 
	if(bRedraw) 
	{ 
		if(::IsWindow(GetParentFrame()->GetSafeHwnd())) 
			GetParentFrame()->RecalcLayout(); 
	} 
 
	return TRUE; 
} 
 
 
CString COXTabWorkspace::GetTextForTabItem(const CWnd* pChildWnd) const 
{ 
	ASSERT(pChildWnd!=NULL); 
	ASSERT(pChildWnd->IsKindOf(RUNTIME_CLASS(CMDIChildWnd))); 
	 
	CString sWindowText=(LPCTSTR)((CWnd*)pChildWnd)-> 
		SendMessage(OXWM_MTI_GETWINDOWTEXT); 
	 
	if(sWindowText.IsEmpty()) 
	{ 
		CDocument* pDoc=((CMDIChildWnd*)pChildWnd)->GetActiveDocument(); 
		if(pDoc!=NULL) 
			sWindowText=pDoc->GetTitle(); 
			 
		if(sWindowText.IsEmpty()) 
			pChildWnd->GetWindowText(sWindowText); 
	} 
	return sWindowText; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// COXTabClientWnd 
 
COXTabClientWnd::COXTabClientWnd() 
{ 
	m_pParentFrame=NULL; 
	m_bForceToRecalc=FALSE; 
} 
 
COXTabClientWnd::~COXTabClientWnd() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(COXTabClientWnd, CWnd) 
	//{{AFX_MSG_MAP(COXTabClientWnd) 
	ON_MESSAGE(WM_MDIACTIVATE,OnMDIActivate) 
	ON_MESSAGE(WM_MDICREATE,OnMDICreate) 
	ON_MESSAGE(WM_MDIDESTROY,OnMDIDestroy) 
	ON_WM_SIZE() 
	ON_WM_SHOWWINDOW() 
	ON_WM_CONTEXTMENU()	 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
// subclasses MDIClient window of the specified MDIFrame window and  
// create COXTabWorkspace control to manage MDIChild window 
BOOL COXTabClientWnd::Attach(const CMDIFrameWnd* pParentFrame,  
							 DWORD dwTabCtrlStyle/*=DEFAULT_TABCTRLSTYLE*/) 
{ 
	ASSERT(pParentFrame!=NULL); 
	ASSERT(::IsWindow(pParentFrame->GetSafeHwnd())); 
 
	// check if already attached 
	if(IsAttached()) 
	{ 
		TRACE(_T("COXTabClientWnd::Attach: window has already been attached. Call Detach() function before!\n")); 
		return FALSE; 
	} 
 
	// make sure the specified window is/derived from CMDIFrameWnd class 
	if(!pParentFrame->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))) 
	{ 
		TRACE(_T("COXTabClientWnd::Attach: specified frame window is not of CMDIFrameWnd class (or derived)!\n")); 
		return FALSE; 
	} 
 
	// try to sublass MDIClient window 
	if(!SubclassWindow(pParentFrame->m_hWndMDIClient)) 
	{ 
		TRACE(_T("COXTabClientWnd::Attach: failed to subclass MDI Client window\n")); 
		return FALSE; 
	} 
 
	// save the pointer to parent MDIFrame 
	m_pParentFrame=(CMDIFrameWnd*)pParentFrame; 
 
 
	// create tab control 
	// 
	 
	ASSERT(!::IsWindow(m_tab.GetSafeHwnd())); 
	CRect rect(0,0,0,0); 
 
	// make sure WS_POPUP style is not used 
	ASSERT((dwTabCtrlStyle&WS_POPUP)==0); 
	// make sure the following styles are used  
	dwTabCtrlStyle|=(TCS_FOCUSNEVER|WS_VISIBLE|WS_CHILD); 
	m_tab.m_pTabClientWnd=this; 
	// try to create the tab control 
    if(!m_tab.Create(dwTabCtrlStyle,rect,m_pParentFrame,IDC_TABWORKSPACE)) 
	{ 
		TRACE(_T("COXTabClientWnd::Attach: failed to create tab control\n")); 
		// if failed we detach the parent frame 
		Detach(); 
		return FALSE; 
	} 
	 
	// update the size and position of the tab control and MDIClient window 
	m_pParentFrame->RecalcLayout(); 
 
	// populate tab control with MDIChild windows if any exist at the moment 
	m_tab.UpdateContents(TRUE); 
 
	return TRUE; 
} 
 
 
// unsubclasses MDIClient window and destroy the COXTabWorkspace control  
// that was used to manage MDIChild window 
BOOL COXTabClientWnd::Detach() 
{ 
	// check if any attached 
	if(!IsAttached()) 
	{ 
		TRACE(_T("COXTabClientWnd::Attach: there is nothing to detach! Window hasn't been attached!\n")); 
		return FALSE; 
	} 
 
	// destroy tab control 
	if(::IsWindow(m_tab.GetSafeHwnd())) 
		m_tab.DestroyWindow(); 
 
	m_tab.m_pTabClientWnd=NULL; 
 
	// unsubclass MDIClient window 
	UnsubclassWindow(); 
 
	// update the size and position of the MDIClient window 
	if(::IsWindow(m_pParentFrame->GetSafeHwnd())) 
		m_pParentFrame->RecalcLayout(); 
 
	m_pParentFrame=NULL; 
 
	return TRUE; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// COXTabClientWnd message handlers 
 
 
// crucial function that calculate the size of MDIClient window. Called 
// by parent MDIFrame window 
void COXTabClientWnd::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)  
{ 
	// TODO: Add your specialized code here and/or call the base class 
 
    // now do the laying out 
    HDWP dwh=BeginDeferWindowPos(2); 
 
    // move tab window 
    if(::IsWindow(m_tab.m_hWnd) && (m_tab.GetStyle()&WS_VISIBLE)==WS_VISIBLE) 
    { 
		// get the size of MDIClient the way it fits into the client area of 
		// the tab control 
		DWORD dwTabStyle=m_tab.GetStyle(); 
		if((dwTabStyle&TCS_BUTTONS)==TCS_BUTTONS &&  
			(dwTabStyle&TCS_VERTICAL)==TCS_VERTICAL) 
		{ 
			CRect rectTab=lpClientRect; 
 
			CRect rect(lpClientRect->left,lpClientRect->top, 
				lpClientRect->left+lpClientRect->bottom-lpClientRect->top, 
				lpClientRect->top+lpClientRect->right-lpClientRect->left); 
 
			// move tab control 
			::SetWindowPos(m_tab.m_hWnd,NULL, 
				rect.left,rect.top,rect.Width(), 
				rect.Height(),SWP_NOZORDER|SWP_NOREDRAW); 
 
			rect.DeflateRect(m_tab.GetOffset(),m_tab.GetOffset()); 
			CRect rectCopy=rect; 
 
			// adjust the size of tab control 
			lpClientRect->left+=m_tab.GetOffset();        
			lpClientRect->top+=m_tab.GetOffset();        
			lpClientRect->right-=m_tab.GetOffset();        
			lpClientRect->bottom-=m_tab.GetOffset();        
 
			if((dwTabStyle&TCS_RIGHT)==TCS_RIGHT) 
			{ 
				m_tab.ModifyStyle(TCS_RIGHT|TCS_VERTICAL,0,SWP_NOREDRAW); 
				m_tab.AdjustRect(FALSE,rect); 
				m_tab.ModifyStyle(0,TCS_RIGHT|TCS_VERTICAL,SWP_NOREDRAW); 
			} 
			else 
			{ 
				m_tab.ModifyStyle(TCS_VERTICAL,0,SWP_NOREDRAW); 
				m_tab.AdjustRect(FALSE,rect); 
				m_tab.ModifyStyle(0,TCS_VERTICAL,SWP_NOREDRAW); 
				lpClientRect->left+=rect.top-rectCopy.top; 
			} 
 
			lpClientRect->top+=rect.left-rectCopy.left; 
			lpClientRect->bottom=lpClientRect->top+rect.Width(); 
			lpClientRect->right=lpClientRect->left+rect.Height(); 
 
			// move tab control 
			dwh=::DeferWindowPos(dwh,m_tab.m_hWnd,NULL,rectTab.left, 
				rectTab.top,rectTab.Width(), 
				rectTab.Height(),SWP_NOZORDER); 
		} 
		else 
		{ 
			CRect rectTab=lpClientRect; 
 
			// move tab control 
			dwh=::DeferWindowPos(dwh,m_tab.m_hWnd,NULL,lpClientRect->left, 
				lpClientRect->top, 
				lpClientRect->right-lpClientRect->left, 
				lpClientRect->bottom-lpClientRect->top, SWP_NOZORDER); 
 
			// adjust the size of tab control 
			if(lpClientRect->bottom-lpClientRect->top>2*(int)m_tab.GetOffset()) 
			{ 
				lpClientRect->top+=m_tab.GetOffset(); 
				lpClientRect->bottom-=m_tab.GetOffset(); 
			} 
			else 
			{ 
				lpClientRect->top=lpClientRect->bottom; 
			} 
 
			if(lpClientRect->right-lpClientRect->left>2*(int)m_tab.GetOffset()) 
			{ 
				lpClientRect->left+=m_tab.GetOffset(); 
				lpClientRect->right-=m_tab.GetOffset(); 
			} 
			else 
			{ 
				lpClientRect->left=lpClientRect->right; 
			} 
 
			if((dwTabStyle&TCS_BUTTONS)==TCS_BUTTONS &&  
				(dwTabStyle&TCS_VERTICAL)!=TCS_VERTICAL &&  
					(dwTabStyle&TCS_BOTTOM)==TCS_BOTTOM) 
			{ 
				int nTop=lpClientRect->top; 
 
				m_tab.ModifyStyle(TCS_BOTTOM,0,SWP_NOREDRAW); 
				m_tab.AdjustRect(FALSE,lpClientRect); 
				m_tab.ModifyStyle(0,TCS_BOTTOM,SWP_NOREDRAW); 
 
				lpClientRect->bottom-=lpClientRect->top-nTop; 
				lpClientRect->top-=lpClientRect->top-nTop; 
 
			} 
			else 
			{ 
				m_tab.AdjustRect(FALSE,lpClientRect); 
			} 
		} 
 
		if(lpClientRect->bottomtop ||  
			lpClientRect->rightleft) 
			::memset(lpClientRect,0,sizeof(RECT)); 
 
		::ShowWindow(m_tab.m_hWnd,SW_SHOWNA); 
    } 
 
	// move MDIClient window 
    dwh=::DeferWindowPos(dwh,m_hWnd,NULL,lpClientRect->left,lpClientRect->top, 
		lpClientRect->right-lpClientRect->left, 
		lpClientRect->bottom-lpClientRect->top, 
		SWP_NOZORDER); 
 
    EndDeferWindowPos(dwh); 
 
	CWnd::CalcWindowRect(lpClientRect, nAdjustType); 
} 
 
// handler for WM_MDIACTIVATE message. Will select corresponding  
// tab control item 
LONG COXTabClientWnd::OnMDIActivate(UINT wParam, LONG lParam) 
{ 
	UNREFERENCED_PARAMETER(lParam); 
 
	LONG lResult=Default(); 
	 
	HWND hActiveWnd=(HWND)wParam; 
	// find corresponding tab control item  
	int nTabItem=m_tab.FindTabItem(hActiveWnd); 
	if(nTabItem!=-1) 
	{ 
		ASSERT(nTabItem>=0 && nTabItem