transbutton.cpp

来自「网狐棋牌(家园版)最新版本7.1.1源代码,共享组件源码」· C++ 代码 · 共 434 行

CPP
434
字号
#include "Stdafx.h"
#include "Resource.h"
#include "TransButton.h"

//////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC(TransButton, CButton)

BEGIN_MESSAGE_MAP(TransButton, CButton)
	ON_WM_CREATE()
	ON_WM_MOUSEMOVE()
	ON_WM_ERASEBKGND()
	ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////////////////

//宏定义
#define DEF_TEXT_COLOR				RGB(10,10,10)							//默认颜色
#define DEF_TEXT_COLOR_EX			RGB(10,10,10)							//默认颜色

//静态变量
TransButtonAttribute				TransButton::m_SkinAttribute;			//按钮属性

//////////////////////////////////////////////////////////////////////////

//构造函数
TransButtonAttribute::TransButtonAttribute() : CSkinAttribute(TEXT("TransButton"))
{
	//初始化变量
	m_crTextColor=DEF_TEXT_COLOR;

	//注册属性
	RegisterAttribute(SKIN_BUTTON_CRTEXTCOLOR,&m_crTextColor,false);
	RegisterAttribute(SKIN_BUTTON_STRIMAGEPATH,&m_strImagePath,false);

	return;
}

//析构函数
TransButtonAttribute::~TransButtonAttribute() 
{
}

//加载配置
bool __cdecl TransButtonAttribute::LoadSkinOption()
{
	//读取字体颜色
	m_crTextColor=ReadColor(SKIN_BUTTON_CRTEXTCOLOR,DEF_TEXT_COLOR);
	m_ImageBack.SetLoadInfo(IDB_SKIN_BUTTON_BACK,GetModuleHandle(SKIN_CONTROL_DLL_NAME));

	return true;
}

//保存配置
bool __cdecl TransButtonAttribute::SaveSkinOption()
{
	WriteColor(SKIN_BUTTON_CRTEXTCOLOR,m_crTextColor);
	WriteString(SKIN_BUTTON_STRIMAGEPATH,m_strImagePath);
	return true;
}

//////////////////////////////////////////////////////////////////////////

//构造函数
TransButton::TransButton()
{
	m_hIcon=NULL;
	m_bExpand=true;
	m_bHovering=false;
	m_pIMouseEvent=NULL;
	m_crTextColor=m_SkinAttribute.m_crTextColor;
}

//析构函数
TransButton::~TransButton()
{
}

//对象附加到现有窗口
void TransButton::PreSubclassWindow()
{
	__super::PreSubclassWindow();
	SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);
	SendMessage(WM_SETFONT,(WPARAM)m_SkinAttribute.GetDefaultFont(),TRUE);
	return;
}

//建立消息
int TransButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (__super::OnCreate(lpCreateStruct)==-1) return -1;
	SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);
	SendMessage(WM_SETFONT,(WPARAM)m_SkinAttribute.GetDefaultFont(),TRUE);
	return 0;
}

//设置颜色
bool TransButton::SetTextColor(COLORREF crTextColor)
{
	m_crTextColor=crTextColor;
	if (GetSafeHwnd()) Invalidate(FALSE);
	return true;
}

//设置图标
bool TransButton::SetButtonIcon(HICON hIcon)
{
	m_hIcon=hIcon;
	if (GetSafeHwnd()) Invalidate(FALSE);
	return true;
}

//加载位图
bool TransButton::SetButtonImage(LPCTSTR pszFileName, bool bExpandImage)
{
	//效验参数
	ASSERT(pszFileName);
	if (pszFileName==NULL) return false;

	//加载位图
	m_bExpand=bExpandImage;
	m_ImageBack.SetLoadInfo(pszFileName);

	//调整位置
	if (m_bExpand==false) FixButtonSize();
	if (GetSafeHwnd()) Invalidate(FALSE);

	return true;
}

//加载位图
bool TransButton::SetButtonImage(UINT uBitmapID, HINSTANCE hInstance, bool bExpandImage)
{
	//加载位图
	ASSERT(uBitmapID!=0);
	if (uBitmapID==0) return false;
	m_bExpand=bExpandImage;
	m_ImageBack.SetLoadInfo(uBitmapID,hInstance);

	//调整位置
	if (m_bExpand==false) FixButtonSize();
	if (GetSafeHwnd()) Invalidate(FALSE);

	return true;
}

//获取位图参数
bool TransButton::GetButtonLoadInfo(tagImageLoadInfo & LoadInfo)
{
	if (m_ImageBack.IsSetLoadInfo()) return m_ImageBack.GetLoadInfo(LoadInfo);
	return m_SkinAttribute.m_ImageBack.GetLoadInfo(LoadInfo);
}

//默认按钮
void TransButton::SetDefaultButton(bool bResetIcon, bool bResetColor, bool bResetImage)
{
	//恢复默认
	if (bResetImage) 
	{
		m_bExpand=true;
		m_ImageBack.RemoveLoadInfo();
	}
	if (bResetIcon)	m_hIcon=NULL;
	if (bResetColor) m_crTextColor=m_SkinAttribute.m_crTextColor;

	//刷新界面
	if (GetSafeHwnd()) Invalidate(FALSE);

	return;
}

