MFC设计局域网对战五子棋游戏(二)实现GDI+自绘按钮

因为按钮位于对话框右侧的透明区域,如果使用GDI绘制的话不能达到效果,,因为GDI不支持alpha通道,绘制到透明的对话框上只能是透明的效果,而GDI+支持alpha通道,所以使用GDI+绘制就可以了。首先看看自绘的按钮的类成员和重载函数:

class MyButton : public CButton{DECLARE_DYNAMIC(MyButton)public:MyButton();virtual ~MyButton();protected:DECLARE_MESSAGE_MAP()public:virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);afx_msg BOOL OnEraseBkgnd(CDC* pDC);private :BOOL m_tracking;RECT rect;bool m_hover;virtual void PreSubclassWindow();public:Gdiplus::Image*normalImage;Gdiplus::Image*hoverImage;Gdiplus::Image*activeImage;//WCHAR *image[3];afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);};

这个按钮实现了三种状态的变化:普通、悬停、按下,三种状态由三个png图片来显示。

具体实现如下:// MyButton.cpp : 实现文件//#include "stdafx.h"#include "MyButton.h"// MyButtonIMPLEMENT_DYNAMIC(MyButton, CButton)MyButton::MyButton():activeImage(NULL),normalImage(NULL),hoverImage(NULL){m_tracking = FALSE;m_hover = false;}MyButton::~MyButton(){}BEGIN_MESSAGE_MAP(MyButton, CButton)ON_WM_MOUSEMOVE()ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)ON_WM_ERASEBKGND()ON_WM_SETCURSOR()END_MESSAGE_MAP()using namespace Gdiplus;void MyButton::DrawItem(LPDRAWITEMSTRUCT lpDS){HBRUSH hbr = ::CreateSolidBrush(0);::FillRect(lpDS->hDC,&lpDS->rcItem,hbr);CDC memdc;memdc.Attach(lpDS->hDC);CDC bufferdc;bufferdc.CreateCompatibleDC(&memdc);CBitmap buffermap;buffermap.CreateCompatibleBitmap(&memdc,lpDS->rcItem.right-lpDS->rcItem.left,lpDS->rcItem.bottom-lpDS->rcItem.top);bufferdc.SelectObject(&buffermap);//Graphics gs(lpDS->hDC);Graphics gs(bufferdc.GetSafeHdc());UINT W = activeImage->GetWidth(),H = activeImage->GetHeight();if(lpDS->itemState&ODS_SELECTED)//按钮按下{gs.DrawImage(activeImage,0,0,W,H);}else if(m_hover)//鼠标移上{gs.DrawImage(hoverImage,0,0,W,H);}else//普通形态{gs.DrawImage(normalImage,0,0,W,H);}//gs.ReleaseHDC(lpDS->hDC);gs.ReleaseHDC(bufferdc.GetSafeHdc());memdc.BitBlt(0,0,lpDS->rcItem.right-lpDS->rcItem.left,lpDS->rcItem.bottom-lpDS->rcItem.top,&bufferdc,0,0,SRCCOPY);memdc.Detach();}void MyButton::OnMouseMove(UINT nFlags, CPoint point){if(!m_tracking){TRACKMOUSEEVENT tme;tme.cbSize = sizeof(tme);tme.dwFlags = TME_HOVER|TME_LEAVE;tme.dwHoverTime =1;tme.hwndTrack = m_hWnd;m_tracking = _TrackMouseEvent(&tme);}CButton::OnMouseMove(nFlags, point);}LRESULT MyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam){if(m_hover == true){m_hover = false;m_tracking = FALSE;Invalidate();}return 1;}LRESULT MyButton::OnMouseHover(WPARAM wParam, LPARAM lParam){if(m_hover == false){m_hover = true;m_tracking = FALSE;Invalidate();}return 1;}void MyButton::PreSubclassWindow(){CButton::PreSubclassWindow();ModifyStyle(0, BS_OWNERDRAW);}BOOL MyButton::OnEraseBkgnd(CDC* pDC){return true;}BOOL MyButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message){HCURSOR hCur = LoadCursor( NULL , IDC_HAND ) ;::SetCursor(hCur);return TRUE;}该类还是有很多不足之处,各位可以给点意见和建议,共同学习,共同进步。

源代码下载:

每个人心中,都会有一个古镇情怀,流水江南,烟笼人家。

MFC设计局域网对战五子棋游戏(二)实现GDI+自绘按钮

相关文章:

你感兴趣的文章:

标签云: