自绘制按钮(通过重载DrawItem函数实现)
来源:互联网 发布:vb中static 编辑:程序博客网 时间:2024/05/29 15:06
实现方法:先建一个自定义类继承CButtoon类,重载一些消息和函数。
1. 设置数据成员:
private:
BOOL m_bMouseMove;//鼠标是否在按钮上
public:
int m_nStyle;//有外部设置按钮为几态
Gdiplus::Image* m_pImage;//按钮图片
2. 设置成员函数
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CXXXButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);//重载自绘制
//}}AFX_VIRTUAL
protected:
//{{AFX_MSG(CXXXButton)
afx_msg void On
afx_msg LRESULT On
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
CSize GetImageBlockSize() const;//通过m_nStyle和图片的大小来得到每次需要得到的图片的长和宽
BOOL TrackMouseEventEx(HWND hWnd, DWORD flags = TME_LEAVE, DWORD hoverTime = HOVER_DEFAULT); // 追踪鼠标事件
3. 构造函数的实现
CXXXButton::CXXXButton()
{
m_bMouseMove = false;//默认设置鼠标不再按钮上
}
4. 消息的定义
BEGIN_MESSAGE_MAP(CXXXButton, CButton)
//{{AFX_MSG_MAP(CXXXButton)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, On
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
5. 个函数的实现
void CXXXButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
UINT uStyle = DFCS_BUTTONPUSH;
// This co
ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);
CRect imgRc;
CRect txtRc = lpDrawItemStruct->rcItem;
CRect dstRc = lpDrawItemStruct->rcItem;
COLORREF textColor = RGB(77,77,77);
CSize block = GetImageBlockSize();
if (lpDrawItemStruct->itemState & ODS_DISABLED) //按钮不可用状态
{
textColor = RGB(77,77,77);
imgRc = CRect(block.cx*(m_nStyle - 1), 0, block.cx*m_nStyle, block.cy);
}
else if (lpDrawItemStruct->itemState & ODS_SELECTED) //按钮按下状态
{
textColor = RGB(77,77,77); //设置文字颜色
imgRc = CRect(block.cx,0,2*block.cx,block.cy);//设置按钮的图片在Load的图片上面的位置
}
else
{
if(!m_bMouseMove) //鼠标不在按钮上面
{
textColor = RGB(77,77,77);
imgRc = CRect(0,0,block.cx,block.cy);
}
Else //鼠标在按钮上面
{
textColor = RGB(255,255,255);
imgRc = CRect(block.cx*2, 0, block.cx*3, block.cy);
}
}
//Draw the Background
CDC* dcMem = CDC::FromHandle(lpDrawItemStruct->hDC);
Graphics grap(dcMem->GetSafeHdc());
grap.DrawImage(m_pImage, Rect(dstRc.top,dstRc.left,dstRc.Width(),dstRc.Height()),
imgRc.left,imgRc.top,imgRc.Width(),imgRc.Height(),UnitPixel);
// Get the button's text.
CString strText;
GetWindowText(strText);
// Draw the button text using the text color red.
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);
COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, textColor);
::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(),
&lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
::SetTextColor(lpDrawItemStruct->hDC, crOldColor);
}
void CXXXButton::SizeToContent()
{
CRect rc;
GetWindowRect(&rc);
CSize block = GetImageBlockSize();
if(rc.Width() != block.cx || rc.Height() != block.cy)
{
SetWindowPos(NULL, -1, -1, block.cx, block.cy,
SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE);
}
}
CSize CXXXButton::GetImageBlockSize() const
{
CSize block;
block.cy = m_pImage->GetHeight();
block.cx = m_pImage->GetWidth()/m_nStyle;
return block;
}
void CXXXButton::On
{
// TODO: Add your message handler co
if(!m_bMouseMove)
{
TrackMouseEventEx(m_hWnd);
m_bMouseMove = TRUE;
Invalidate();
}
CButton::On
}
BOOL CXXXButton::TrackMouseEventEx(HWND hWnd, DWORD flags, DWORD hoverTime)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = hWnd;
tme.dwFlags = flags;
tme.dwHoverTime = hoverTime;
return _TrackMouseEvent(&tme);
}
LRESULT CXXXButton::On
{
m_bMouseMove = FALSE;
Invalidate();
return LRESULT(0);
}
6. 应用
通过MFC产生一个按钮,将按钮的属性改为Owner draw,在ClassWizard中为按钮关联一个CButton对象,如m_btnMyButton;在头文件里面将按钮的类型CButton改为我们自绘制按钮类,CXXXButton。再在实现文件的构造函数里面定义自绘制按钮的参数,设置如下:
m_btnMyButton.m_nStyle = 3;
m_btnClearList.m_pImage = LoadImage();//自定义按钮图片
基本完成了。
注意:按钮的图标必须为三态或者四态,如:
- 自绘制按钮(通过重载DrawItem函数实现)
- 自绘制按钮(通过重载DrawItem函数实现)
- CListCtrl, 重载DrawItem函数
- CListCtrl, 重载DrawItem函数
- CListCtrl, 重载DrawItem函数
- MFC自绘制按钮
- 重载CListCtrl::DrawItem
- VC:重载CListCtrl::DrawItem
- 重载 CListCtrl::DrawItem.
- 自绘制按钮初探一
- 利用按钮自绘制作图形按钮
- 利用按钮自绘制作图形按钮
- VC DrawItem函数
- c语言中通过函数指针实现函数重载
- c语言中通过函数指针实现函数重载
- c语言中通过函数指针实现函数重载
- 虚函数 DrawItem()和 消息WM_DRAWITEM之间的区别
- php通过魔术方法__call实现类函数重载
- hibernate Java项目中自动创表、插入、表不存在等
- 在Eclipse 4.2.2 上离线安装Google Plugin
- JAVA学习的网址总结
- cocos2d中CCCallFuncND传参数的注意事项
- 深入探索 Kdump,第 4 部分: kdump 的亲密战友 crash
- 自绘制按钮(通过重载DrawItem函数实现)
- 【xinfanqie】教你如何让双硬盘自主选择关闭
- getOutputStream() has already been called for this response
- 13条创业公司不应忽视的用户体验设计准则
- IDEA 快捷键笔记
- liunx修改文件及目录的权限详细说明
- 'hibernate.dialect' must be set when no Connection available 异常处理
- swift流程
- WPF——图片的预览,以流的方式将图片保存在数据库中,再以流的方式从数据库中读取显示图片