C++ MFC 自定义控件:【按钮/CButton】,使用GDI贴图,设置图片、按钮圆角,点击切换图片,可实现多种按钮风格。

2 篇文章 1 订阅

C++ MFC GDI 自定义控件:按钮/CButton

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边

目录

C++ MFC GDI 自定义控件:按钮/CButton

文章目录

前言

一、如何制作MFC自定义控件?

二、使用步骤

1. stdafx.h 头文件最后加入:

2. 初始化GDI: 

3.创建自定义的ButtonEx头文件和实现: 

4.项目中使用ButtonEx: 

总结


的帮助文档

 

文章目录

 


前言

MFC一种古老的东西,作为一个小白,根据两个月的研究时间,从cout函数控制台应用程序,到Windows程序设计,最后接触MFC,翻遍网上的一些帖子和文章,并引以借鉴,终于汇总出一套可以使用的扩展按钮类:ButtonEx,共大家参考,有疑问或者bug,请联系我,源码:https://download.csdn.net/download/baidu_27541197/14950629!QQ:1245688904


提示:以下是本篇文章正文内容,下面案例可供参考

一、如何制作MFC自定义控件?

想要按钮上贴图,并且可以实现qq或者其他炫酷的控件,需要自己手写一个类,继承CButton,如果是做其他控件,道理是一样的,MFC不像QT,无法根据参数或属性设置图片,目前VS08及之前的版本是无法做到的,不过,MFCButton倒是可以实现,应该是VS08以后才支持使用MFCButton,不过好像也无法实现圆角的图片或者按钮,还是得靠自己去写,废话不多说了,直接上料...

二、使用步骤

1. stdafx.h 头文件最后加入:

代码如下(示例):

#include <comdef.h>   //初始化一下com口 
#pragma comment(lib,"gdiplus.lib")//引入库
#include <GdiPlus.h>//引入头文件
using namespace Gdiplus;//使用命名空间

 

2. 初始化GDI: 

 

创建CInitGdiplus头文件和实现

#pragma once
#include "StdAfx.h"
class CInitGdiplus
{
public:
	CInitGdiplus();
	~CInitGdiplus();
private:
	ULONG_PTR m_GdiplusToken;
	GdiplusStartupInput gdiplusStartupInput;
};

#include "stdafx.h"
#include "InitGdiplus.h"


CInitGdiplus::CInitGdiplus()
{
	GdiplusStartup(&m_GdiplusToken, &gdiplusStartupInput, NULL);
}


CInitGdiplus::~CInitGdiplus()
{
	GdiplusShutdown(m_GdiplusToken);
}

3.创建自定义的ButtonEx头文件和实现: 

  1. 创建FontEx类和实现,为了设置GDI文字的相关参数:
#pragma once

class FontEx
{
public:
	/************************************************************************/
	/* 是否赋值                                                                     */
	/************************************************************************/
	BOOL  IsAssignment;
	Gdiplus::Color m_color;
	const WCHAR  *m_name;
	Gdiplus::REAL m_cbSize ;
	FontEx();
	FontEx(Gdiplus::Color _color, const WCHAR*_name, Gdiplus::REAL _size);
}; 
#include "stdafx.h"
#include "FontEx.h"

FontEx::FontEx(Gdiplus::Color _color, const WCHAR*_name, Gdiplus::REAL _size) {
	m_color = _color;
	m_name = _name;
	m_cbSize = _size;
}

FontEx::FontEx()
{

}

     2.创建的ButtonEx头文件和实现,并继承CButton,(看过CButtonST和网上的其他资料,汇总出一个套简单的控件,没有其他多余的代码)

#pragma once

#include <locale>
#include <iostream>
#include <string>
#include <sstream>
#include "FontEx.h"
using namespace std;

