轉帖|其它|編輯:郝浩|2010-11-19 11:41:00.000|閱讀 1016 次
概述:很多情況下,我們需要控件的背景是透明的,就是要求直接看到控件父窗口的背景顏色、背景位圖,比如標簽控件、單選Radio控件、復選Check控件,通常都要求在父窗口的背景上進行繪制。然而要求控件的畫布透明,這個技術在GDI的文檔中沒有看到Microsoft作任何說明,當然還是有別的辦法。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
很多情況下,我們需要控件的背景是透明的,就是要求直接看到控件父窗口的背景顏色、背景位圖,比如標簽控件、單選Radio控件、復選Check控件,通常都要求在父窗口的背景上進行繪制。然而要求控件的畫布透明,這個技術在GDI的文檔中沒有看到Microsoft作任何說明,當然還是有別的辦法。
其一: 如果程序支持桌面主題服務的話,則可調用主題服務的API來實現背景。我們先看看這個API:
HRESULT DrawThemeParentBackground(HWND hwnd , HDC hdc , RECT *prc );
這個函數就是專門用來繪制父窗口的背景的,其中的hwnd參數是子窗口的句柄,hdc也時子窗口的畫布句柄,prc是子窗口需繪制的區域,這個函數實際是把父窗口的背景拷貝到子窗口上來,以這種方法達到透明。
其二: 如果程序不支持桌面主題服務,則不能使用上面的方法,比如程序運行在Windows2000上。這時我們可以向父窗口發送WM_PAINT消息,不過此消息所附帶的wParam參數是一個畫布句柄:
HDC dc = GetDC(NULL);
HWND cWnd= ...;//子窗口句柄
HWND pWnd= ...;//父窗口句柄
RECTcRect;
GetClientRect(cWnd,&cRect);
HBITMAPbitmap = CreateCompatibleBitmap(dc, cRect.right,cRect.bottom);
ReleaseDC(dc);
HDCmemDC = CreateCompatibleDC(NULL);
HGDIOBJoldBitmap = SelectObject(memDC, bitmap);
//此處可以調用SetClipRect()等函數來限制繪制范圍
SendMessage(pWnd, WM_ERASEBKGND, (WPARAM)memDC,0);
SendMessage(pWnd, WM_PAINT, (WPARAM)memDC,0);
//至此memDC上已經保存了父窗口的背景內容
//用戶可以調用BitBlt(...)等函數拷貝memDC的內容到子窗口的某個區域,這樣就達到了透明效果;
SelectObject(memDC, oldBitmap);
DeleteDC(memDC);
DeleteObject(bitmap);
上面的辦法當然有限制,因為不是所有的父窗口都可以接受這種特殊的WM_PAINT消息功能,不過MSDN中提到大多數控件都有這個功能,大家要注意讀它的文檔內容。
其三: 如果上面的辦法都不行的話,就剩下最笨的辦法了,用GDI函數涂刷子窗口的背景,但你事先就要知道父窗口的背景顏色、背景位圖等信息。比如拿父窗口的顏色來填充子窗口的背景,可以調用FillRect()等:
//-------------------父窗口的背景是顏色的情況
COLORREFpColor = ...;//父窗口的顏色
HDC cDC =...;//子窗口的畫布句柄
RECTcRect = ...;//子窗口需刷新的區域
HBRUSHbrush = CreateSolidBrush(pColor);
FillRect(cDC, &cRect,brush);
DeleteObject(brush);
//-------------------父窗口的背景是位圖的情況
HBITMAPpBitmap = ...;父窗口的背景位圖
HDC cDC =...;//子窗口的畫布句柄
RECTcRect = ...;//子窗口需刷新的區域
POINTrp;
SetBurshOrgEx(cDC, x, y,&rp);如果是位圖刷子,則還需要調整畫布的刷子原點偏移確保無縫
HBRUSHbrush = CreatePatternBrush(pBitmap);
FillRect(cDC, &cRect,brush);
DeleteObject(brush);
SetBurshOrgEx(cDC, rp.x, rp.y,NULL);還原畫布的刷子偏移
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客轉載