您的位置:首页 > 其它

MFC-自绘贴图按钮

2016-03-15 11:21 309 查看
前言

控件窗口自绘贴图需要子类化, 有自绘风格, 接管WM_PAINT, 覆盖虚函数DrawItem.

效果







工程下载

srcSelfDrawBtn.zip

工程预览

调用方代码

CMyButton   m_BtnPic;


自绘按钮类

#if !defined(AFX_MYBUTTON_H__C7179F52_CFB9_4588_9E1F_164276B42521__INCLUDED_)
#define AFX_MYBUTTON_H__C7179F52_CFB9_4588_9E1F_164276B42521__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MyButton.h : header file
//

class CMyButton : public CButton
{
public:
CMyButton();
virtual ~CMyButton();

public:
//{{AFX_VIRTUAL(CMyButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
//}}AFX_VIRTUAL

protected:
//{{AFX_MSG(CMyButton)
afx_msg void OnPaint();
afx_msg void OnClicked();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()

private:
void OwnerDraw(CDC& dc, UINT itemAction);
void GetBitmapInfo(CBitmap& cbm, OUT int& iWidth, OUT int& iHeight);

private:
UINT m_itemAction;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYBUTTON_H__C7179F52_CFB9_4588_9E1F_164276B42521__INCLUDED_)


/// @file MyButton.cpp : implementation file

#include "stdafx.h"
#include "resource.h"
#include "MyButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CMyButton::CMyButton()
{
m_itemAction = ODA_DRAWENTIRE;
}

CMyButton::~CMyButton()
{
}

BEGIN_MESSAGE_MAP(CMyButton, CButton)
//{{AFX_MSG_MAP(CMyButton)
ON_WM_PAINT()
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC dc;

if (NULL != lpDrawItemStruct) {
if (ODT_BUTTON == lpDrawItemStruct->CtlType) {
dc.SetOutputDC(lpDrawItemStruct->hDC);

if (this != GetFocus()) {
m_itemAction = ODA_DRAWENTIRE;
} else {
m_itemAction = lpDrawItemStruct->itemAction;
}

switch (m_itemAction) {
case ODA_SELECT: ///< d
TRACE(TEXT("IDB_BITMAP_D\n"));
break;

case ODA_FOCUS: ///< h
TRACE(TEXT("IDB_BITMAP_H\n"));
break;

case ODA_DRAWENTIRE: ///< n
default:
TRACE(TEXT("IDB_BITMAP_N\n"));
break;
}

OwnerDraw(dc, lpDrawItemStruct->itemAction);
}
}
}

void CMyButton::OnPaint()
{
CPaintDC dc(this); // device context for painting
OwnerDraw(dc, m_itemAction);
// Do not call CButton::OnPaint() for painting messages
}

void CMyButton::OnClicked()
{
TRACE(TEXT("CMyButton::OnClicked()\n"));
}

void CMyButton::GetBitmapInfo(CBitmap& cbm, OUT int& iWidth, OUT int& iHeight) {
BITMAP bm;
cbm.GetObject(sizeof(BITMAP), &bm);
iWidth = bm.bmWidth;
iHeight = bm.bmHeight;
}

void CMyButton::OwnerDraw(CDC& dc, UINT itemAction) {
RECT rt;
CDC memdc;
CBitmap bm;
int iWidth = 0;
int iHeight = 0;

GetClientRect(&rt);
memdc.CreateCompatibleDC(&dc);
switch (itemAction) {
case ODA_SELECT: ///< d
bm.LoadBitmap(IDB_BITMAP_D);
GetBitmapInfo(bm, iWidth, iHeight);
MoveWindow(rt.left, rt.top, iWidth, iHeight);
SetRect(&rt, rt.left, rt.top, rt.left + iWidth, rt.top + iHeight);
break;

case ODA_FOCUS: ///< h
bm.LoadBitmap(IDB_BITMAP_H);
GetBitmapInfo(bm, iWidth, iHeight);
MoveWindow(rt.left, rt.top, iWidth, iHeight);
SetRect(&rt, rt.left, rt.top, rt.left + iWidth, rt.top + iHeight);
break;

case ODA_DRAWENTIRE: ///< n
default:
bm.LoadBitmap(IDB_BITMAP_N);
GetBitmapInfo(bm, iWidth, iHeight);
MoveWindow(rt.left, rt.top, iWidth, iHeight);
SetRect(&rt, rt.left, rt.top, rt.left + iWidth, rt.top + iHeight);
break;
}

memdc.SelectObject(&bm);
dc.BitBlt(rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top,
&memdc, 0, 0, SRCCOPY);

/// @todo 画个3D边框, 而不是完全依赖与贴图
dc.MoveTo(rt.left, rt.top);
dc.LineTo(rt.right, rt.top);
dc.LineTo(rt.right, rt.bottom);
dc.LineTo(rt.left, rt.bottom);
dc.LineTo(rt.left, rt.top);
}

BOOL CMyButton::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class

return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: