mfc控件透明方法

时间:2022-06-23 10:09:12

MFC中各种控件透明的实现方法总结

Button:

资料来源:

http://www.cnblogs.com/songsu/articles/1370665.html

关键是其中的OnEraseBkgnd。OnDrawItem只是在原来BUTTON的位置上画了一个椭圆显示BUTTON的位置。

/*
mfc控件透明方法 *    画项
mfc控件透明方法 */
mfc控件透明方法void CImageButton::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) 
mfc控件透明方法mfc控件透明方法mfc控件透明方法{
mfc控件透明方法    CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
mfc控件透明方法    CRect rc(lpDrawItemStruct->rcItem);
mfc控件透明方法    pDC->SelectStockObject(NULL_BRUSH);
mfc控件透明方法    pDC->Ellipse(rc);
mfc控件透明方法}
mfc控件透明方法
mfc控件透明方法mfc控件透明方法/**//*
mfc控件透明方法 *    擦除背景
mfc控件透明方法 */
mfc控件透明方法BOOL CImageButton::OnEraseBkgnd(CDC* pDC) 
mfc控件透明方法mfc控件透明方法mfc控件透明方法{
mfc控件透明方法    CWnd *pParent = GetParent();   
mfc控件透明方法    CRect rc;
mfc控件透明方法
mfc控件透明方法    GetWindowRect(rc);
mfc控件透明方法    pParent->ScreenToClient(rc);
mfc控件透明方法    pParent->InvalidateRect(rc,false);
mfc控件透明方法    pParent->UpdateWindow();
mfc控件透明方法    CDC *dcParent = pParent->GetDC();   
mfc控件透明方法    pDC->BitBlt(0,0,rc.Width(),rc.Height(),dcParent,rc.left,rc.top,SRCCOPY);
mfc控件透明方法    pParent->ReleaseDC(dcParent);
mfc控件透明方法 return true;
mfc控件透明方法}

 

如何在EDITBOX控件中使用背景位图

方法一:

资料来源:

http://www.vckbase.com/document/viewdoc/?id=360

摘要:在VC中,标准的WINDOWS控件如TREEVIEW,EDITBOX,COMBOBOX和LISTBOX等控件都不支持选择背景位图的属性,所以如果要使这些标准控件达到这种效果,必须有些非常规的方法。本文介绍一个CEDIT类如何实现背景位图,并且可以更换背景的例子。可能实现的方法还有其它种,如果有兴趣可以大家探讨。效果如图:

mfc控件透明方法

关于网上这个方法:我按照文中的方法进行多次尝试,始终不能达到理想的效果,下载下来的代码编译后效果很理想,但我多次尝试未果后,我将源码中的MyEditCtrl类直接拿来用了,尝试按照源码中的模式进行编码,但效果仍是不理想的。可能是我在某方面出了差错。

效果如图:

mfc控件透明方法

注意我故意将编辑框缩小,以便能显示出后面的背景,可以看到背景是画出来了,但是编辑框是黑色的。

方法二:

于是我尝试查找其他的实现方法,在网上看到了这篇文章:

http://www.codeguru.com/cpp/controls/editctrl/transparent/article.php/c3921/

这篇文章虽然是想实现透明的,但我觉得他的透明效果实现的并不理想。但对于背景位图的实现很有启发。

下载了源码,发现他并没有重载CEdit类,而是直接在Dialog中的重载函数OnCtlColor()中进行的修改,我模仿他的方法进行了尝试,实现的效果比较理想,效果如图:

mfc控件透明方法

从实现效果来讲,还算理想,但这种方法有一个缺陷,那就是,背景图只能画在Edit控件的内部,而我想要实现的效果是将“电话图标”作为编辑框的图标来显示,而在输入的时候直接在“电话图标”的后面的编辑框中进行,这就要求将背景位图“前移”一段距离,画到编辑框的外面,可这种方法是无法实现的,一种伪实现是,将这张背景图片切割成两部分,“电话图标”部分在Dialog中来画,后半部分作为编辑框的背景来画。虽然效果是一样的,但这不是我想要的理想结果。看来要实现这种效果,只能通过重载CEdit类来实现了,所以方法一我究竟错在哪里,害要继续研究。

方法二的关键代码:

if (pWnd->GetDlgCtrlID() == IDC_EDIT_IMAGE)
{

    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(RGB(0,0,255));
    pDC->SelectObject(&m_brush2);
    return m_brush2;

}

几点注意的地方:

1. m_brush2是成员变量,也就是要保证它的生命周期不能只在重载函数OnCtlColor()中。

2.m_brush2.CreateXXX()函数是创建画刷的函数,根据需要选择具体的创建函数,注意不要把该函数放在会被多次调用的函数(比如重载函数OnCtlColor())中,以免多次创建错误,除非你在第二次创建之前调用了m_brush.DeleteObject()函数。

3.直接拷贝上面的代码是效果是出不来的,你还需要一个CBitmap位图对象,并初始化它和m_brush2对象。

 

Transparent Edit Box

为了搞定这个效果,花费了我不少时间。

透明的伪实现:

Edit Box的颜色分为3部分,文字颜色,文字背景色,编辑框背景色。所以如果“文字背景色,编辑框背景色”能和对话框背景色一直的话,就能实现透明。

方法一:

直接在Dialog中的重载函数OnCtlColor里实现:

if (pWnd->GetDlgCtrlID() == IDC_TRANS_EDIT)
{
    pDC->SetBkColor(RGB(236,233,216));

    return m_brush;

}

注意m_brush是成员变量,是为RGB(236,233,216)的纯色画刷。该颜色就是对话框的背景色。

方法二:

通过继承CEdit类来实现. 网上找到的,一种伪实现的方法:

http://www.codeproject.com/KB/edit/ctrltrans.aspx

透明的True Implementaion 分析:

 

方法一:一个不太完美的实现方法。

根据前面的分析return m_brush能够改变“编辑框背景色”,而SetBkColor能够改变“文字背景色”。

在这里,我可以得到一个Dialog的DC然后把Edit的区域的位图信息复制出来保存成一个CBitmap对象,在用这个bitmap对象创建一个画刷,把这个画刷返回,让对话框有这个画刷绘制控件。

从某种角度来说,透明Edit是实现了,但当把鼠标点击“文字背景色”时,能够看到一个黑色的区域。。。很不理想。

这种情况与上面位图背景中提到的方法一所遇到的问题有点类似,只是通常情况下看不到黑框了。

 

 

 

 

 

 

Owner Draw Progress Control

资料来源:

实例一:

http://www.codeguru.com/Cpp/controls/controls/progresscontrols/article.php/c2221

实例二:

http://www.codeproject.com/KB/miscctrl/cprogressctrlst.aspx