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; };