WTL 自定义 Button类-自绘

WTL 自绘Button类,支持按钮三种形态,正常模式,hover模式,鼠标按下模式,支持png图片。使用方法很简单:

   MyButton* pButton = new MyButton;
   pButton->SetBtnBmp(strBtnNormal,strBtnHover,strBtnDown);
   pButton->Create(m_hWnd,rt,NULL,WS_CHILD|WS_VISIBLE);
   pButton->SetBtnID(nID);//该ID是用来处理WM_COMMAND 命令的,即单机左键命令

#pragma  once


#pragma comment(lib, "gdiplus.lib")
static ULONG_PTR s_gdiplusToken2=0;


enum
{
	btn_state_normal = 0,
	btn_state_over   = 1,
	btn_state_down  = 2
};

class MyButton:public CWindowImpl<MyButton>
{
public:
	MyButton()
	{
		GdiplusStartupInput gdiplusStartupInput;
		GdiplusStartup(&s_gdiplusToken2, &gdiplusStartupInput, NULL);
		m_nState = btn_state_normal;
		m_bBtnDown = false;

	}
	~MyButton()
	{
		GdiplusShutdown(s_gdiplusToken2);
	}
protected:
	BEGIN_MSG_MAP(MyButton)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)	
		MESSAGE_HANDLER(WM_PAINT,OnPaint)
		MESSAGE_HANDLER(WM_MOUSEMOVE,OnMouseMove)
		MESSAGE_HANDLER(WM_MOUSELEAVE,OnMouseLeave)
		MESSAGE_HANDLER(WM_LBUTTONDOWN,OnLButtonDown)
		MESSAGE_HANDLER(WM_LBUTTONUP,OnLButtonUp)
		MESSAGE_HANDLER(WM_CREATE,OnCreate)
		MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBkgnd)
	END_MSG_MAP()


	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		CRect winRect;
		GetWindowRect(winRect);
		SetWindowPos(HWND_TOPMOST,winRect,SWP_SHOWWINDOW);
		
		return TRUE;
	}
	LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		
		return TRUE;
	}
	HBITMAP GetBitmapFromFile( LPCWSTR pFile )
	{
		std::auto_ptr<Bitmap> pBmp(new Bitmap(pFile));
		if(!pBmp.get())
			return NULL;
		HBITMAP hBmp = NULL;
		Color backColor = Color(255,0,0,0);   
		if(Ok!=pBmp->GetHBITMAP(backColor,&hBmp))
			return NULL;
		return hBmp;
	}
	void SetBtnBmp(CString strBtnNormal,CString strBtnHover,CString strBtnDown)
	{
		m_btmNormal.Attach(GetBitmapFromFile(strBtnNormal));
		m_btmOver.Attach(GetBitmapFromFile(strBtnHover));
		m_btmDown.Attach(GetBitmapFromFile(strBtnDown));
	}
	BOOL  DrawBmp( HDC hdc, CRect rect, HBITMAP hBitmap )
	{
		BITMAP bm;
		GetObject(hBitmap,sizeof(bm),(VOID*)&bm);
		INT nWidth = bm.bmWidth;
		INT nHeight = bm.bmHeight;
		CDC memdc;
		memdc.CreateCompatibleDC(hdc);
		CBitmap bitmap;
		bitmap.CreateCompatibleBitmap(hdc,nWidth,nHeight);
		memdc.SelectBitmap(hBitmap);

		BLENDFUNCTION bf = {AC_SRC_OVER,0,255,1};
		return ::AlphaBlend(hdc,rect.left,rect.top,nWidth,nHeight,memdc,0,0,nWidth,nHeight,bf);

		//::StretchBlt(hdc,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,
		//		comDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY );
	}
		LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		CPaintDC dc(m_hWnd);
		CRect rect;
		GetClientRect(&rect);
		switch(m_nState)
		{
		case btn_state_over:
			DrawBmp(dc,rect,m_btmOver);
			break;
		case btn_state_down:
			DrawBmp(dc,rect,m_btmDown);
			break;
		default://case = btn_state_normal		
			DrawBmp(dc,rect,m_btmNormal);
			break;

		}
		dc.SetBkMode(TRANSPARENT);
		dc.SetTextColor(RGB(240,250,240));
		dc.DrawText(m_strText,m_strText.GetLength(),&rect,DT_CENTER);
		return TRUE;
	}
	LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		if(!m_bBtnDown)
		{
			m_nState = btn_state_over;
			InvalidateRect(NULL);
			TRACKMOUSEEVENT   t_MouseEvent; 
			t_MouseEvent.cbSize       =     sizeof(TRACKMOUSEEVENT); 
			t_MouseEvent.dwFlags      =     TME_LEAVE|TME_HOVER; 
			t_MouseEvent.hwndTrack    =     m_hWnd; 
			t_MouseEvent.dwHoverTime  =     30; 
			::_TrackMouseEvent(&t_MouseEvent);

		}

		return TRUE;
	}
	LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		m_nState = btn_state_normal;
		m_bBtnDown = false;
		InvalidateRect(NULL);
		return TRUE;
	}
	LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		m_nState = btn_state_normal;
		m_bBtnDown  = false;
		InvalidateRect(NULL);
		::PostMessage(GetParent(),WM_COMMAND,m_nBtnID,NULL);
		return TRUE;
	}
	LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		m_bBtnDown = true;
		m_nState = btn_state_down;
		InvalidateRect(NULL);
		return TRUE;
	}
	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{

		return TRUE;
	}
	void SetBtnText(CString strText)
	{
		m_strText = strText;

	}
	void SetBtnID(int nID)
	{
		m_nBtnID = nID;
	}
private:
	CBitmap m_btmNormal;
	CBitmap m_btmOver;
	CBitmap m_btmDown;
	int m_nState;
	bool m_bBtnDown;
	CString m_strText;

	INT	    m_nBtnID;

};

 

posted @ 2013-12-27 18:03  Jamy Cai  阅读(1968)  评论(0编辑  收藏  举报