T类,大概了解了ST类透明按钮的制作方法,对于MFC的函数调用机制仍然不是很了解,
本文待修改。
其实透明按钮并不是透明的,只是在第一次绘制按钮时将按钮矩形区域(CRect)的图片保存了起来,
并且在按钮重绘时再将保存的图片显示出来的过程,下面给出一个简单的处理方法:
(加粗部分为添加的代码)
(1)重载CButton类:
class CMyButton : public CButton
(2)为CMyButton类添加成员变量:
CDC m_dcBk;
CBitmap m_bmpBk;
CBitmap* m_pbmpOldBk;
int m_drawCount;
(3)在类向导中重载函数:
1、void CMyButton::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类
ModifyStyle(0, BS_OWNERDRAW);//设置按钮类得自绘风格
CButton::PreSubclassWindow();
}
2、void CmyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: 添加您的代码以绘制指定项
CDC *pDC = this ->GetDC();//获取DC指针
CClientDC clDC(GetParent());//获取父窗口客户DC
CRect rect;//用于保存本Button在父窗口中的区域
CRect rect1;//用于保存父窗口的区域
GetClientRect(rect);
GetWindowRect(rect1);
GetParent()->ScreenToClient(rect1);
if (m_dcBk.m_hDC == NULL && m_drawCount >= 1)//注意:m_drawCount是我自己添加的变量
//因为每次初始化时DrawItem函数都会绘制两次,这点现在我也不是很明白,所以让本段代码在第
//二次之后(包含)再进行绘制操作
{
m_dcBk.CreateCompatibleDC(&clDC);
m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());//注意:这里的
//函数调用保存了按钮矩形区的图像,用于重绘时调用
m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
} // if
else
{
m_drawCount++;
}
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);
}//至此,背景图像的保存和重绘已经完成了
下面变可以根据自己的喜好重载函数
void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)
来完成按钮的自绘了,此处不再赘述,下面贴出重绘后的按钮效果图:
无焦点:
鼠标按下:
MFC 关于透明按钮的自绘" type="#_x0000_t75" o:spid="_x0000_i1025">MFC 关于透明按钮的自绘" src="file:///C:\Users\Alision\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png">
注:按钮中的渐变效果是通过GDI+中的绘图函数实现的
浙公网安备 33010602011771号