//调整位置
bool TransButton::FixButtonSize()
{
	if (m_ImageBack.IsSetLoadInfo()&&GetSafeHwnd())
	{
		CImageHandle ImageHandle(&m_ImageBack);
		SetWindowPos(NULL,0,0,ImageHandle->GetWidth()/5,ImageHandle->GetHeight(),SWP_NOMOVE);
		return true;
	}
	return false;
}

//鼠标移动消息
void TransButton::OnMouseMove(UINT nFlags, CPoint point)
{
	if (m_bHovering==false)
	{
		//注册消息
		m_bHovering=true;
		Invalidate(FALSE);
		TRACKMOUSEEVENT TrackMouseEvent;
		TrackMouseEvent.cbSize=sizeof(TrackMouseEvent);
		TrackMouseEvent.dwFlags=TME_LEAVE;
		TrackMouseEvent.hwndTrack=GetSafeHwnd();
		TrackMouseEvent.dwHoverTime=HOVER_DEFAULT;
		_TrackMouseEvent(&TrackMouseEvent);
	}
	__super::OnMouseMove(nFlags, point);
}

//鼠标离开消息
LRESULT TransButton::OnMouseLeave(WPARAM wparam, LPARAM lparam)
{
	m_bHovering=false;
	Invalidate(FALSE);
	return 0;
}

//背景函数
BOOL TransButton::OnEraseBkgnd(CDC * pDC)
{
	Invalidate(FALSE);
	UpdateWindow();
	return TRUE;
}

//界面绘画函数
void TransButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	//定义变量
	CRect ClientRect;
	GetClientRect(&ClientRect);
	bool bDisable=((lpDrawItemStruct->itemState&ODS_DISABLED)!=0);
	bool bButtonDown=((lpDrawItemStruct->itemState&ODS_SELECTED)!=0);

	//设置 DC
	HDC hDC=lpDrawItemStruct->hDC;
	///////////////////////////////////////////////////////////////////////

	CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);

	//目前m_ImageBack是没有用到的参数
	//在SetupRgn中以GetButtonLoadInfo(buttonInfo)得到了按钮的位图信息
	SetupRgn(pDC,m_ImageBack,RGB(255,0,255));

	//CBitmap cBitmap;
	//cBitmap.LoadBitmap(IDB_SKIN_MASK);
	//此IDB_SKIN_MASK为手动裁剪的一个按钮的1/5.目前按钮透明没有问题。
	//如能将此CPP中的m_ImageBack裁剪下1/5,则透明按钮可共用

	///////////////////////////////////////////////////////////////////////
	//获取文字
	CString strText;
	GetWindowText(strText);

	//加载背景图
	CImageHandle ImageHandle;
	if (m_ImageBack.IsSetLoadInfo()) ImageHandle.AttachResource(&m_ImageBack);
	else ImageHandle.AttachResource(&m_SkinAttribute.m_ImageBack);
	if (ImageHandle.IsResourceValid())
	{
		//计算位图位置
		int iPartWidth=ImageHandle->GetWidth()/5,iDrawPos=0;
		if (bDisable) iDrawPos=iPartWidth*4;
		else if (bButtonDown) iDrawPos=iPartWidth;
		else if (m_bHovering) iDrawPos=iPartWidth*3;
		else if (lpDrawItemStruct->itemState&ODS_FOCUS)	iDrawPos=iPartWidth*2;

		//绘画背景图
		if (m_bExpand==false) 
		{
			//ImageHandle->BitBlt(hDC,0,0,ClientRect.Width(),ClientRect.Height(),iDrawPos,0,SRCCOPY);
			ImageHandle->AlphaDrawImage(pDC,0,0,ClientRect.Width(),ClientRect.Height(),iDrawPos,0,RGB(255,0,255));
		}
		else 
			ImageHandle->StretchBlt(hDC,0,0,ClientRect.Width(),ClientRect.Height(),iDrawPos,0,iPartWidth,ImageHandle->GetHeight(),SRCCOPY);
	}
	else
	{
		//绘画默认界面
		CDC * pDC=CDC::FromHandle(hDC);
		pDC->FillSolidRect(&ClientRect,GetSysColor(COLOR_BTNFACE));
		if (bButtonDown) pDC->Draw3dRect(&ClientRect,GetSysColor(COLOR_WINDOWFRAME),GetSysColor(COLOR_3DHILIGHT));
		else pDC->Draw3dRect(&ClientRect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_WINDOWFRAME));
	}

	//绘画图标
	if (bButtonDown) ClientRect.top+=2;
	if (m_hIcon)
	{
		DrawIconEx(hDC,ClientRect.left+6,ClientRect.top+(ClientRect.Height()-16)/2+1,m_hIcon,16,16,0,NULL,DI_NORMAL);
		ClientRect.left+=22;
	}

	//绘画字体
	ClientRect.top+=1;
	::SetBkMode(hDC,TRANSPARENT);
	if (bDisable) ::SetTextColor(hDC,GetSysColor(COLOR_GRAYTEXT));
	else ::SetTextColor(hDC,m_crTextColor);
	DrawText(hDC,strText,strText.GetLength(),ClientRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);

	return;
}
void TransButton::SetupRgn(CDC *pDC,				//窗体的DC指针
						   //CBitmap &cBitmap,		//含有窗体形状的位图对象
						   CSkinImage bImage,
						   COLORREF TransColor)	//透明色
{
	///////////////////////////////////////////////////////////////
	//bimage中可能不包含IDB信息。。。。此路不通
	//能否寻找到cskinimage到bmp的转换?
	////从CSkinImage中得到资源IDB
	//tagImageLoadInfo imageIDB;
	//bImage.GetLoadInfo(imageIDB.uResourceID);
	//从IDB中得到BMP
	//CBitmap cBitmap;
	//cBitmap.LoadBitmap(imageIDB);

	//int IWidth,IHeight;
	//IWidth=bImage.GetWidth()/5;
	//IHeight=bImage.GetHeight();

	//CBitmap cBitmap;
	//cBitmap.LoadBitmap(IDB_SKIN_MASK);

	//从按钮装载信息将按钮图片载入BMP,根据BMP确定透明区域
	tagImageLoadInfo buttonInfo;
	GetButtonLoadInfo(buttonInfo);

	CBitmap cBitmap;
	if((buttonInfo.strFileName)!="")
		cBitmap.LoadBitmap(buttonInfo.strFileName);
	else if((buttonInfo.uResourceID)!=0)
		cBitmap.LoadBitmap(buttonInfo.uResourceID);

	//////////////////////////////////////////////////////////////////


	CDC memDC;
	//创建与传入DC兼容的临时DC
	memDC.CreateCompatibleDC(pDC);

	CBitmap *pOldMemBmp=NULL;
	//将位图选入临时DC
	pOldMemBmp=memDC.SelectObject(&cBitmap);

	CRgn wndRgn;
	//创建总的窗体区域,初始region为0
	wndRgn.CreateRectRgn(0,0,0,0);


	BITMAP bit;   
	cBitmap.GetBitmap (&bit);//取得位图参数,这里要用到位图的长和宽     

	int y;
	for(y=0;y<=bit.bmHeight  ;y++)
	{
		CRgn rgnTemp; //保存临时region

		int iX = 0;
		do
		{
			//跳过透明色找到下一个非透明色的点.
			while (iX <= bit.bmWidth/5  && memDC.GetPixel(iX, y) == TransColor)
				iX++;

			//记住这个起始点
			int iLeftX = iX;

			//寻找下个透明色的点
			while (iX <= bit.bmWidth/5  && memDC.GetPixel(iX, y) != TransColor)
				++iX;

			//创建一个包含起点与重点间高为1像素的临时“region”
			rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1);

			//合并到主"region".
			wndRgn.CombineRgn(&wndRgn, &rgnTemp, RGN_OR);

			//删除临时"region",否则下次创建时和出错
			rgnTemp.DeleteObject();
		}while(iX <bit.bmWidth/5 );
		iX = 0;
	}
	if(pOldMemBmp)
		memDC.SelectObject(pOldMemBmp);
	CWnd * pWnd = pDC->GetWindow();
	pWnd->SetWindowRgn(wndRgn,TRUE);    
	pWnd->SetForegroundWindow();    
}