class ButtonEx : public CButton
{
public:
	FontEx FontParam;
	std::wstring Text;
	std::wstring s2ws(const std::string& s);
	/************************************************************************/
	/* 是否在按钮抬起的时候禁用当前按钮,操作完成将无法切换成第一张图片,可实现互斥按钮                                                                    */
	/************************************************************************/
	BOOL IsButtonUpDisable;
	/************************************************************************/
	/* 是否已经禁用                                                                     */
	/************************************************************************/
	BOOL IsDisabled;
	/************************************************************************/
	/* 按钮显示图片的状态,是否当释放按钮时回到之前图片, 该参数为TRUE时,忽略IsButtonUpDisable参数                                                                */
	/************************************************************************/
	BOOL IsBounceBack ;
	/************************************************************************/
	/* 没有点击按钮默认显示第一张图片                                                                     */
	/************************************************************************/
	BOOL IsClick ;
	/************************************************************************/
	/* 左键是否按下,和           IsLButtonup相对                                                */
	/************************************************************************/
	BOOL IsLButtonDown;
	/************************************************************************/
	/* 左键是否弹起,和         IsLButtonDown相对                                                            */
	/************************************************************************/
	BOOL IsLButtonUp;
	/************************************************************************/
	/* 设置圆角度数                                                                     */
	/************************************************************************/
	UINT RoundSize ;
	/************************************************************************/
	/* 默认文字显示方式,此成员变量也可以设置文字显示的方式                                                                     */
	/************************************************************************/
	UINT TextAlign  ;
	/************************************************************************/
	/* 字体颜色的设置,此成员变量也可以设置文字显示的方式                                                                     */
	/************************************************************************/
	COLORREF TextColor;
	/************************************************************************/
	/*绘制按钮                                                                      */
	/************************************************************************/
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
	/************************************************************************/
	/* 获取按钮位置                                                                     */
	/************************************************************************/
	CRect GetButtonRect();
	/************************************************************************/
	/* 小图标数组                                                                     */
	/************************************************************************/
	WCHAR * IconResIds[2] ;
	/************************************************************************/
	/* 背景图片数组                                                                     */
	/************************************************************************/
	WCHAR * BkImageResIds[2] ;
	/************************************************************************/
	/* 设置图标,默认不设置,不显示                                                                     */
	/************************************************************************/
	UINT SetIcon(WCHAR* resourceId1, WCHAR* resourceId2);
	/************************************************************************/
	/* 设置背景图片   默认图片和按下图片                                                                   */
	/************************************************************************/
	UINT SetBkImage(WCHAR* resourceId1, WCHAR* resourceId2);
	/************************************************************************/
	/* 设置字体显示方式,默认是:DT_CENTER | DT_VCENTER | DT_SINGLELINE (注:只有在CDC模式下才可使用,也就是说未设置了按钮图片背景或者icon的情况下)    */
	/************************************************************************/
	void SetTextAlign(UINT);
	/************************************************************************/
	/* 设置字体颜色 (注:只有在CDC模式下才可使用,也就是说未设置了按钮图片背景或者icon的情况下)                                                                    */
	/************************************************************************/
	void SetTextColor(COLORREF colorRef);
	/************************************************************************/
	/* 设置按钮圆角大小                                                                     */
	/************************************************************************/
	void SetRoundSize(UINT);
	/************************************************************************/
	/* 设置字体的参数                                                                     */
	/************************************************************************/
	void SetFont(FontEx params);
	void SetButtonRound();
	ButtonEx();
	~ButtonEx();
	CRect IconRect;
public:
	DECLARE_MESSAGE_MAP()
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseHover(UINT nFlags, CPoint point);
	afx_msg void OnMouseLeave();
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnSetFocus(CWnd* pOldWnd);
	afx_msg void OnKillFocus(CWnd* pNewWnd);
private:
	SizeF GetTextBounds(const Gdiplus::Font& font,const StringFormat& strFormat,const WCHAR* szText);
	UINT DrawImage(CDC* pDC, UINT type, UINT resId);
	void CreateRoundImage(IN const WCHAR* imageUrl, CString cStr,BOOL isPressed, IN const WCHAR* iconUrl = NULL);
	void SetIconRect(CRect rect);
	CRect GetIconRect();
	/************************************************************************/
	/* 画圆角                                                                     */
	/************************************************************************/
	Gdiplus::GraphicsPath* MakeRoundRect(Point topLeft, Point bottomRight, INT percentageRounded);
};

