📄 xfloorwndctl.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// CXFloorWndCtrl::DoPropExchange - Persistence support
void CXFloorWndCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Bool(pPX, _T("Animation"), m_bAnimation, TRUE);
PX_Long(pPX, _T("Sleep"), m_nSleep, 0);
PX_Bool(pPX, _T("Sign"), m_bSign, TRUE);
PX_Bool(pPX, _T("AsPage"), m_bAsPage, TRUE);
PX_String(pPX, _T("Pages"), m_sPages, _T(""));
if (pPX->IsLoading())
OnPagesChanged();
}
/////////////////////////////////////////////////////////////////////////////
// CXFloorWndCtrl::OnResetState - Reset control to default state
void CXFloorWndCtrl::OnResetState()
{
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
COLORREF clrBack = defaultRGBBkGnd;
SetBackColor((OLE_COLOR)clrBack);
}
/////////////////////////////////////////////////////////////////////////////
// CXFloorWndCtrl::AboutBox - Display an "About" box to the user
void CXFloorWndCtrl::AboutBox()
{
CDialog dlgAbout(IDD_ABOUTBOX_XFLOORWND);
dlgAbout.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CXFloorWndCtrl message handlers
// Function name : CXFloorWndCtrl::GetCountPage
// Description : Get count of pages
// Return type : int
int CXFloorWndCtrl::GetCountPage()
{
return m_pArPage->GetSize();
}
// Function name : CXFloorWndCtrl::GetPage
// Description : Return the page index nIndex
// Return type : CFloorPageObject*
// Argument : int nIndex
CFloorPageObject* CXFloorWndCtrl::GetPage(int nIndex)
{
if (nIndex >=0)
if (nIndex < GetCountPage() )
return (*m_pArPage)[nIndex];
return NULL;
}
// Function name : CXFloorWndCtrl::GetPage
// Description : Return the page with name lpszPageName
// Return type : CFloorPageObject*
// Argument : LPCTSTR lpszPageName
CFloorPageObject* CXFloorWndCtrl::GetPage(LPCTSTR lpszPageName)
{
for (int i = 0; i < GetCountPage(); i++)
if (GetPage(i)->GetName().CompareNoCase(lpszPageName) == 0)
return GetPage(i);
return NULL;
}
// Function name : CXFloorWndCtrl::RecalcLayout
// Description : Called this function when a page was added, removed, or his size, position changes
// This function can recalc all rect of windows.
// Return type : void
void CXFloorWndCtrl::RecalcLayout()
{
if (::IsWindow(m_hWnd))
{
if (m_bAsPage)
{
CRect rClient; GetClientRect(rClient);
rClient.InflateRect(-1,-1);
int uY = rClient.top, dY = rClient.bottom;
for (int i = 0; i < GetCountPage(); i++)
{
CFloorObject* pPage = GetPage(i);
if (pPage->IsPullUp())
{
pPage->m_rect = CRect(rClient.left,uY,rClient.right,uY + pPage->GetHeight());
uY += pPage->GetHeight() + 1;
ValidateRect(pPage->m_rect);
}
}
for (i = GetCountPage() - 1; i >= 0 ; i--)
{
CFloorObject* pPage = GetPage(i);
if (pPage->IsPullDown())
{
pPage->m_rect = CRect(rClient.left,dY - pPage->GetHeight(),rClient.right,dY);
dY -= pPage->GetHeight() + 1;
ValidateRect(pPage->m_rect);
}
}
m_rectClient = CRect(rClient.left + 1, uY, rClient.right - 2, dY - 1);
}
else
{
CRect rect; GetClientRect(rect);
CRect rPage = ChangeHeightLabel(rect.Size());
m_rectClient = rect;
m_rectClient.top += m_nDYLabel;
m_rectClient.InflateRect(m_rtBorder);
for (int i = 0; i < m_pArPage->GetSize(); i++)
(*m_pArPage)[i]->m_rect = rPage;
if (CFloorPageObject* pPage = GetActivePage())
pPage->SetRectClient(m_rectClient);
}
Invalidate();
}
}
// Function name : CXFloorWndCtrl::Preview
// Description : Preview of window to a bitmap, If pWnd == NULL then
// function will return the bitmap with bkgnd color of thsi window
// Return type : CBitmap*
// Argument : CWnd * pWnd
CBitmap* CXFloorWndCtrl::Preview(CWnd * pWnd)
{
CBitmap *pBitmap = NULL, bitmapNonClient;
CWnd *pDrawWnd = pWnd ? pWnd : this;
if (pDrawWnd && ::IsWindow(pDrawWnd->m_hWnd))
{
CRect rectWindow; pDrawWnd->GetWindowRect(rectWindow);
CRect rectClient; pDrawWnd->GetClientRect(rectClient);
CPoint p(0,0);
pDrawWnd->ClientToScreen(&p);
rectClient.OffsetRect(p.x - rectWindow.left, p.y - rectWindow.top);
CDC* pDC = pDrawWnd->GetDC();
CDC dcMemSourceNonClient, dcMemDestination;
COLORREF colorBkGnd = TranslateColor(GetBackColor());
CBrush brBkGnd(colorBkGnd);
CGdiStack stack;
if (dcMemSourceNonClient.CreateCompatibleDC(pDC))
if (dcMemDestination.CreateCompatibleDC(pDC))
if (pBitmap = new CBitmap())
if (pBitmap->CreateCompatibleBitmap(pDC, rectWindow.Width(), rectWindow.Height()))
if (bitmapNonClient.CreateCompatibleBitmap(pDC, rectWindow.Width(), rectWindow.Height()))
{
stack.Push(&dcMemSourceNonClient,&bitmapNonClient);
stack.Push(&dcMemSourceNonClient,&brBkGnd);
dcMemSourceNonClient.PatBlt(0,0,rectWindow.Width(), rectWindow.Height(), PATCOPY);
stack.Push(&dcMemDestination, pBitmap);
if (pWnd)
pDrawWnd->Print(&dcMemSourceNonClient, PRF_NONCLIENT);
dcMemDestination.BitBlt(0,0,rectWindow.Width(), rectWindow.Height(), &dcMemSourceNonClient, 0,0, SRCCOPY);
if (pWnd)
{
CPoint pLT(0,0);
pDrawWnd->ClientToScreen(&pLT);
dcMemDestination.SetViewportOrg(pLT.x - rectWindow.left, pLT.y - rectWindow.top);
pDrawWnd->Print(&dcMemDestination, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND);
}
stack.Pop();
stack.Pop();
stack.Pop();
bitmapNonClient.DeleteObject();
dcMemDestination.DeleteDC();
dcMemSourceNonClient.DeleteDC();
}
pDrawWnd->ReleaseDC(pDC);
}
return pBitmap;
}
// Function name : CXFloorWndCtrl::AddPage
// Description : Call to add a new page into floorwindow control
// Updated : Version 1.01
// Return type : CFloorPageObject*
// Argument : LPCTSTR lpszPageName
// Argument : int * pIndex
CFloorPageObject* CXFloorWndCtrl::AddPage(LPCTSTR lpszPageName, int * pIndex)
{
ActivatePage(GetCountPage() - 1);
if (CFloorPageObject* pPage = NewPage(m_bAsPage, lpszPageName))
{
int index = m_pArPage->Add(pPage);
if (pIndex) *pIndex = index;
RecalcLayout();
OnActivatePage(pPage);
return pPage;
}
return NULL;
}
// Function name : CXFloorWndCtrl::OnActivatePage
// Description : Activate page pPage, and notify the parent of this object
// Update : Version 1.01. Focus bug
// Return type : void
// Argument : CFloorPageObject * pPage
void CXFloorWndCtrl::OnActivatePage(CFloorPageObject * pPage)
{
if (::IsWindow(m_hWnd))
{
// Always, this function must be called after RecalcLayout
if (m_pActivePage)
m_pActivePage->OnDeactivateObject();
m_pActivePage = pPage;
m_pActivePage->SetRectClient(m_rectClient);
m_pActivePage->OnActivateObject();
if (CWnd* pParentWnd = GetParent())
pParentWnd->SendMessage(m_nMessageChange, (WPARAM)m_pActivePage, (LPARAM)pPage);
FireActivatePage(PtrPageToIndex(pPage));
m_pFocusPage = NULL;
}
}
// Function name : CXFloorWndCtrl::RegClassFloorWnd
// Description : Call once this function to register FloorWnd class name
// Return type : BOOL
BOOL CXFloorWndCtrl::RegClassFloorWnd()
{
if (!m_nMessageChange)
{
//At the first call set the new page's font
m_nMessageChange = RegisterWindowMessage(MessageChange);
return TRUE;
}
return FALSE;
}
// Function name : CXFloorWndCtrl::GetActivePage
// Description : Return the active page
// Return type : CFloorPageObject*
CFloorPageObject* CXFloorWndCtrl::GetActivePage()
{
return m_pActivePage;
}
// Function name : CXFloorWndCtrl::GetRectClient
// Description : Return the emtpy rect of this
// Return type : CRect
CRect CXFloorWndCtrl::GetRectClient()
{
return m_rectClient;
}
// Function name : CXFloorWndCtrl::OnSize
// Description : Call to recall all height's page
// Return type : void
// Argument : UINT nType
// Argument : int cx
// Argument : int cy
void CXFloorWndCtrl::OnSize(UINT nType, int cx, int cy)
{
COleControl::OnSize(nType, cx, cy);
RecalcLayout();
if (CFloorPageObject* pPage = GetActivePage())
pPage->SetRectClient(GetRectClient());
}
// Function name : CXFloorWndCtrl::ActivatePage
// Description : Activate the page nIndex.
// Return type : BOOL
// Argument : int nIndex
BOOL CXFloorWndCtrl::ActivatePage(int nIndex)
{
if (CFloorPageObject* pPage = GetPage(nIndex))
if (pPage != GetActivePage())
{
pPage->PrepareToScroll();
if (m_bAsPage)
if (pPage->IsPullUp())
return PullDownPages(nIndex);
else
return PullUpPages(nIndex);
else
{
// If this is label ...
Move(PtrPageToIndex(pPage),TRUE);
RecalcLayout();
OnActivatePage(pPage);
}
pPage->EndScroll();
if (CWnd* pWnd = pPage->GetWindow())
if (::IsWindow(pWnd->m_hWnd))
pWnd->SetFocus();
}
return FALSE;
}
// Function name : CXFloorWndCtrl::ActivatePage
// Description : Activate the page with name lpszPageName
// Return type : BOOL
// Argument : LPCTSTR lpszPageName
BOOL CXFloorWndCtrl::ActivatePage(LPCTSTR lpszPageName)
{
return ActivatePage(PtrPageToIndex(GetPage(lpszPageName)));
}
// Function name : CXFloorWndCtrl::PullDownPages
// Description : Pull down all pages, that follow nIndex page
// Update : Version 1.01
// Return type : BOOL
// Argument : CFloorPageObject * pPage
BOOL CXFloorWndCtrl::PullDownPages(int nIndex)
{
if (CFloorPageObject* pPage = GetPage(nIndex))
if (pPage->IsPullUp())
{
Move(nIndex, TRUE);
for (int i = nIndex + 1; i < GetCountPage() && GetPage(i)->IsPullUp() ; i++)
GetPage(i)->m_bPullUp = FALSE;
RecalcLayout();
OnActivatePage(pPage);
}
return FALSE;
}
// Function name : CXFloorWndCtrl::PullDownPages
// Description : Pull up all pages, that ? nIndex page
// Update : Version 1.01
// Return type : BOOL
// Argument : CFloorPageObject * pPage
BOOL CXFloorWndCtrl::PullUpPages(int nIndex)
{
if (::IsWindow(m_hWnd))
if (CFloorPageObject* pPage = GetPage(nIndex))
if (pPage->IsPullDown())
{
Move(nIndex, FALSE);
for (int i = nIndex; (i >= 0) && (GetPage(i)->IsPullDown()); i--)
GetPage(i)->m_bPullUp = TRUE;
RecalcLayout();
OnActivatePage(pPage);
}
return FALSE;
}
// Function name : CXFloorWndCtrl::PtrPageToIndex
// Description : Return position from m_arPages, of pPage
// Return type : int
// Argument : CFloorPageObject * pPage
int CXFloorWndCtrl::PtrPageToIndex(CFloorPageObject * pPage)
{
for (int i = 0; i < GetCountPage(); i++)
if ((DWORD)GetPage(i) == (DWORD)pPage)
return i;
return -1;
}
// Function name : CXFloorWndCtrl::Move
// Description : Scroll window from page nIndex, down or up
// Return type : void
// Argument : int nIndex
// Argument : BOOL bDown
void CXFloorWndCtrl::Move(int nIndex, BOOL bDown)
{
if (::IsWindow(m_hWnd))
if (::IsWindowVisible(m_hWnd))
if (m_bAnimation)
{
HANDLE hThread = ::GetCurrentThread();
int tPriority = ::GetThreadPriority(hThread);
::SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
// Before I tryed to set highest priority to this thread,
// because follows a critical section. At the end of functions, I will retrieve
// the priority of current thread.
CFloorPageObject* pPage = GetPage(nIndex);
ASSERT (pPage);
if (pPage != m_pActivePage)
{
CRect rClient; GetClientRect(rClient);
CRect rScroll(rClient);
int dyScroll = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -