// BSWndContainer.cpp : implementation file // #include "stdafx.h" #include "BSWndContainer.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CBSWndContainer CBSWndContainer::CBSWndContainer() { // init active page pointer m_pActivePage = NULL; // init window state m_bFullScreen = FALSE; // Full screen sign m_bMultiScreen = TRUE; // Multiple-window sign m_bAutoAdjustPos= FALSE; // Auto adjust sign SetDrawActivePage(TRUE); // Enable frame m_nShowPortion=100; // Display proportion } CBSWndContainer::~CBSWndContainer() { // remove all pages while(!m_PageList.IsEmpty()) m_PageList.RemoveHead(); } BEGIN_MESSAGE_MAP(CBSWndContainer, CWnd) //{{AFX_MSG_MAP(CBSWndContainer) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBSWndContainer member functions /////////////////////////////////////////////////// // call this function to create container object. // it is override from cwnd class BOOL CBSWndContainer::Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext ) { dwStyle|=WS_EX_TOOLWINDOW; return CWnd::Create(lpszClassName,lpszWindowName,dwStyle,rect,pParentWnd,nID,pContext ); } /////////////////////////////////////////////////// // call this function to add a page wnd to // container. if success retrun TRUE,else return // FALSE. BOOL CBSWndContainer::AddPage(CWnd *pWnd, BOOL bRepaint) { // check parameter if( !pWnd || !IsWindow(pWnd->m_hWnd) ) return FALSE; // check list POSITION pos=m_PageList.Find(pWnd); if(pos!=NULL) { TRACE("This Window has been added to container, the operation will terminate.\n"); return TRUE; } // added page m_PageList.AddTail(pWnd); if( m_bDrawActive ) DrawActivePage(FALSE); // reset active page SetActivePage(pWnd, bRepaint); return TRUE; } /////////////////////////////////////////////////// // call this function to remove a page wnd from // container. CWnd *CBSWndContainer::DelPage(CWnd *pWnd) { // check list POSITION pos=m_PageList.Find(pWnd); if(pos==NULL) { TRACE("This Window is not a member of container, the operation will terminate.\n"); return NULL; } if(pWnd==m_pActivePage) if(m_pActivePage==GetPrevPage(pWnd))//m_PageList.IsEmpty()?NULL:m_PageList.GetHead(); m_pActivePage=NULL; else m_pActivePage=GetPrevPage(pWnd); m_PageList.RemoveAt(pos); if (pWnd) { pWnd->ShowWindow(SW_HIDE); } // Invalidate(); return pWnd; } /////////////////////////////////////////////////// // call this function to remove active page from // container. CWnd *CBSWndContainer::DelPage() { return DelPage(m_pActivePage); } /////////////////////////////////////////////////// // call this function to set a page to be active // page. void CBSWndContainer::SetActivePage(CWnd *pWnd, BOOL bRepaint) { // check parameter if( !pWnd || !IsWindow(pWnd->m_hWnd) ) return; // if pWnd is the Active Page, return if( m_pActivePage==pWnd ) return; // check list POSITION pos=m_PageList.Find(pWnd); if(pos==NULL) { TRACE("__This Window is not a member of container, the operation will terminate.\n"); return; } if(bRepaint) UpdateWnd(); if( m_bDrawActive ) DrawActivePage(FALSE); m_pActivePage=pWnd; if( m_bDrawActive ) DrawActivePage(TRUE); } /////////////////////////////////////////////////// // call this function to get the active page's // pointer. if no active page,return NULL; CWnd *CBSWndContainer::GetActivePage() { return m_pActivePage; } CWnd *CBSWndContainer::GetTailPage() { return m_PageList.GetTail(); } /////////////////////////////////////////////////// // call this function to get the next page by // the page that user defined. if the defined // page is not find in container, return NULL. CWnd *CBSWndContainer::GetNextPage(CWnd *pWnd) { // check parameter if( !pWnd || !IsWindow(pWnd->m_hWnd) ) return NULL; // check list POSITION pos=m_PageList.Find(pWnd); if(pos==NULL) { TRACE("This Window is not a member of container, the operation will terminate.\n"); return NULL; } // m_PageList.GetNext(pos); if(pos==NULL) return m_PageList.GetHead(); else return m_PageList.GetNext(pos); } /////////////////////////////////////////////////// // call this function to get the prev page by // the page that user defined. if the defined // page is not find in container,return NULL. CWnd *CBSWndContainer::GetPrevPage(CWnd *pWnd) { // check parameter if( !pWnd || !IsWindow(pWnd->m_hWnd) ) return NULL; // check list POSITION pos=m_PageList.Find(pWnd); if(pos==NULL) { TRACE("This Window is not a member of container, the operation will terminate.\n"); return NULL; } // m_PageList.GetPrev(pos); if(pos==NULL) return m_PageList.GetTail(); else return m_PageList.GetPrev(pos); } CWnd *CBSWndContainer::GetPage(int nIndex) { CWnd *pRet = NULL; POSITION pos = m_PageList.FindIndex(nIndex); if(pos == NULL) return pRet; return m_PageList.GetAt(pos); } int CBSWndContainer::GetCount() const { return m_PageList.GetCount(); } /////////////////////////////////////////////////// // call this function to page wnds,when // the window is resized. void CBSWndContainer::UpdateWnd() { if(!IsWindowVisible()||IsIconic()) return; ///////////////////// //Calculate display total zone //To get current window device coordinates CRect rtContainer; GetClientRect(&rtContainer); GetShowRect(&rtContainer); rtContainer.DeflateRect(1,1); //Adjust Container position if(m_bAutoAdjustPos) AdjustRect(&rtContainer); ///////////////////// // if(m_bMultiScreen) { //Multiple-window status CRect rt; int nCount=m_PageList.GetCount(); int i=0; for(POSITION pos=m_PageList.GetHeadPosition();pos!=NULL;) { CWnd *p=m_PageList.GetNext(pos); rt=rtContainer; CalcPageRect(&rt,i,nCount); rt.DeflateRect(WINDOW_SPACE,WINDOW_SPACE,WINDOW_SPACE,WINDOW_SPACE); p->MoveWindow(&rt); p->ShowWindow(SW_SHOW); i++; } if( m_bDrawActive && m_PageList.GetCount()>1 ) DrawActivePage(TRUE); } else { //One-window status for(POSITION pos=m_PageList.GetHeadPosition();pos!=NULL;) { CWnd *p=m_PageList.GetNext(pos); if(p==m_pActivePage) p->MoveWindow(&rtContainer); else { if(m_bFullScreen) p->MoveWindow(0,0,1,1); else p->MoveWindow(rtContainer.right+1,rtContainer.bottom+1,1,1); } } } } /////////////////////////////////////////////////// // full screen void CBSWndContainer::SetFullScreen(BOOL bFlag) { if(bFlag==m_bFullScreen) return; if( bFlag ) {//Full screen //Get displayer resolution int cx=GetSystemMetrics(SM_CXSCREEN); int cy=GetSystemMetrics(SM_CYSCREEN); //Save position information GetWindowPlacement(&_temppl); //Modify style ModifyStyle(WS_CHILD,WS_POPUP); //Modify main-window _tempparent=SetParent(NULL); _tempparent->ShowWindow(SW_HIDE); //Move window MoveWindow(0,0,cx,cy); // SetWindowPos(&wndTopMost,0,0,cx,cy,NULL); } else {//Restore //Restore main window _tempparent->ShowWindow(SW_SHOW); SetParent(_tempparent); //Restore style ModifyStyle(WS_POPUP,WS_CHILD); //Restore position SetWindowPlacement(&_temppl); } m_bFullScreen=bFlag; Invalidate(); } BOOL CBSWndContainer::GetFullScreen() { return m_bFullScreen; } /////////////////////////////////////////////////// // multiscreen void CBSWndContainer::SetMultiScreen(BOOL bFlag) { if(m_bMultiScreen==bFlag) return; m_bMultiScreen=bFlag; Invalidate(); } BOOL CBSWndContainer::GetMultiScreen() { return m_bMultiScreen; } ////////////////////////////////////////////////// // autoadjustpos void CBSWndContainer::SetAutoAdjustPos(BOOL bFlag) { if(m_bAutoAdjustPos==bFlag) return; m_bAutoAdjustPos=bFlag; Invalidate(); } BOOL CBSWndContainer::GetAutoAdjustPos() { return m_bAutoAdjustPos; } ////////////////////////////////////////////////// // draw active page void CBSWndContainer::SetDrawActivePage(BOOL bFlag,COLORREF clrTopLeft,COLORREF clrBottomRight) { if(m_bDrawActive==bFlag) return; if(bFlag) { m_clrTopLeft=clrTopLeft; m_clrBottomRight=clrBottomRight; } m_bDrawActive=bFlag; DrawActivePage(bFlag); } BOOL CBSWndContainer::GetDrawActivePage() { return m_bDrawActive; } ////////////////////////////////////////////////// // Display percentage // 40 <= nPortion <=100 void CBSWndContainer::SetShowPortion(int nPortion) { if(m_nShowPortion==nPortion) return; if(m_nShowPortion<40) m_nShowPortion=40; if(m_nShowPortion>100) m_nShowPortion=100; m_nShowPortion=nPortion; Invalidate(); } int CBSWndContainer::GetShowPortion() { return m_nShowPortion; } /////////////////////////////////////////////////// // clean the no useful page in the container, // return the page count. int CBSWndContainer::UpdateList() { POSITION posPrev; for(POSITION pos=m_PageList.GetHeadPosition();pos!=NULL;) { posPrev=pos; CWnd *p=m_PageList.GetNext(pos); if(!IsWindow(p->m_hWnd)) m_PageList.RemoveAt(posPrev); } return m_PageList.GetCount(); } /////////////////////////////////////////////////// // get a rect by the index of a child void CBSWndContainer::CalcPageRect(LPRECT lpRect,int nIndex,int nPageCount) { if((nPageCount<=0)||(nIndex>=nPageCount)) { lpRect->left=lpRect->right=lpRect->top=lpRect->bottom=0; return; } //get row count int nRow=0; while((nRow)*(nRow)right-lpRect->left)/nRow; int nHeight=(lpRect->bottom-lpRect->top)/nRow; //get top-left point CPoint pt; pt.x=lpRect->left+nWidth*(nIndex%nRow); pt.y=lpRect->top+nHeight*(nIndex/nRow); //set rect return back lpRect->left=pt.x; lpRect->top=pt.y; lpRect->right=lpRect->left+nWidth; lpRect->bottom=lpRect->top+nHeight; } /////////////////////////////////////////////////// // adjust a rect by defined proportion void CBSWndContainer::AdjustRect(LPRECT lpRect) { int nWidth=lpRect->right-lpRect->left; int nHeight=lpRect->bottom-lpRect->top; CPoint pt((lpRect->left+lpRect->right)/2,(lpRect->top+lpRect->bottom)/2); int nTemp=nWidth*8/11; if(nTemp>nHeight) { nWidth=nHeight*11/8; } else if(nTempleft=pt.x-nWidth/2; lpRect->right=pt.x+nWidth/2; lpRect->top=pt.y-nHeight/2; lpRect->bottom=pt.y+nHeight/2; } /////////////////////////////////////////////////// //To get display zone in proportion void CBSWndContainer::GetShowRect(LPRECT lpRect) { if(m_nShowPortion<40) m_nShowPortion=40; if(m_nShowPortion>100) m_nShowPortion=100; int nWidth = lpRect->right-lpRect->left; int nHeight = lpRect->bottom-lpRect->top; int nNewWidth = (int)(nWidth*m_nShowPortion/100); int nNewHeight = (int)(nHeight*m_nShowPortion/100); int ndx = ( nWidth-nNewWidth )/2; int ndy = ( nHeight-nNewHeight )/2; lpRect->left = lpRect->left + ndx; lpRect->top = lpRect->top + ndy; lpRect->right = lpRect->left + nNewWidth; lpRect->bottom = lpRect->top + nNewHeight; } /////////////////////////////////////////////////// // draw the frame of active page void CBSWndContainer::DrawActivePage(BOOL bFlag) { if( !m_bMultiScreen || !m_pActivePage || m_PageList.GetCount()<2 ) return; CRect rt; m_pActivePage->GetWindowRect(&rt); ScreenToClient(&rt); rt.InflateRect(1,1); if(bFlag) { CDC *pDC=GetDC(); if(!pDC) return; // pDC->Draw3dRect(&rt,m_clrTopLeft, m_clrBottomRight); pDC->Draw3dRect(&rt,RGB(255,0,0), RGB(255,0,0)); ReleaseDC(pDC); } else InvalidateRect(&rt); }