#include "stdafx.h"
#include "ButtonEx.h"
#include "InitGdiplus.h"
#include "resource.h"
#include <math.h>
//创建背景
CInitGdiplus cInitGdiplus;
BEGIN_MESSAGE_MAP(ButtonEx, CButton)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_MOUSEHOVER()
	ON_WM_MOUSELEAVE()
	ON_WM_SETFOCUS()
	ON_WM_KILLFOCUS()
END_MESSAGE_MAP()
ButtonEx::ButtonEx()
{
	FontParam.IsAssignment=FALSE;
	if (!FontParam.IsAssignment)
	{
		FontEx FontExDefault(Gdiplus::Color(255, 0, 0, 0), L"Times New Roman", 14);
		FontParam = FontExDefault;
		FontParam.IsAssignment = TRUE;
	}
	/************************************************************************/
	/* 按钮显示图片的状态,是否当释放按钮时回到之前图片                                                                     */
	/************************************************************************/
	 IsBounceBack = FALSE;
	/************************************************************************/
	/* 没有点击按钮默认显示第一张图片                                                                     */
	/************************************************************************/
	 IsClick = FALSE;
	/************************************************************************/
	/* 设置圆角度数                                                                     */
	/************************************************************************/
	RoundSize = 50;
	/************************************************************************/
	/* 默认文字显示方式,此成员变量也可以设置文字显示的方式                                                                     */
	/************************************************************************/
	TextAlign = DT_CENTER | DT_VCENTER | DT_SINGLELINE;
	/************************************************************************/
	/* 字体颜色的设置,此成员变量也可以设置文字显示的方式                                                                     */
	/************************************************************************/
	TextColor = RGB(0, 0, 0);
	/************************************************************************/
	/* 小图标数组                                                                     */
	/************************************************************************/
	IconResIds[0] = NULL;
	IconResIds[1] = NULL;
	/************************************************************************/
	/* 背景图片数组                                                                     */
	/************************************************************************/
	BkImageResIds[0]= NULL;
	BkImageResIds[1]= NULL;
	/************************************************************************/
	/* 是否在按钮抬起的时候禁用当前按钮                                                                     */
	/************************************************************************/
	IsButtonUpDisable=FALSE;
	/************************************************************************/
	/* 是否已经禁用                                                                     */
	/************************************************************************/
	IsDisabled=FALSE;
}
CRect ButtonEx::GetButtonRect()
{
	CRect cRect;
	this->GetWindowRect(&cRect);
	this->ScreenToClient(&cRect);
	return cRect;
}
/************************************************************************/
/* 画圆角                                                                     */
/************************************************************************/
Gdiplus::GraphicsPath* ButtonEx::MakeRoundRect(Point topLeft, Point bottomRight, INT percentageRounded)
{
	ASSERT(percentageRounded >= 1 && percentageRounded <= 100);

	INT left = min(topLeft.X, bottomRight.X);
	INT right = max(topLeft.X, bottomRight.X);

	INT top = min(topLeft.Y, bottomRight.Y);
	INT bottom = max(topLeft.Y, bottomRight.Y);
	
	float offsetX = (right - left)*percentageRounded / 100;
	float offsetY = (bottom - top)*percentageRounded / 100;

	Gdiplus::GraphicsPath pt;
	Gdiplus::GraphicsPath * path = pt.Clone();

	float Width = right - left;
	float Height = bottom - top;
	// 小矩形的半宽(hew)和半高(heh)
	float hew = offsetX;
	float heh = offsetY;
	float x = 0;
	float y = 0;
	// 圆角修正
	if (fabs((hew - heh)) > 10)
	{
		hew = heh = hew > heh ? heh : hew;
	}

	// 保存绘图路径
	//path->AddLine(x+hew, y, x+Width-hew, y);  // 顶部横线
	path->AddArc(x + Width - 2 * hew, y, 2 * hew, 2 * heh, 270, 90); // 右上圆角
	path->AddArc(x + Width - 2 * hew, y + Height - 2 * heh, 2 * hew, 2 * heh, 0, 90); // 右下圆角
	path->AddArc(x, y + Height - 2 * heh, 2 * hew, 2 * heh, 90, 90); // 左下圆角
	path->AddArc(x, y, 2 * hew, 2 * heh, 180, 90); // 左上圆角
	return path;
}

