天天看點

mfc控件透明方法

MFC中各種控件透明的實作方法總結

Button:

資料來源:

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

關鍵是其中的OnEraseBkgnd。OnDrawItem隻是在原來BUTTON的位置上畫了一個橢圓顯示BUTTON的位置。

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控件透明方法

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

繼續閱讀