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

📄 kcsidebannerwnd.cpp

📁 求解TSP问题的蚁群算法图形演示程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
 *	class		:	CKCSideBannerWnd
 *	author		:	Peter Mares / kinkycode.com (gui@kinkycode.com)
 *	base class	:	CWnd (MFC)
 *	notes		:	A control to act as a banner to a window. More of a look'n'feel
 *					control.
 *					NOTE: Remember to link to MSIMG32.LIB to enable GradientFill()
 *
 *	Blurb		:	Its free, it feels good and its from South Africa :)
 ****************************************************************************
 *	Version History:
 *
 *	v0.1 (20-Oct-2003)
 *
 *	- First public release
 *
 *	v0.2 (24-Oct-2003)
 *
 *	- Added (Set)(Get)ColTxtTitle() and (Set)(Get)ColTxtCaption() functions
 *	- Revised all other updates since initial release
 *
 *	v0.3 (25-Oct-2003)
 *
 *	- Changed the SetIcon() function to support a delete flag
 *	- Added SetTexture() function
 *	- Fixed a resource leak
 *
 *	v0.31 (26-Oct-2003)
 *
 *	- Added UNICODE support to the control - thanks to Abraxas23
 *
 *	v0.32 (29-Oct-2003)
 *
 *	- Added support for gradient drawing without the dependancy on MSIMG32.LIB
 *    Used John A. Johnson's GradientFill() function, and used dynamic linking
 *	  of the MSIMG32.DLL (thanks to Irek Zielinski's code)
 *
 ****************************************************************************/

#include "stdafx.h"
#include "KCSideBannerWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CKCSideBannerWnd

CKCSideBannerWnd::CKCSideBannerWnd()
: CWndUtil(KCSB_CLASSNAME)
, m_pOwner(NULL)
, m_nSize(50)
, m_uPosFlag(0)
, m_uFillFlag(KCSB_FILL_GRADIENT)
, m_colBkg(RGB(255,255,255))
, m_colBkg2(RGB(128,128,192))
, m_colTxtTitle(RGB(0,0,0))
, m_colTxtCaption(RGB(0,0,0))
, m_colEdge(RGB(0,0,0))
, m_strTitle(_T("This is the sample title"))
, m_strCaption(_T("This is the sample caption..."))
, m_szEdgeOffset(5,3)
, m_szCaptionOffset(4, 10)
, m_uIconPos(KCSB_ICON_RIGHT)
, m_hIcon(0)
, m_bIconDelete(false)
, m_hBkgBitmap(0)
, m_bBmpDelete(false)
, m_pGradFill(NULL)
, m_hGradMod(0)
{
	RegisterWndClass();

	CFont			font;

	font.CreatePointFont(110, _T("Tahoma Bold"));
	font.GetLogFont(&m_lfTitle);
	font.DeleteObject();
	font.CreatePointFont(85, _T("Tahoma"));
	font.GetLogFont(&m_lfCaption);
	font.DeleteObject();

	// try and load the MSIMG32.LIB
	if ( (m_hGradMod = LoadLibrary("MSIMG32.DLL")) )
		m_pGradFill = (PFNGRADFILL) GetProcAddress( m_hGradMod, "GradientFill" );
}

/////////////////////////////////////////////////////////////////////////////

CKCSideBannerWnd::~CKCSideBannerWnd()
{
	if ( m_hBkgBitmap && m_bBmpDelete )
		::DeleteObject(m_hBkgBitmap);
	if ( m_hIcon && m_bIconDelete )
		::DeleteObject(m_hIcon);
	if ( m_hGradMod )
		::FreeLibrary(m_hGradMod);
}

/////////////////////////////////////////////////////////////////////////////

BEGIN_MESSAGE_MAP(CKCSideBannerWnd, CWnd)
	//{{AFX_MSG_MAP(CKCSideBannerWnd)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

BOOL CKCSideBannerWnd::Attach(CWnd* pWnd, unsigned int uFlags, unsigned int uiID)
{
	ASSERT(pWnd);
	if ( !pWnd )
		return FALSE;
	ASSERT(pWnd->m_hWnd);
	if ( !pWnd->m_hWnd )
		return FALSE;

	CRect				rect;

	m_pOwner = pWnd;
	m_pOwner->GetWindowRect(&rect);
	m_pOwner->ClientToScreen(&rect);

	m_uPosFlag = uFlags;

	// Banner LEFT
	if ( uFlags & KCSB_ATTACH_LEFT )
	{
		rect.left -= m_nSize;
		if ( rect.left < 0 )
			rect.OffsetRect( -rect.left, 0 );
	}
	// Banner RIGHT
	else if ( uFlags & KCSB_ATTACH_RIGHT )
	{
		rect.right += m_nSize;
	}
	// Banner TOP
	else if ( uFlags & KCSB_ATTACH_TOP )
	{
		rect.top -= m_nSize;
		if ( rect.top < 0 )
			rect.OffsetRect( 0, -rect.top );
	}
	// Banner BOTTOM
	else if ( uFlags & KCSB_ATTACH_BOTTOM )
	{
		rect.bottom += m_nSize;
	}
	// update the size of the owner
	m_pOwner->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER);

	// update the positions of the child controls
	UpdateLayout(m_nSize);

	// attach the banner respective to its positional flag
	m_pOwner->GetClientRect(&rect);
	if ( uFlags & KCSB_ATTACH_LEFT )
		rect.right = rect.left + m_nSize;
	else if ( uFlags & KCSB_ATTACH_RIGHT )
		rect.left = rect.right - m_nSize;
	else if ( uFlags & KCSB_ATTACH_TOP )
		rect.bottom = rect.top + m_nSize;
	else if ( uFlags & KCSB_ATTACH_BOTTOM )
		rect.top = rect.bottom - m_nSize;

	// et voila... create the banner..
	Create(WS_CHILD | WS_VISIBLE, rect, m_pOwner, uiID);

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////

void CKCSideBannerWnd::SetSize(int nSize)
{
	if ( m_hWnd )
	{
		CRect			rect;

		//
		// offset the controls accordingly
		if ( m_uPosFlag & KCSB_ATTACH_LEFT || m_uPosFlag & KCSB_ATTACH_TOP )
		{
			UpdateLayout( nSize - m_nSize );
		}

		//
		// size the containing window
		m_pOwner->GetWindowRect(&rect);

		if ( m_uPosFlag & KCSB_ATTACH_LEFT )
		{
			rect.left -= (nSize-m_nSize);
			if ( rect.left < 0 )
				rect.OffsetRect( -rect.left, 0 );
			m_pOwner->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER);
		}
		else if ( m_uPosFlag & KCSB_ATTACH_RIGHT )
		{
			rect.left -= (nSize - m_nSize);
			m_pOwner->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
		}
		else if ( m_uPosFlag & KCSB_ATTACH_TOP )
		{
			rect.top -= (nSize - m_nSize);
			if ( rect.top < 0 )
				rect.OffsetRect( 0, -rect.top );
			m_pOwner->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER);
		}
		else if ( m_uPosFlag & KCSB_ATTACH_BOTTOM )
		{
			rect.top -= (nSize - m_nSize );
			m_pOwner->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
		}
	
		// size the banner
		GetClientRect(&rect);
		if ( m_uPosFlag & KCSB_ATTACH_LEFT )
			rect.right = rect.left + nSize;
		else if ( m_uPosFlag & KCSB_ATTACH_RIGHT )
			rect.right = rect.left + nSize;
		else if ( m_uPosFlag & KCSB_ATTACH_TOP )
			rect.bottom = rect.top + nSize;
		else if ( m_uPosFlag & KCSB_ATTACH_BOTTOM )
			rect.bottom = rect.top + nSize;
		MoveWindow(&rect);

		m_pOwner->Invalidate();

	}

	m_nSize = nSize;
}