std::wstring ButtonEx::s2ws(const std::string& s)
{
	setlocale(LC_ALL, "chs");
	const char* _Source = s.c_str();
	size_t _Dsize = s.size() + 1;
	wchar_t *_Dest = new wchar_t[_Dsize];
	wmemset(_Dest, 0, _Dsize);
	mbstowcs(_Dest, _Source, _Dsize);
	Text = _Dest;
	delete[]_Dest;
	setlocale(LC_ALL, "C");
	return Text;
}

/************************************************************************/
/* 创建圆角图片                                                                     */
/************************************************************************/
void ButtonEx::CreateRoundImage(IN const WCHAR* imageUrl, CString cStr, BOOL isPressed,IN const WCHAR* iconUrl)
{
	if (imageUrl == NULL)
		return;
	CRect itemRect = GetButtonRect();
	CDC *pDC = GetDC();
	HDC hdc = pDC->GetSafeHdc();
	Gdiplus::Graphics graphics(hdc);
	//设置画图时的滤波模式为消除锯齿现象
	graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
	//设置为圆角
	Gdiplus::GraphicsPath *gp = MakeRoundRect(Point(0, 0), Point(itemRect.right, itemRect.bottom), RoundSize);
	// Draw the outline of the region.
	Gdiplus::Region region(gp);
	//pen
	Gdiplus::Pen pen(Color(0, 0, 0, 0));
	graphics.DrawPath(&pen, gp);
	// Set the clipping region of the Graphics object.
	graphics.SetClip(&region);
	//创建图片
	Gdiplus::Image image(imageUrl);
	UINT width = image.GetWidth();
	UINT height = image.GetHeight();
	graphics.DrawImage(&image, 0, 0, itemRect.Width(), itemRect.Height());

	//渐变背景
	// Create a path gradient brush based on the elliptical path.
	PathGradientBrush pthGrBrush(gp);
	pthGrBrush.SetGammaCorrection(TRUE);
	// Set the color along the entire boundary to blue.
	Color color(Color(1, 0, 0, 0));
	INT num = 1;
	pthGrBrush.SetSurroundColors(&color, &num);
	// Set the center point to a location that is not the centroid of the path.
	if (isPressed)
	{
			pthGrBrush.SetCenterPoint(Point( itemRect.Width()-30,itemRect.Height()/2+30));
	}else{
			pthGrBrush.SetCenterPoint(Point( itemRect.Width(),itemRect.Height()));
	}

	// Set the center color to aqua.
	pthGrBrush.SetCenterColor(Color(255, 255, 255, 255));
	// Use the path gradient brush to fill the ellipse. 
	graphics.FillPath(&pthGrBrush, gp);
	// Set the focus scales for the path gradient brush.
	pthGrBrush.SetFocusScales(0.8f, 0.8f);


	//绘制图标
	BOOL isDrawIcon = FALSE;
	float offsetIconX(0);
	if (iconUrl != NULL)
	{
		offsetIconX = 10;
		isDrawIcon = TRUE;
		Gdiplus::Image iconImage(iconUrl);
		width = iconImage.GetWidth();
		height = iconImage.GetHeight();
		graphics.DrawImage(&iconImage, offsetIconX, (float)((itemRect.bottom - height) / 2), width, height);
	}


	//绘制文字
	wstring wchars = s2ws(cStr.GetString()).c_str();
	if (wchars.length() > 0)
	{
		SolidBrush  brush(FontParam.m_color);
		FontFamily  fontFamily(FontParam.m_name);
		StringFormat stringformat(StringAlignmentNear);
		Gdiplus::Font   font(&fontFamily, FontParam.m_cbSize, FontStyleRegular, UnitPixel);
		REAL size = font.GetSize();
		//开始逻辑校验
		float offsetX(0);
		//是否绘制图标
		if (isDrawIcon) {
			offsetIconX = (width + offsetIconX) / 2;
		}
		UINT strLength = wchars.length();
		SizeF sizef= GetTextBounds(font,&stringformat,wchars.c_str());
		offsetX = (itemRect.Width() - sizef.Width-size/2)/2;
		Gdiplus::PointF     pointF(offsetX + offsetIconX, itemRect.Height() / 2 - font.GetHeight(&graphics) / 2 );
		graphics.DrawString(wchars.c_str(), -1, &font, pointF, &brush);
	}
	graphics.ReleaseHDC(hdc);
	delete gp;
	gp = NULL;
}

