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

📄 spinbuttonctrlex.cpp

📁 UHF RFID Reader Program
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// LBSpinButtonCtrl.cpp : implementation file
//
// Copyright ?1999 Oleg Lobach, All Rights Reserved.
//
// mailto:oleglb@mail.ru
//or
// mailto:oleg@alexen.ru
//
//
// This source file may be redistributed unmodified by any means PROVIDING 
// it is 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. This software is by no means to be 
// included as part of any third party components library, or as part any
// development solution that offers MFC extensions that are sold for profit. 
// 
// If the source code is used in any commercial applications then a statement 
// along the lines of:
// 
// "Portions Copyright ?1999 Oleg Lobach" must be included in the "Startup 
// Banner", "About Box" or "Printed Documentation". This software is provided 
// "as is" without express or implied warranty. Use it at your own risk! The 
// author(s) accepts no liability for any damage/loss of business that this 
// product may cause.
//
/////////////////////////////////////////////////////////////////////////////
//****************************************************************************

#include "stdafx.h"
#include "SpinButtonCtrlEx.h"

#pragma warning(disable:4786)
#include <map>


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

using namespace std;

namespace techwin
{

#ifdef _WIN32_WCE
	CSpinButtonCtrlEx::CSpinButtonCtrlEx()
	{
	}
	CSpinButtonCtrlEx::~CSpinButtonCtrlEx()
	{
	}
#else
	typedef map <HWND,HWND> HWNDMAP;
	static HWNDMAP gHandleMap;


	static LRESULT CALLBACK FilterBuddyMsgProc(int code,WPARAM wParam,  LPARAM lParam );
	static HHOOK ghHook=NULL;

	/////////////////////////////////////////////////////////////////////////////
	// CSpinButtonCtrlEx

	CSpinButtonCtrlEx::CSpinButtonCtrlEx():m_hWndBuddy(NULL),
		m_bVertical(true),m_nSpinAlign(Outside),
		m_bDefaultDirection(true),m_bBuddyIsEdit(false),
		m_rctIsPressed(0,0,0,0),m_bActiveSpinPressed(false),
		m_bAutoDisable(true)
	{

	}

	CSpinButtonCtrlEx::~CSpinButtonCtrlEx()
	{
	}


	BEGIN_MESSAGE_MAP(CSpinButtonCtrlEx, CSpinButtonCtrl)
		//{{AFX_MSG_MAP(CSpinButtonCtrlEx)
		ON_NOTIFY_REFLECT_EX(UDN_DELTAPOS, OnDeltapos)
		ON_WM_LBUTTONDOWN()
		ON_WM_ERASEBKGND()
		ON_WM_LBUTTONUP()
		ON_WM_DESTROY()
		ON_WM_PAINT()
		//}}AFX_MSG_MAP

	END_MESSAGE_MAP()

	/////////////////////////////////////////////////////////////////////////////
	// CSpinButtonCtrlEx message handlers

	void CSpinButtonCtrlEx::PreSubclassWindow() 
	{
		//I need custom pens to draw up_down control

		COLORREF clr=::GetSysColor(COLOR_3DDKSHADOW);
		m_penDarkShadow=::CreatePen(PS_SOLID,0,clr);	

		clr=::GetSysColor(COLOR_BTNSHADOW);
		m_penShadow=::CreatePen(PS_SOLID,0,clr);

		clr=::GetSysColor(COLOR_3DHILIGHT);
		m_penLight=::CreatePen(PS_SOLID,0,clr);

		clr=::GetSysColor(COLOR_3DLIGHT);
		m_penLightShadow=::CreatePen(PS_SOLID,0,clr);

		clr=::GetSysColor(COLOR_BTNFACE);
		m_penButtonFace=::CreatePen(PS_SOLID,0,clr);


		Init();
		CSpinButtonCtrl::PreSubclassWindow();
	}

