www.pudn.com > mu_explorer.rar > CJMetaFileButton.cpp


// CJMetaFileButton.cpp : implementation file 
// 
// Copyright © 1999 Ian Brumby 
// 
// This source code may be used in compiled form in any way you desire.  
// Source file(s) may be redistributed unmodified by any means PROVIDING 
// they are not sold for profit without the authors expressed written consent, 
// and providing that this notice and the authors name and all copyright 
// notices remain intact. 
// 
// ==========================================================================   
// HISTORY:	   
// ==========================================================================   
//			1.20	21 Apr 1999	- Initial release. 
// ==========================================================================   
///////////////////////////////////////////////////////////////////////////// 
/**************************************************************************** 
 * 
 * $Date: 10/31/99 11:04p $ 
 * $Revision: 6 $ 
 * $Archive: /CodeJock/CJLibrary/CJMetaFileButton.cpp $ 
 * 
 * $History: CJMetaFileButton.cpp $ 
 *  
 * *****************  Version 6  ***************** 
 * User: Kirk Stowell Date: 10/31/99   Time: 11:04p 
 * Updated in $/CodeJock/CJLibrary 
 * Overrode OnEraseBkgnd(...) and OnPaint() for flicker free drawing. 
 *  
 * *****************  Version 5  ***************** 
 * User: Kirk Stowell Date: 10/25/99   Time: 10:52p 
 * Updated in $/CodeJock/CJLibrary 
 * Modified resource include for static builds. 
 *  
 * *****************  Version 4  ***************** 
 * User: Kirk Stowell Date: 10/24/99   Time: 12:01a 
 * Updated in $/CodeJock/CJLibrary 
 * Fixed potential resource and memory leak problems. 
 *  
 * *****************  Version 3  ***************** 
 * User: Kirk Stowell Date: 10/14/99   Time: 12:41p 
 * Updated in $/CodeJock/CJLibrary 
 * Added source control history to file header. 
 * 
 ***************************************************************************/ 
///////////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "CJResource.h" 
#include "CJMetaFileButton.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CCJMetaFileButton 
 
CCJMetaFileButton::CCJMetaFileButton() 
{ 
} 
 
CCJMetaFileButton::~CCJMetaFileButton() 
{ 
} 
 
void CCJMetaFileButton::SetMetaFiles(HENHMETAFILE hMetaFile, 
	HENHMETAFILE hMetaFileSel, HENHMETAFILE hMetaFileFocus, HENHMETAFILE hMetaFileDisabled) 
{ 
	m_hEnhMetaFile         = hMetaFile; 
	m_hEnhMetaFileSel      = hMetaFileSel; 
	m_hEnhMetaFileFocus    = hMetaFileFocus; 
	m_hEnhMetaFileDisabled = hMetaFileDisabled; 
} 
 
 
BEGIN_MESSAGE_MAP(CCJMetaFileButton, CButton) 
	//{{AFX_MSG_MAP(CCJMetaFileButton) 
	ON_WM_LBUTTONDBLCLK() 
	ON_WM_ERASEBKGND() 
	ON_WM_PAINT() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CCJMetaFileButton message handlers 
 
void CCJMetaFileButton::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
	// Fix for the double click problem with owner drawn buttons 
	POINT pt; 
	::GetCursorPos(&pt); 
	::MapWindowPoints(NULL, (HWND)(m_hWnd), &pt, 1); 
	::SendMessage((HWND)(m_hWnd), WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));	 
	CButton::OnLButtonDblClk(nFlags, point); 
} 
 
void CCJMetaFileButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
{ 
	ASSERT(lpDrawItemStruct != NULL); 
 
	// define some temporary variables. 
	CDC*  pDC	 = CDC::FromHandle( lpDrawItemStruct->hDC ); 
	CRect rcItem = lpDrawItemStruct->rcItem; 
	int   nState = lpDrawItemStruct->itemState; 
 
	// Paint the background. 
	pDC->FillSolidRect(rcItem, ::GetSysColor(COLOR_3DFACE)); 
	 
	// draw 3D button outline 
	CPen penOutline(PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT)); 
	CPen penLight(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT)); 
	CPen penDark(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW)); 
	CPen* pOldPen = NULL; 
 
	if (nState & ODS_SELECTED) 
	{ 
		pOldPen = pDC->SelectObject(&penDark); 
		pDC->MoveTo(0, rcItem.bottom - 1); 
		pDC->LineTo(0, 1); 
		pDC->LineTo(rcItem.right - 1, 1); 
	} 
	else 
	{ 
		pOldPen = pDC->SelectObject(&penLight); 
		pDC->MoveTo(0, rcItem.bottom - 2); 
		pDC->LineTo(0, 1); 
		pDC->LineTo(rcItem.right - 2, 1); 
		pDC->SelectObject(&penDark); 
		pDC->MoveTo(0, rcItem.bottom - 1); 
		pDC->LineTo(rcItem.right - 2, rcItem.bottom - 1); 
		pDC->LineTo(rcItem.right - 2, 0); 
		pDC->MoveTo(1, rcItem.bottom - 2); 
		pDC->LineTo(rcItem.right - 3, rcItem.bottom - 2); 
		pDC->LineTo(rcItem.right - 3, 1); 
	} 
	pDC->SelectObject(&penOutline); 
	pDC->MoveTo(0, 0); 
	pDC->LineTo(rcItem.right - 1, 0); 
	pDC->LineTo(rcItem.right - 1, rcItem.bottom); 
	 
	HENHMETAFILE hMetaFile = m_hEnhMetaFile; 
	if ((nState & ODS_SELECTED) && m_hEnhMetaFileSel != NULL) 
		hMetaFile = m_hEnhMetaFileSel; 
	else if ((nState & ODS_FOCUS) && m_hEnhMetaFileFocus != NULL) 
		hMetaFile = m_hEnhMetaFileFocus;   // third image for focused 
	else if ((nState & ODS_DISABLED) && m_hEnhMetaFileDisabled != NULL) 
		hMetaFile = m_hEnhMetaFileDisabled;   // last image for disabled 
	 
	ASSERT(hMetaFile != NULL); 
	 
	CRect rcBounds(5,4,0,0); 
	int iButtonHeight = rcItem.Height(); 
	if (iButtonHeight > 15) 
		iButtonHeight = 15; 
	else if (iButtonHeight < 11) 
		iButtonHeight = 11; 
	int iArrowWidth = (iButtonHeight / 2) - 3; 
	rcBounds.right = rcBounds.left + iArrowWidth - 1; 
	rcBounds.bottom = rcBounds.top + (iArrowWidth * 2) - 2; 
	 
	if (nState & ODS_SELECTED) 
		rcBounds += CPoint(1, 1); 
	pDC->PlayMetaFile(hMetaFile, rcBounds); 
 
	// fix potential resource leak - KStowell - 10-21-99 
	pDC->SelectObject(pOldPen); 
	penOutline.DeleteObject(); 
	penLight.DeleteObject(); 
	penDark.DeleteObject(); 
} 
 
BOOL CCJMetaFileButton::OnEraseBkgnd(CDC* pDC)  
{ 
	// KStowell - overridden for flicker-free drawing. 
	UNUSED_ALWAYS(pDC); 
	return TRUE; 
} 
 
void CCJMetaFileButton::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	 
	// KStowell - Get the client rect. 
	CRect rcClient, rcClip; 
	dc.GetClipBox( &rcClip ); 
	GetClientRect( &rcClient ); 
 
	// KStowell - Create a memory device-context. This is done to help reduce 
	// screen flicker, since we will paint the entire control to the 
	// off screen device context first. 
	CDC memDC; 
	CBitmap bitmap; 
	memDC.CreateCompatibleDC(&dc); 
	bitmap.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height()); 
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap); 
 
	// KStowell - Repaint the background. 
	memDC.FillSolidRect( rcClient, ::GetSysColor(COLOR_WINDOW) ); 
 
	// let the control do its default drawing. 
	CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); 
 
	// KStowell - Copy the memory device context back into the original DC via BitBlt(). 
	dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC,  
		rcClip.left, rcClip.top, SRCCOPY ); 
 
	// KStowell - Cleanup resources. 
	memDC.SelectObject(pOldBitmap); 
	memDC.DeleteDC(); 
	bitmap.DeleteObject(); 
}