MFC中各種控件透明的實作方法總結
Button:
資料來源:
http://www.cnblogs.com/songsu/articles/1370665.html
關鍵是其中的OnEraseBkgnd。OnDrawItem隻是在原來BUTTON的位置上畫了一個橢圓顯示BUTTON的位置。
void CImageButton::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rc(lpDrawItemStruct->rcItem);
pDC->SelectStockObject(NULL_BRUSH);
pDC->Ellipse(rc);
}
BOOL CImageButton::OnEraseBkgnd(CDC* pDC)
{
CWnd *pParent = GetParent();
CRect rc;
GetWindowRect(rc);
pParent->ScreenToClient(rc);
pParent->InvalidateRect(rc,false);
pParent->UpdateWindow();
CDC *dcParent = pParent->GetDC();
pDC->BitBlt(0,0,rc.Width(),rc.Height(),dcParent,rc.left,rc.top,SRCCOPY);
pParent->ReleaseDC(dcParent);
return true;
}
如何在EDITBOX控件中使用背景位圖
方法一:
資料來源:
http://www.vckbase.com/document/viewdoc/?id=360
摘要:在VC中,标準的WINDOWS控件如TREEVIEW,EDITBOX,COMBOBOX和LISTBOX等控件都不支援選擇背景位圖的屬性,是以如果要使這些标準控件達到這種效果,必須有些非正常的方法。本文介紹一個CEDIT類如何實作背景位圖,并且可以更換背景的例子。可能實作的方法還有其它種,如果有興趣可以大家探讨。效果如圖:
關于網上這個方法:我按照文中的方法進行多次嘗試,始終不能達到理想的效果,下載下傳下來的代碼編譯後效果很理想,但我多次嘗試未果後,我将源碼中的MyEditCtrl類直接拿來用了,嘗試按照源碼中的模式進行編碼,但效果仍是不理想的。可能是我在某方面出了差錯。
效果如圖:
注意我故意将編輯框縮小,以便能顯示出後面的背景,可以看到背景是畫出來了,但是編輯框是黑色的。
方法二:
于是我嘗試查找其他的實作方法,在網上看到了這篇文章:
http://www.codeguru.com/cpp/controls/editctrl/transparent/article.php/c3921/
這篇文章雖然是想實作透明的,但我覺得他的透明效果實作的并不理想。但對于背景位圖的實作很有啟發。
下載下傳了源碼,發現他并沒有重載CEdit類,而是直接在Dialog中的重載函數OnCtlColor()中進行的修改,我模仿他的方法進行了嘗試,實作的效果比較理想,效果如圖:
從實作效果來講,還算理想,但這種方法有一個缺陷,那就是,背景圖隻能畫在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