/////////////////////////////////////////////////////////////////////////////

void CKCSideBannerWnd::UpdateSize()
{
	if ( !m_hWnd )
		return;

	CRect				rect;

	m_pOwner->GetClientRect(&rect);
	if ( m_uPosFlag & KCSB_ATTACH_LEFT )
		rect.right = rect.left + m_nSize;
	else if ( m_uPosFlag & KCSB_ATTACH_RIGHT )
		rect.left = rect.right - m_nSize;
	else if ( m_uPosFlag & KCSB_ATTACH_TOP )
		rect.bottom = rect.top + m_nSize;
	else if ( m_uPosFlag & KCSB_ATTACH_BOTTOM )
		rect.top = rect.bottom - m_nSize;

	MoveWindow(&rect, TRUE);
}

/////////////////////////////////////////////////////////////////////////////

void CKCSideBannerWnd::SetPosFlag(unsigned int uFlags)
{
	if ( (uFlags & 0xF) == (m_uPosFlag & 0xF) )
		return;

	CRect				rect;
	int					nSize = m_nSize;

	SetSize(0);
	m_uPosFlag = uFlags;
	SetSize(nSize);

	m_pOwner->GetClientRect(&rect);

	if ( uFlags & KCSB_ATTACH_LEFT )
		rect.right = rect.left + nSize;
	else if ( uFlags & KCSB_ATTACH_RIGHT )
		rect.left = rect.right - nSize;
	else if ( uFlags & KCSB_ATTACH_TOP )
		rect.bottom = rect.top + nSize;
	else if ( uFlags & KCSB_ATTACH_BOTTOM )
		rect.top = rect.bottom - nSize;

	MoveWindow(&rect);
	
	m_pOwner->Invalidate();
}