SizeF ButtonEx::GetTextBounds(const Gdiplus::Font& font,const StringFormat& strFormat,const WCHAR* szText)
{
	GraphicsPath graphicsPathObj;
	FontFamily fontfamily;
	font.GetFamily(&fontfamily);
	graphicsPathObj.AddString(szText,-1,&fontfamily,font.GetStyle(),font.GetSize(),\
		PointF(0,0),&strFormat);
	RectF rcBound;

	/// 获取边界范围
	graphicsPathObj.GetBounds(&rcBound);
	/// 返回文本的宽高
	return SizeF(rcBound.Width,rcBound.Height);
}


void ButtonEx::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
	CDC*	pDC = CDC::FromHandle(lpDIS->hDC);
	//获取文字
	CString character;
	GetWindowText(character);
	//获取按钮的位置
	CRect btnRect= GetButtonRect();
	//是否存在图片
	BOOL  isExistsImg= !(
		BkImageResIds[0]==NULL&&BkImageResIds[1]==NULL&&
		IconResIds[0]==NULL&&IconResIds[1]==NULL);
	if(isExistsImg){
		pDC->SetBkMode(TRANSPARENT);
		pDC->SelectStockObject(NULL_BRUSH);
	}

	CRect itemRect = lpDIS->rcItem;
	//设置圆角按钮
	SetButtonRound();
	//画背景
	//画ICON
	//是否按下按钮
	BOOL m_bIsPressed = (lpDIS->itemState & ODS_SELECTED);
	int index;
	if (IsBounceBack)
	{
		index=m_bIsPressed?1:0;
	}
	else
	{
		index=IsClick?1:0;
	}
	if (isExistsImg)
	{
		CreateRoundImage(BkImageResIds[index], character,index, IconResIds[index]);
	}else{
		pDC->RoundRect(&btnRect,CPoint(RoundSize,RoundSize));
		pDC->SetBkColor(RGB(255,0,0));
		pDC->SetTextColor(TextColor);
		pDC->DrawText(character,&btnRect,TextAlign);
	}
}


UINT ButtonEx::SetIcon(WCHAR* resourceId1, WCHAR* resourceId2)
{
	IconResIds[0] = resourceId1;
	IconResIds[1] = resourceId2;
	return 0;
}

UINT ButtonEx::SetBkImage(WCHAR* resourceId1, WCHAR* resourceId2)
{
	BkImageResIds[0] = resourceId1;
	BkImageResIds[1] = resourceId2;
	return 0;
}

void ButtonEx::SetButtonRound()
{
	CRect itemRect = GetButtonRect();
	//创建圆角矩形
	HRGN h_rgn = CreateRoundRectRgn(0, 0, itemRect.Width()+1, itemRect.Height()+1, RoundSize, RoundSize);
	SetWindowRgn(h_rgn, FALSE);
}

UINT ButtonEx::DrawImage(CDC* pDC, UINT type, UINT resId)
{
	if (resId == NULL)
		return -1;
	CRect winRect = GetButtonRect();
	//设置背景图为自适应
	int imgX(0);
	int imgY(0);
	if (type == 1)
	{
		imgX = winRect.Width();
		imgY = winRect.Height();
	}
	HBITMAP hBitmapIn = (HBITMAP)::LoadImage(AfxFindResourceHandle(MAKEINTRESOURCE(resId), RT_BITMAP), MAKEINTRESOURCE(resId), IMAGE_BITMAP, imgX, imgY, 0);
	BITMAP	csBitmapSize;
	HBITMAP hbmSrcT;
	int nRetValue = ::GetObject(hBitmapIn, sizeof(csBitmapSize), &csBitmapSize);
	UINT dwWidth = (DWORD)csBitmapSize.bmWidth;
	UINT dwHeight = (DWORD)csBitmapSize.bmHeight;
	HDC	hdcSrc = ::CreateCompatibleDC(NULL);
	hbmSrcT = (HBITMAP)::SelectObject(hdcSrc, hBitmapIn);
	//画图标
	if (type == 0)
	{
		winRect.left = winRect.left + 10;
		winRect.top = (winRect.bottom - winRect.top) / 2 - dwHeight / 2;
		//记录当前icon位置和other
		CRect iconRect;
		iconRect.left = winRect.left;
		iconRect.top = winRect.top;
		iconRect.right = dwWidth;
		iconRect.bottom = dwHeight;
		SetIconRect(iconRect);
		::BitBlt(pDC->GetSafeHdc(), winRect.left, winRect.top, dwWidth, dwHeight, hdcSrc, 0, 0, SRCCOPY);
	}
	else {
		//画位图
		::BitBlt(pDC->GetSafeHdc(), 0, 0, winRect.Width(), winRect.Height(), hdcSrc, 0, 0, SRCCOPY);
	}
	::SelectObject(hdcSrc, hbmSrcT);
	::DeleteDC(hdcSrc);
	::DeleteObject(hbmSrcT);
	return 0;
}
void ButtonEx::SetIconRect(CRect rect)
{
	IconRect = rect;
}

CRect ButtonEx::GetIconRect()
{
	return IconRect;
}
void ButtonEx::SetTextAlign(UINT VAR)
{
	TextAlign = VAR;
}

void ButtonEx::SetTextColor(COLORREF colorRef)
{
	TextColor=colorRef;
}

void ButtonEx::SetRoundSize(UINT size = 50)
{
	RoundSize = size;
}

void ButtonEx::SetFont(FontEx params)
{
	FontParam = params;
	FontParam.IsAssignment = TRUE;
}

void ButtonEx::OnLButtonDown(UINT nFlags, CPoint point)
{
	IsLButtonDown = TRUE;
	IsLButtonUp = FALSE;
	CButton::OnLButtonDown(nFlags, point);
	ClientToScreen(&point);
	CWnd*		wndUnderMouse = WindowFromPoint(point);
	HWND hWnd = wndUnderMouse->m_hWnd;
	if (IsBounceBack)
	{
		return;
	}
	//
	if (wndUnderMouse&& wndUnderMouse->m_hWnd == m_hWnd&&nFlags&MK_LBUTTON)
	{
		CString character;
		GetWindowText(character);
		IsClick = !IsClick;
		if (IsClick)
		{
			CreateRoundImage(BkImageResIds[1], character,1, IconResIds[1]);
		}
		else {
			CreateRoundImage(BkImageResIds[0], character,0, IconResIds[0]);
		}

	}
}

void ButtonEx::OnLButtonUp(UINT nFlags, CPoint point)
{
	if (!IsLButtonDown)
	{
		return;
	}
	IsLButtonDown = FALSE;
	CButton::OnLButtonUp(nFlags, point);
	ClientToScreen(&point);
	CWnd*		wndUnderMouse = WindowFromPoint(point);
	HWND hWnd = wndUnderMouse->m_hWnd;
	if (IsBounceBack)
	{
		return;
	}
	if (wndUnderMouse&& wndUnderMouse->m_hWnd == m_hWnd){
		IsLButtonUp = TRUE;
		if(IsButtonUpDisable){
			EnableWindow(0);
			IsDisabled=TRUE;
		}
	}else{
		CString character;
		GetWindowText(character);
		IsClick = !IsClick;
		if (IsClick)
		{
			CreateRoundImage(BkImageResIds[1], character,1, IconResIds[1]);
		}
		else {
			CreateRoundImage(BkImageResIds[0], character,0, IconResIds[0]);
		}
	}
}

void ButtonEx::OnMouseHover(UINT nFlags, CPoint point)
{
	CButton::OnMouseHover(nFlags, point);
}

void ButtonEx::OnMouseLeave()
{
	CButton::OnMouseLeave();
}