	void CSpinButtonCtrlEx::OnPaint() 
	{
		if(m_bAutoDisable)
		{
			//Draw control by hands

			CPaintDC RealDC(this); // device context

			CRect rctPaint=m_rctClient;
			CRect rcPaintUp,rcPaintDown;

			//To get rid of flickering we are drawing to memory DC (dc),
			//and then BitBlting it to the screen.
			//So we have to create compatible memory DC and select bitmap into it.

			CDC dc;
			CBitmap bmpMem,*pOldMemBmp;
			dc.CreateCompatibleDC(&RealDC);
			bmpMem.CreateCompatibleBitmap(&RealDC,rctPaint.Width(),rctPaint.Height());
			pOldMemBmp=dc.SelectObject(&bmpMem);

			//As so I bypassed WM_ERASEBCKGND, do it here 
			dc.FillSolidRect(&rctPaint,::GetSysColor(COLOR_BTNFACE));


			if(::IsWindow(m_hWndBuddy) && m_nSpinAlign!=Outside )
			{
				rctPaint.top+=2;
				rctPaint.bottom-=2;
				if(m_nSpinAlign == OnRightInside)
					rctPaint.right-=2;
				else
					rctPaint.left+=2;
			}

			rcPaintUp= rctPaint;

			//Draw control, depending on it alignment and orientation
			if(m_bVertical)
			{
				rcPaintUp.bottom=rcPaintUp.top+rcPaintUp.Height()/2;
				rcPaintDown=rctPaint;
				rcPaintDown.top=rcPaintDown.bottom-rcPaintUp.Height();

				dc.DrawFrameControl(&rcPaintUp,DFC_SCROLL,DFCS_SCROLLUP);
				dc.DrawFrameControl(&rcPaintDown,DFC_SCROLL,DFCS_SCROLLDOWN);

			}
			else
			{
				rcPaintUp.right=rcPaintUp.left+rcPaintUp.Width()/2;
				rcPaintDown=rctPaint;
				rcPaintDown.left=rcPaintDown.right-rcPaintUp.Width();

				dc.DrawFrameControl(&rcPaintUp,DFC_SCROLL,DFCS_SCROLLLEFT);
				dc.DrawFrameControl(&rcPaintDown,DFC_SCROLL,DFCS_SCROLLRIGHT);

			}

			if(::IsWindow(m_hWndBuddy) && m_nSpinAlign!=Outside )
			{
				//We are inside buddy,so have to draw buddy's border around
				//CSpinButtonCtrlEx

				//We use m_rctClient as so rctPaint may have been already modified.
				if(m_nSpinAlign == OnRightInside)
				{
					::SelectObject(dc.m_hDC,m_penShadow);
					dc.MoveTo(m_rctClient.left,m_rctClient.top);
					dc.LineTo(m_rctClient.right,m_rctClient.top);

					::SelectObject(dc.m_hDC,m_penDarkShadow);
					dc.MoveTo(m_rctClient.left,m_rctClient.top+1);
					dc.LineTo(m_rctClient.right-1,m_rctClient.top+1);

					::SelectObject(dc.m_hDC,m_penLight);
					dc.LineTo(m_rctClient.right-1,m_rctClient.bottom-1);
					dc.LineTo(m_rctClient.left-1,m_rctClient.bottom-1);
				}
				else
				{
					::SelectObject(dc.m_hDC,m_penShadow);
					dc.MoveTo(m_rctClient.right,m_rctClient.top);
					dc.LineTo(m_rctClient.left,m_rctClient.top);
					dc.LineTo(m_rctClient.left,m_rctClient.bottom);

					::SelectObject(dc.m_hDC,m_penDarkShadow);
					dc.MoveTo(m_rctClient.right,m_rctClient.top+1);
					dc.LineTo(m_rctClient.left+1,m_rctClient.top+1);
					dc.LineTo(m_rctClient.left+1,m_rctClient.top+1);
					dc.LineTo(m_rctClient.left+1,m_rctClient.bottom-1);

					::SelectObject(dc.m_hDC,m_penLight);
					dc.LineTo(m_rctClient.right+1,m_rctClient.bottom-1);
				}

			}
			//If the position reached the limit, draw corresponding
			//part of control as disabled
			switch (m_nSpinState)
			{
			case DisableRight:
				if(m_bDefaultDirection)
				{
					if(m_bVertical)
						DisableRect(dc,rcPaintDown);
					else
						DisableRect(dc,rcPaintUp);
				}
				else
				{
					if(m_bVertical)
						DisableRect(dc,rcPaintUp);
					else
						DisableRect(dc,rcPaintDown);
				}

				break;
			case DisableLeft:
				if(m_bDefaultDirection)
				{
					if(m_bVertical)
						DisableRect(dc,rcPaintUp);
					else
						DisableRect(dc,rcPaintDown);

				}
				else
				{
					if(m_bVertical)
						DisableRect(dc,rcPaintDown); 
					else
						DisableRect(dc,rcPaintUp);

				}
				break;
			}

			if(m_bActiveSpinPressed)
			{
				//The control's position has changed, so we have to
				//draw corresponding part as pressed
				if(m_rctIsPressed.IsRectEmpty())
				{
					CPoint pt=::GetMessagePos();
					ScreenToClient(&pt);
					if(rcPaintUp.PtInRect(pt))
					{
						m_rctIsPressed = rcPaintUp;
					}
					else
					{
						if(rcPaintDown.PtInRect(pt))
						{
							m_rctIsPressed = rcPaintDown; 
						}
					}

				}
				DrawPressedRect(dc,m_rctIsPressed);
				m_bActiveSpinPressed=false;

			}
			//Copy drawing from memory device context to the screen
			RealDC.BitBlt(m_rctClient.left,m_rctClient.top,m_rctClient.Width(),
				m_rctClient.Height(),&dc,m_rctClient.left,m_rctClient.top,SRCCOPY);

			dc.SelectObject(pOldMemBmp);
		}
		else
		{
			//Let the Windows do it's work 
			Default();
			return;
		}

	}
	void CSpinButtonCtrlEx::DisableRect(CDC &dc, const CRect &rectDisable) const
	{
		CBitmap bmpMask,*pBmpBeforeMask;
		CBrush	brushMask,*pOldBrush;
		COLORREF clrOldBack,clrOldText;
		CDC memDC;
		memDC.CreateCompatibleDC(&dc);


		CRect rctClient;
		CRect rectToDisable=rectDisable;
		GetClientRect(&rctClient);

		//Create MONO bitmap
		bmpMask.CreateBitmap(rctClient.Width(),rctClient.Height(),1,1,NULL);
		pBmpBeforeMask=memDC.SelectObject(&bmpMask);

		CDC dcSrc;
		dcSrc.CreateCompatibleDC(&dc);
		CBitmap bmpSrc,*pBmpBeforeSrc;

		bmpSrc.CreateCompatibleBitmap(&dc,rctClient.Width(),rctClient.Height());
		pBmpBeforeSrc=dcSrc.SelectObject(&bmpSrc);

		clrOldBack=dc.SetBkColor(RGB(0,0,0)); //Suppose arrows are black

		//Create mask into memDC (the pixels which in dc were black  - become white in memDC,
		//all others pixels in memDC become black)
		memDC.BitBlt(rectToDisable.left,rectToDisable.top,
			rectToDisable.Width(),rectToDisable.Height(),&dc,
			rectToDisable.left,rectToDisable.top,SRCCOPY);

		//Copy bitmap from screen to memory DC
		dcSrc.BitBlt(rectToDisable.left,rectToDisable.top,
			rectToDisable.Width(),rectToDisable.Height(),&dc,
			rectToDisable.left,rectToDisable.top,SRCCOPY);

		CBrush brushSrc;
		rectToDisable.DeflateRect(1,1);

		//Apply DSPxax ROP code to memory dc . As result black arrow become
		// of COLOR_3DSHADOW
		brushSrc.CreateSolidBrush(::GetSysColor(COLOR_3DSHADOW));
		dcSrc.SelectObject(&brushSrc);
		dcSrc.SetBkColor(RGB(255,255,255));
		dcSrc.SetTextColor(RGB(0,0,0));
		dcSrc.BitBlt(rectToDisable.left,rectToDisable.top,
			rectToDisable.Width(),rectToDisable.Height(),&memDC,
			rectToDisable.left,rectToDisable.top,0x00E20746L);

		//Apply DSPxax ROP code to screen dc and shift result one pixel left and bottom.
		//As result black arrow become shifted and of COLOR_3DLIGHT.
		brushMask.CreateSolidBrush(::GetSysColor(COLOR_3DHILIGHT));
		pOldBrush = dc.SelectObject(&brushMask);
		dc.SetBkColor(RGB(255,255,255));
		clrOldText=dc.SetTextColor(RGB(0,0,0));
		dc.BitBlt(rectToDisable.left+1,rectToDisable.top+1,
			rectToDisable.Width()-1,rectToDisable.Height()-1,&memDC,
			rectToDisable.left,rectToDisable.top,0x00E20746L);


		// Draw memory dc (dcSrc) transparently over device dc.
		//As result only arrow of color COLOR_3DSHADOW will be drawn over device dc
		//-------------------------------------------------------------------------

		//Create mask into memDC (the pixels which in dc were COLOR_BTNFACE
		//- become white in memDC,all others pixels in memDC become black)
		dcSrc.SetBkColor(GetSysColor(COLOR_BTNFACE));
		memDC.BitBlt(rectToDisable.left,rectToDisable.top,
			rectToDisable.Width(),rectToDisable.Height(),&dcSrc,
			rectToDisable.left,rectToDisable.top,SRCCOPY);

		dc.BitBlt(rectToDisable.left,rectToDisable.top,
			rectToDisable.Width(),rectToDisable.Height(),&dcSrc,
			rectToDisable.left,rectToDisable.top,SRCINVERT);

		dc.BitBlt(rectToDisable.left,rectToDisable.top,
			rectToDisable.Width(),rectToDisable.Height(),&memDC,
			rectToDisable.left,rectToDisable.top,SRCAND);
		dc.BitBlt(rectToDisable.left,rectToDisable.top,
			rectToDisable.Width(),rectToDisable.Height(),&dcSrc,
			rectToDisable.left,rectToDisable.top,SRCINVERT);
		//-------------------------------------------------------------------------

		//Restore resourses
		memDC.SelectObject(pBmpBeforeMask);
		dcSrc.SelectObject(pBmpBeforeSrc);

		dc.SetBkColor(clrOldBack);
		dc.SetTextColor(clrOldText);

⌨️ 快捷键说明

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