/////////////////////////////////////////////////////////////////////////////

void CKCSideBannerWnd::UpdateLayout(int nOffset)
{
	stEnum				data;

	data.pBannerWnd = this;
	data.pParentWnd = m_pOwner;
	data.nOffset = nOffset;
	data.uFlags = m_uPosFlag;

	::EnumChildWindows( m_pOwner->m_hWnd, ChildEnumProc, (LPARAM)&data );
}

/////////////////////////////////////////////////////////////////////////////

BOOL CALLBACK CKCSideBannerWnd::ChildEnumProc(HWND hWndChild, LPARAM lParam)
{
	stEnum*			pData = (stEnum*) lParam;
	HWND			hWndParent = 0;
	CRect			rect;
	POINT			topLeft, bottomRight;

	// check if the hwnd is valid, and check that its not the HWND to the banner
	if ( hWndChild && hWndChild != pData->pBannerWnd->m_hWnd )
	{
		// now we check if the parent is actually the parent of the banner..
		// this check was put it to deal with composite controls like a combobox..
		// NOTE: For some reason, a combobox's edit control appears to be a child
		// of the parent, until you query for its parent HWND.
		hWndParent = ::GetParent(hWndChild);
		if ( hWndParent == pData->pParentWnd->m_hWnd )
		{
			// we have a valid child window which we can now reposition
			::GetWindowRect(hWndChild, &rect);
			topLeft.x = rect.left;
			topLeft.y = rect.top;
			bottomRight.x = rect.right;
			bottomRight.y = rect.bottom;
			::ScreenToClient( pData->pParentWnd->m_hWnd, &topLeft );
			::ScreenToClient( pData->pParentWnd->m_hWnd, &bottomRight );
			if ( pData->uFlags & KCSB_ATTACH_LEFT )
			{
				topLeft.x += pData->nOffset;
				bottomRight.x += pData->nOffset;
			}
			else if ( pData->uFlags & KCSB_ATTACH_TOP )
			{
				topLeft.y += pData->nOffset;
				bottomRight.y += pData->nOffset;
			}
			::MoveWindow( hWndChild, topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y, TRUE );
		}
	}

	// return TRUE to continue enumerating...
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CKCSideBannerWnd message handlers
/////////////////////////////////////////////////////////////////////////////

BOOL CKCSideBannerWnd::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
	BOOL		bResult = CWnd::Create(KCSB_CLASSNAME, _T(""), dwStyle, rect, pParentWnd, nID, pContext);

	return bResult;
}

