// ========================================================================== // Class Implementation : // COXTabClientWnd & COXTabWorkspace & COXTabWorkspaceDropTarget // ========================================================================== // Source file : OXTabClientWnd.cpp // Version: 9.3 // This software along with its related components, documentation and files ("The Libraries") // is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is // governed by a software license agreement ("Agreement"). Copies of the Agreement are // available at The Code Project (www.codeproject.com), as part of the package you downloaded // to obtain this file, or directly from our office. For a copy of the license governing // this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900. // ////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "OXTabClientWnd.h" #include "OXSkins.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; if (!pTabWorkspace || !pTabWorkspace->IsAcceptingDraggedObject()) return DROPEFFECT_NONE; TC_HITTESTINFO hitTest; hitTest.pt=point; // Find the drop target item int nItem=pTabWorkspace->HitTest(&hitTest); // If found ... if(nItem>=0 && m_nOldItem!=nItem) { // Get the pointer to the corresponding MDIChild CWnd* pChildWnd=pTabWorkspace->m_arrTab[nItem].pWnd; if(::IsWindow(pChildWnd->GetSafeHwnd())) { // Activate it pTabWorkspace->GetParentFrame()->MDIActivate(pChildWnd); m_nOldItem=pTabWorkspace->HitTest(&hitTest); } } return DROPEFFECT_NONE; } void COXTabWorkspaceDropTarget::OnDragLeave(CWnd* pWnd) { m_nOldItem=-1; COleDropTarget::OnDragLeave(pWnd); } //////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC(COXTabWorkspace, COXSkinnedTabCtrl) COXTabWorkspace::COXTabWorkspace() { m_pTabClientWnd=NULL; m_dwOffset=ID_TABOFFSET; m_bAcceptDraggedObject=TRUE; m_pTabSkin = NULL; } COXTabWorkspace::~COXTabWorkspace() { } BEGIN_MESSAGE_MAP(COXTabWorkspace, COXSkinnedTabCtrl) //{{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() //}}AFX_MSG_MAP ON_WM_ERASEBKGND() 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; } // Set default font SendMessage(WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT)); // Set image list so that it will be 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; lpncsp->rgrc[0].bottom-=m_dwOffset; } 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; lpncsp->rgrc[0].right-=m_dwOffset; } 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.topDrawMDITabBorder(&dc, rectWindow, this); // Do not call CTabCtrl::OnNcPaint() for painting messages } void COXTabWorkspace::OnDestroy() { CTabCtrl::OnDestroy(); // TODO: Add your message handler code here // Delete image list VERIFY(m_imageList.DeleteImageList()); // Kill update timer VERIFY(KillTimer(IDT_MDI_STATUS_TIMER)); // Clean up internal arrays m_arrImage.RemoveAll(); m_arrTab.RemoveAll(); } ////////////////////////////////////////////////////////////////////////////// // Description: Timer handler - periodically refreshes tabs, determines // active MDIChild and updates window names ////////////////////////////////////////////////////////////////////////////// void COXTabWorkspace::OnTimer(UINT nIDEvent) { if(nIDEvent!=IDT_MDI_STATUS_TIMER) { CTabCtrl::OnTimer(nIDEvent); return; } // Update active MDIChild and window text UpdateContents(TRUE); } ////////////////////////////////////////////////////////////////////////////// // Description: Selection change handler ////////////////////////////////////////////////////////////////////////////// BOOL COXTabWorkspace::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult) { UNREFERENCED_PARAMETER(pNMHDR); if(GetCurSel()>=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) { UNREFERENCED_PARAMETER(nFlags); UNREFERENCED_PARAMETER(point); if(GetCurSel()>=0) { // Get the pointer to the MDIChild that will be maximized/restored CWnd* pChildWnd=m_arrTab[GetCurSel()].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); } } } // Scans through all MDIChild windows and refreshes window names and // current active window. If bAddNewWindows is set to TRUE then if any // new MDIChild is found it will be added to the tab control void COXTabWorkspace::UpdateContents(BOOL bAddNewWindows/*=FALSE*/, BOOL bUpdateWindowsInfo/*=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 int nIndex=0; for(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; //replace "&" characters for doubles "&&" int nFind=sWindowText.Find(TEXT('&')); while (nFind != -1) { if (nFindGetSafeHwnd()); int nImageIndex=(hIcon==NULL ? -1 : AddTabItemIcon(hIcon)); if(nImageIndex!=tci.iImage) { tci.iImage=nImageIndex; SetItem(nFoundItem,&tci); } } } else { nInsertIndex--; if(nActiveIndex!=-1 && nActiveIndex>nFoundItem) { nActiveIndex--; } RemoveTabItem(pChildWnd,FALSE); bRecalc=TRUE; } } else if(bAddNewWindows) { if(nActiveIndex!=-1 && nActiveIndex>=nInsertIndex) { nActiveIndex++; } // add item InsertTabItem(nInsertIndex,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; } // Inserts 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::InsertTabItem(int nIndex, const CWnd* pChildWnd, BOOL bRedraw/*=TRUE*/, BOOL bOnlyVisible/*=TRUE*/) { ASSERT(pChildWnd!=NULL); ASSERT(::IsWindow(pChildWnd->GetSafeHwnd())); ASSERT(nIndex>=0 && nIndex<=m_arrTab.GetSize()); // 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 window class TCHAR sWndClass[512]; ::GetClassName(pChildWnd->GetSafeHwnd(),sWndClass, sizeof(sWndClass)/sizeof(TCHAR)); // WNDCLASSEX classInfo={ sizeof(WNDCLASSEX) }; // ::GetClassInfoEx(AfxGetInstanceHandle(),sWndClass,&classInfo); // Get icon HICON hIcon=GetWindowIcon(pChildWnd->GetSafeHwnd()); int nImageIndex=(hIcon==NULL ? -1 : AddTabItemIcon(hIcon)); // Set item text to window text CString sWindowText=GetTextForTabItem(pChildWnd); TC_ITEM tci; tci.mask=TCIF_TEXT|TCIF_IMAGE; tci.pszText=(TCHAR*)(void*)(const TCHAR*)sWindowText; tci.iImage=nImageIndex; // Insert new tab control item VERIFY(InsertItem(nIndex,&tci)!=-1); // Redraw the tab control if(!m_arrTab.GetSize() && bRedraw) InvalidateRect(NULL); // Save information about new entry TAB_ITEM_ENTRY newTabItemEntry; m_arrTab.Add(newTabItemEntry); for(int nTabItemIndex=PtrToInt(m_arrTab.GetSize())-1; nTabItemIndex>nIndex; nTabItemIndex--) { m_arrTab[nTabItemIndex]=m_arrTab[nTabItemIndex-1]; } newTabItemEntry.sText=sWindowText; newTabItemEntry.pWnd=(CWnd*)pChildWnd; newTabItemEntry.bFound=TRUE; newTabItemEntry.sWndClass=sWndClass; m_arrTab.SetAt(nIndex,newTabItemEntry); // Update the size and position of the tab control and MDIClient window if(bRedraw) { ASSERT(::IsWindow(GetParentFrame()->GetSafeHwnd())); 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 the 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()) { if(sWindowText.IsEmpty()) pChildWnd->GetWindowText(sWindowText); } return sWindowText; } HICON COXTabWorkspace::GetWindowIcon(HWND hWnd) { ASSERT(::IsWindow(hWnd)); // Work out icon... CWnd* pWnd=CWnd::FromHandle(hWnd); // Work out icon... HICON hIcon=(HICON)pWnd->SendMessage(WM_GETICON,ICON_SMALL); if(hIcon==NULL) { hIcon=(HICON)(INT_PTR)::GetClassLongPtr(hWnd,GCL_HICONSM); if(hIcon==NULL) { hIcon=(HICON)pWnd->SendMessage(WM_GETICON,ICON_BIG); if(hIcon==NULL) { hIcon=(HICON)(INT_PTR)::GetClassLongPtr(hWnd,GCL_HICON); } } } return hIcon; } int COXTabWorkspace::AddTabItemIcon(HICON hIcon) { ASSERT(hIcon!=NULL); // Check if we already included the specified item into the tab control // image list int nImageIndex=0; for(nImageIndex=0; nImageIndexGetSafeHwnd())); // 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; } // Check if there is CWnd object attached to MDIClient CWnd* pMDIClientWnd=CWnd::FromHandlePermanent(pParentFrame->m_hWndMDIClient); if(pMDIClientWnd!=NULL) { TRACE(_T("COXTabClientWnd::Attach: MDIClient window has already been subclassed\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 destroys 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 calculates 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 the 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 { // This code is introduced because of severe bug in CTabCtrl MFC // class, which caused a crash. Crash will appear if only one tab // is present. This code will add temporarily one more tab and // hide tabs. // The number of tabs int nNumOfItems = m_tab.GetItemCount(); // Find the size of Tabs RECT itemRect; m_tab.GetItemRect(nNumOfItems-1, &itemRect); if (nNumOfItems == 1 && !m_bOneTabMode || nNumOfItems == 2 && m_bOneTabMode) { if( itemRect.right - itemRect.left + 50 < lpClientRect->right - lpClientRect->left ) { if( m_bOneTabMode == TRUE ) { m_tab.DeleteItem(nNumOfItems-1); m_bOneTabMode = FALSE; } m_tab.AdjustRect(FALSE,lpClientRect); } else { if( nNumOfItems == 1 ) { m_tab.InsertItem(nNumOfItems,_T("")); m_bOneTabMode = TRUE; } } } else m_tab.AdjustRect(FALSE,lpClientRect); } } if(lpClientRect->bottomtop || lpClientRect->rightleft) ::memset(lpClientRect,0,sizeof(RECT)); ::ShowWindow(m_tab.m_hWnd,SW_SHOWNA); } //lpClientRect->left -= 5; //lpClientRect->right += 5; //lpClientRect->bottom += 5; GetTabSkin()->AdjustChildItemRect(lpClientRect, 5, &m_tab); // 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 a WM_MDIACTIVATE message. Will select corresponding // tab control item LRESULT COXTabClientWnd::OnMDIActivate(UINT wParam, LONG lParam) { UNREFERENCED_PARAMETER(lParam); LRESULT lResult=Default(); HWND hActiveWnd=(HWND)(INT_PTR)wParam; // Find corresponding tab control item int nTabItem=m_tab.FindTabItem(hActiveWnd); if(nTabItem!=-1) { ASSERT(nTabItem>=0 && nTabItem