MFC-自绘贴图按钮
2016-03-15 11:21
309 查看
前言
控件窗口自绘贴图需要子类化, 有自绘风格, 接管WM_PAINT, 覆盖虚函数DrawItem.
效果
工程下载
srcSelfDrawBtn.zip
工程预览
调用方代码
自绘按钮类
控件窗口自绘贴图需要子类化, 有自绘风格, 接管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); }
相关文章推荐
- js中SetInterval与setTimeout用法
- 12C-OCP升级1z-060-007
- [悬线法] BZOJ1057 [ZJOI2007]棋盘制作
- 杭电 HDU ACM 1698 Just a Hook(线段树 区间更新 延迟标记)
- 如何改变Erlang的当前工作路径
- Spiral Matrix II
- 一张很使用的屏幕密度对应尺寸图
- 使用android studio 小技巧文集
- 类型类 V.S. 桥接模式:撞衫不可怕,谁丑谁尴尬
- Android性能优化之常见的内存泄漏
- bootstrap的tree控件
- 192 - Word Frequency
- 剑指offer-两个链表的第一个公共节点
- LUA string库详解
- 网站的最大并发连接数
- 时间格式转换
- 对不可用for update 的数据库管理工具如何复制记录
- 计算两个日期相隔的天数(jodd)
- 通过Object类说明方法重载、方法重写、多态之间的关系
- 开发错误手册