转载:https://blog.csdn.net/songyimin1208/article/details/54408296
1.InitInstance初始化GDI
#include <gdiplus.h>
#pragma comment(lib,"gdiplus.lib")
class CtestMFCButtonApp : public CWinApp { public: CtestMFCButtonApp(); // 重写 public: virtual BOOL InitInstance(); virtual int ExitInstance(); // 实现 DECLARE_MESSAGE_MAP() private: Gdiplus::GdiplusStartupInput m_gdiplusStartupInput; ULONG_PTR m_pGdiToken; };
BOOL CtestMFCButtonApp::InitInstance() { ....................... CWinApp::InitInstance(); GdiplusStartup(&m_pGdiToken, &m_gdiplusStartupInput, NULL); ....................... } int CtestMFCButtonApp::ExitInstance() { Gdiplus::GdiplusShutdown(m_pGdiToken); return 0; }
2.自定义Button类
PicButton.h
#pragma once #include "afxwin.h" #include <gdiplus.h> #pragma comment(lib,"gdiplus.lib") class CPicButton :public CButton { DECLARE_DYNAMIC(CPicButton) public: CPicButton(); ~CPicButton(); enum BUTTON_STATE { BUTTON_ENABLE = 0, BUTTON_HOVER = 1, BUTTON_CLICK = 2, BUTTON_DISABLE = 3 }; protected: afx_msg LRESULT OnMouseLeave(WPARAM wparam, LPARAM lparam); afx_msg LRESULT OnMouseHover(WPARAM wparam, LPARAM lparam); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); protected: virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam); void CPicButton::PreSubclassWindow(); DECLARE_MESSAGE_MAP() public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); void SetButtonImage(Gdiplus::Image* img); private: BOOL m_bDisable; // 按钮是否禁用 BOOL m_bCursorOnButton; // 鼠标是否在按钮上 BOOL m_bPress; // 按钮是否被按下 int m_nWidth; //图片宽 int m_nHeight; //图片高 int m_nSliceWidth; //每一块图片的宽 Gdiplus::Image* m_btnImage;//按钮图片 CRect m_rectButton;//按钮区域 };
PicButton.cpp
#include "stdafx.h" #include "PicButton.h" IMPLEMENT_DYNAMIC(CPicButton, CButton) CPicButton::CPicButton() { m_bDisable = FALSE; m_bCursorOnButton = FALSE; m_bPress = FALSE; } CPicButton::~CPicButton() { if (m_btnImage) { delete m_btnImage; m_btnImage = NULL; } } } BEGIN_MESSAGE_MAP(CPicButton, CButton) ON_WM_MOUSEMOVE() ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover) ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_ERASEBKGND() END_MESSAGE_MAP() void CPicButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); Gdiplus::Graphics graphics(pDC->m_hDC); if (m_bDisable == TRUE) { graphics.DrawImage(m_btnImage, Gdiplus::Rect(0, 0, m_nSliceWidth, m_nHeight), BUTTON_DISABLE * m_nSliceWidth, 0, m_nSliceWidth, m_nHeight, Gdiplus::UnitPixel, NULL, NULL, NULL); } else { // click state if (lpDrawItemStruct->itemState & ODS_SELECTED) { graphics.DrawImage(m_btnImage, Gdiplus::Rect(0, 0, m_nSliceWidth, m_nHeight), BUTTON_CLICK * m_nSliceWidth, 0, m_nSliceWidth, m_nHeight, Gdiplus::UnitPixel, NULL, NULL, NULL); } // hover state else if (m_bPress) { graphics.DrawImage(m_btnImage, Gdiplus::Rect(0, 0, m_nSliceWidth, m_nHeight), BUTTON_HOVER * m_nSliceWidth, 0, m_nSliceWidth, m_nHeight, Gdiplus::UnitPixel, NULL, NULL, NULL); } // enable state else { graphics.DrawImage(m_btnImage, Gdiplus::Rect(0, 0, m_nSliceWidth, m_nHeight), BUTTON_ENABLE*m_nSliceWidth, 0, m_nSliceWidth, m_nHeight, Gdiplus::UnitPixel, NULL, NULL, NULL); } } } void CPicButton::SetButtonImage(Gdiplus::Image* img) { if (m_btnImage != NULL) { delete m_btnImage; m_btnImage = img; } else { m_btnImage = img; } if (m_btnImage) { m_nWidth = m_btnImage->GetWidth(); m_nHeight = m_btnImage->GetHeight(); m_nSliceWidth = m_nWidth; //图片切成四分 CWnd *pWnd = this->GetParent(); GetWindowRect(&m_rectButton); pWnd->ScreenToClient(m_rectButton); m_rectButton.right = m_rectButton.left + m_nSliceWidth; m_rectButton.bottom = m_rectButton.top + m_nHeight; MoveWindow(m_rectButton); //调整按钮大小以适应图片 } Invalidate(); } void CPicButton::PreSubclassWindow() { ModifyStyle(0, BS_OWNERDRAW); CButton::PreSubclassWindow(); } LRESULT CPicButton::OnMouseLeave(WPARAM wparam, LPARAM lparam) { m_bCursorOnButton = FALSE; m_bPress = FALSE; Invalidate(); return 0L; } LRESULT CPicButton::OnMouseHover(WPARAM wparam, LPARAM lparam) { m_bPress = TRUE; Invalidate(); return 0L; } BOOL CPicButton::OnEraseBkgnd(CDC* pDC) { return TRUE; } void CPicButton::OnMouseMove(UINT nFlags, CPoint point) { if (m_bCursorOnButton == FALSE) { TRACKMOUSEEVENT tme; ZeroMemory(&tme, sizeof(TRACKMOUSEEVENT)); tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1; m_bCursorOnButton = _TrackMouseEvent(&tme); } } void CPicButton::OnLButtonDown(UINT nFlags, CPoint point) { Invalidate(); CButton::OnLButtonDown(nFlags, point); } void CPicButton::OnLButtonUp(UINT nFlags, CPoint point) { Invalidate(); CButton::OnLButtonUp(nFlags, point); } LRESULT CPicButton::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if (message == WM_LBUTTONDBLCLK) { message = WM_LBUTTONDOWN; } return CButton::DefWindowProc(message, wParam, lParam);//很重要,消除双击没反应 }
3.修改资源文件中button的属性
4.给控件添加变量,把CButton 改成自定义的CPicButton
5.在OnInitDialog函数中给button设置png
BOOL CtestMFCButtonDlg::OnInitDialog() { CDialogEx::OnInitDialog(); ''''''''''''''''''''''''''''''''''''''''''''''''' Gdiplus::Image* pImg = Gdiplus::Image::FromFile(_T("C:\Users\Administrator\Desktop\touming.png")); m_btn.SetButtonImage(pImg); return TRUE; }
二、给对话框指定区域设置背景色
在WM_ERASEBKGND消息函数里处理
BOOL CtestMFCButtonDlg::OnEraseBkgnd(CDC* pDC) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CBrush brush(RGB(196,196,198)); CBrush* pOldBrush = pDC->SelectObject(&brush); CRect rc; GetClientRect(&rc); pDC->PatBlt(0, 0, rc.Width() - 200, rc.Height(), PATCOPY); pDC->SelectObject(pOldBrush); return TRUE; }
三、对话框背景色不是纯白色的时候,设置对话框上控件背景色透明
在WM_CTLCOLOR消息函数里处理中
HBRUSH CtestMFCButtonDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: 在此更改 DC 的任何特性 // TODO: 如果默认的不是所需画笔,则返回另一个画笔 //静态文本 if (pWnd->GetDlgCtrlID() == IDC_STATIC) { pDC->SetBkMode(TRANSPARENT); return (HBRUSH)::GetStockObject(NULL_BRUSH); } //Radio按钮背景 TCHAR szClassName[MAX_PATH] = { 0 }; ::GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName) / sizeof(TCHAR) - 2); if (lstrcmpi(szClassName, _T("Button")) == 0) { UINT uStyle = ((CButton*)pWnd)->GetButtonStyle(); switch (uStyle) { case BS_AUTORADIOBUTTON: { static HBRUSH hbrSatic = ::CreateSolidBrush(RGB(196, 196, 198)); pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(0, 0, 0)); //字体颜色 return hbrSatic; } break; default: break; } } return hbr; }