⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xfloorwndctl.cpp

📁 类似于OutLook窗口的XFloorWnd ActiveX控件源程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/////////////////////////////////////////////////////////////////////////////
// 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 + -