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

7 篇文章 0 订阅
6 篇文章 0 订阅

因为按钮位于对话框右侧的透明区域,如果使用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"


// MyButton

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




 该类还是有很多不足之处,各位可以给点意见和建议,共同学习,共同进步。


 

源代码下载: http://download.csdn.net/download/jokers_i/4223218

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值