//默认回调函数
LRESULT TransButton::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	if (m_pIMouseEvent)
	{
		switch (message)
		{
		case WM_MOUSELEAVE:
			{
				UINT uButtonID=GetWindowLong(GetSafeHwnd(),GWL_ID);
				m_pIMouseEvent->OnEventMouseLeft(uButtonID,wParam,lParam);
				break;
			}
		case WM_MOUSEMOVE:
			{
				UINT uButtonID=GetWindowLong(GetSafeHwnd(),GWL_ID);
				m_pIMouseEvent->OnEventMouseMove(uButtonID,wParam,lParam);
				break;
			}
		case WM_LBUTTONDOWN:
			{
				UINT uButtonID=GetWindowLong(GetSafeHwnd(),GWL_ID);
				m_pIMouseEvent->OnEventLButtonDown(uButtonID,wParam,lParam);
				break;
			}
		case WM_LBUTTONUP:
			{
				UINT uButtonID=GetWindowLong(GetSafeHwnd(),GWL_ID);
				m_pIMouseEvent->OnEventLButtonUp(uButtonID,wParam,lParam);
				break;
			}
		case WM_RBUTTONDOWN:
			{
				UINT uButtonID=GetWindowLong(GetSafeHwnd(),GWL_ID);
				m_pIMouseEvent->OnEventRButtonDown(uButtonID,wParam,lParam);
				break;
			}
		case WM_RBUTTONUP:
			{
				UINT uButtonID=GetWindowLong(GetSafeHwnd(),GWL_ID);
				m_pIMouseEvent->OnEventRButtonUp(uButtonID,wParam,lParam);
				break;
			}
		}
	}
	return __super::DefWindowProc(message, wParam, lParam);
}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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