fast-yolo4/fast/BSWndContainer.cpp
2024-09-25 09:43:03 +08:00

501 lines
11 KiB
C++

// 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)
{
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)
{
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)
{
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)
{
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)
{
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)<nPageCount) nRow++;
//get singledlg width and height
int nWidth=(lpRect->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(nTemp<nHeight)
{
nHeight=nTemp;
}
lpRect->left=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);
}