void ButtonEx::OnMouseMove(UINT nFlags, CPoint point)
{
	TRACKMOUSEEVENT tme;
	tme.cbSize = sizeof(TRACKMOUSEEVENT);
	tme.dwFlags = TME_LEAVE | TME_HOVER;
	tme.hwndTrack = GetSafeHwnd();
	tme.dwHoverTime = 80;
	_TrackMouseEvent(&tme);
	CButton::OnMouseMove(nFlags, point);
}




void ButtonEx::OnSetFocus(CWnd* pOldWnd)
{

}

void ButtonEx::OnKillFocus(CWnd* pNewWnd)
{
	ButtonEx *bx = (ButtonEx*)pNewWnd;

}

ButtonEx::~ButtonEx()
{
}

       中间有一段DrawImage方法,这个方式是我踩坑的时候用的,目前没有用到可以删掉,CButtonST就是用这种方式做的,CDC绘制,LoadImage加载的图片无法设置成圆角,需要你自己提供一张圆角的图,相比而言,麻烦的多。

       我采用的GDI绘制的圆角的图片,可以设置图片和按钮矩形圆角,边框会做处理,设置RoundSize:50度就已经是圆角了;当贴上图片时,会按照按钮的尺寸的大小,设置背景图片,同时也可设置按钮的Icon,具体方法有:SetIcon、SetBkImage,显而易见,如果没有设置背景图片,则显示白色背景,DrawItem那块可以手动改一下相关逻辑。

4.项目中使用ButtonEx: 

处理完以后,在项目过程中使用,引入头文件:ButtonEx.h,把所有CButton成员变量,改成ButtonEx ,手写一个类,处理绑定的图片或者手动设置单独的某一个按钮的图片逻辑。InitDialog方法添加:

CWnd * km_cWnd=this->GetWindow(GW_CHILD);
	char  csClsName[MAX_PATH];
	while (km_cWnd)
	{
		GetClassName(km_cWnd->m_hWnd,csClsName,MAX_PATH);
		if (stricmp(csClsName,"Button")==0)
		{
			ButtonEx *thatBtn=(ButtonEx*)km_cWnd;
			thatBtn->SetBkImage(L"bk2.bmp",L"bk3.bmp");//默认图片,点击以后的图片
			thatBtn->SetIcon(L"1.bmp",L"2.bmp");//设置图标,同理
			thatBtn->SetRoundSize(50);//圆角
			thatBtn->SetFont(FontEx(Color(255,0,255,198),L"微软雅黑",15));//设置字体
			btnCount++;
		}
		km_cWnd=km_cWnd->GetNextWindow();
	}

 目前Icon在左边,你要想设置到其他位置,你自己可以改ButtonEx中GDI画icon的代码,都有注释,看着改。

 因为按钮在设置圆角以后需要reDraw一下,但是我发现在ButtonEx中设置会出现问题,不停闪烁,所以只能这么做,当前自己的项目中实现OnCtlColor方法:

//头文件中写:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);

//实现中写:
HBRUSH xxxDialogxxx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
	// TODO:  Change any attributes of the DC here
	char lpClassName[MAX_PATH];
	GetClassName(pWnd->m_hWnd,lpClassName,MAX_PATH);
	if (stricmp(lpClassName,_T("Button"))==0)
	{
		//属性设置为透明 
		pDC->SetBkMode(TRANSPARENT);
		// TODO:  如果默认的不是所需画笔,则返回另一个画笔
		return (HBRUSH)::GetStockObject(NULL_BRUSH); //不返回画刷 
	}
	// TODO:  Return a different brush if the default is not desired
	return hbr;
}

// 实现中映射写
BEGIN_MESSAGE_MAP(xxxDialogxxx,CDialogEx)
        ON_WM_CTLCOLOR()//实现中添加
END_MESSAGE_MAP()

 最后设置Dialog对话框窗口,设置按钮的Owner Draw=true就行了。

 

 


总结

提示:扩展按钮控件这种东西,无法在OnPaint函数中调用,会出现很严重的问题,大家可以试试。

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baidu_27541197

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值