/////////////////////////////////////////////////////////////////////////////

void CKCSideBannerWnd::OnPaint() 
{
	CPaintDC			dc(this); // device context for painting
	CDC					memDC;
	CBitmap				memBMP, *pOldBmp = NULL;
	CRect				rect;

	GetClientRect(&rect);

	// create mem DC
	memDC.CreateCompatibleDC(&dc);
	memBMP.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
	pOldBmp = memDC.SelectObject(&memBMP);

	// draw the banner
	DrawBackground(&memDC, rect);
	DrawTextFields(&memDC, rect);

	// render the image
	dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);

	// deselect object
	memDC.SelectObject(pOldBmp);

	// delete objects
	memBMP.DeleteObject();
	memDC.DeleteDC();
}

/////////////////////////////////////////////////////////////////////////////

BOOL CKCSideBannerWnd::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////

void CKCSideBannerWnd::DrawBackground(CDC* pDC, CRect rect)
{
	CBrush				nBrush, *pOldBrush = NULL;
	CPen				nPen, *pOldPen = NULL;

	// Flat fill...
	if ( m_uFillFlag & KCSB_FILL_FLAT || ( (m_colBkg == m_colBkg2) && (m_uFillFlag & KCSB_FILL_GRADIENT) ))
	{
		pDC->FillSolidRect(&rect, m_colBkg);
		DrawEdge(pDC, rect);
	}
	// Gradient fill
	else if ( m_uFillFlag & KCSB_FILL_GRADIENT )
	{
		TRIVERTEX			vert[2];
		GRADIENT_RECT		gRect;
		ULONG				uGFlag;

		if ( m_pGradFill )		// can we use the MSIMG32.DLL function?
		{
			if ( (m_uPosFlag & KCSB_ATTACH_LEFT) || (m_uPosFlag & KCSB_ATTACH_RIGHT) )
			{
				// set the gradient fill according to position
				if ( m_uPosFlag & KCSB_ATTACH_LEFT )
				{
					vert[0].x = 0;
					vert[0].y = rect.top;
					vert[0].Red = GetRValue(m_colBkg2)<<8;
					vert[0].Green = GetGValue(m_colBkg2)<<8;
					vert[0].Blue = GetBValue(m_colBkg2)<<8;
					vert[0].Alpha = 0;

					vert[1].x = rect.right;
					vert[1].y = rect.bottom;
					vert[1].Red = GetRValue(m_colBkg)<<8;
					vert[1].Green = GetGValue(m_colBkg)<<8;
					vert[1].Blue = GetBValue(m_colBkg)<<8;
					vert[1].Alpha = 0;
				}
				else
				{
					vert[0].x = rect.right;
					vert[0].y = rect.top;
					vert[0].Red = GetRValue(m_colBkg)<<8;
					vert[0].Green = GetGValue(m_colBkg)<<8;
					vert[0].Blue = GetBValue(m_colBkg)<<8;
					vert[0].Alpha = 0;

					vert[1].x = 0;
					vert[1].y = rect.bottom;
					vert[1].Red = GetRValue(m_colBkg2)<<8;
					vert[1].Green = GetGValue(m_colBkg2)<<8;
					vert[1].Blue = GetBValue(m_colBkg2)<<8;
					vert[1].Alpha = 0;
				}
				uGFlag = GRADIENT_FILL_RECT_V;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -