2012-06-11 41 views
4

我試圖在本地Win32 C++中繪製一個稍微透明的藍色矩形。我正在使用函數AlphaBlend(),但它沒有在窗口上繪製任何東西,沒有任何反應。使用AlphaBlend繪製稍微透明的矩形失敗

我的問題:當我運行我的函數繪製一個稍微透明的矩形時,它不會顯示在我的窗口上。我有一種感覺我做錯了,也許我應該使用HBITMAP?

你能告訴我需要做些什麼來讓我的函數在窗口上繪製一個稍微透明的矩形嗎?

另外我知道GDI +,但我現在要避免它,因爲當我使用該庫時,我收到了很多編譯/包含錯誤,並且我想盡可能低/本地,而沒有幫助圖書館,爲我做的一切。

bool paintRect(HDC hdc, RECT dim, COLORREF penCol, COLORREF brushCol, unsigned int opacity) 
{ 
    HDC tempHdc   = CreateCompatibleDC(hdc); 
    BLENDFUNCTION blend = {AC_SRC_OVER, 0, 127, AC_SRC_ALPHA}; 

    SetDCPenColor(tempHdc, RGB(255,255,0)); 
    SetDCBrushColor(tempHdc, RGB(255,255,0)); 
    Rectangle(tempHdc, dim.left, dim.top, dim.right, dim.bottom); 

    return bool(AlphaBlend(hdc, dim.left, dim.top, dim.right, dim.bottom, tempHdc, dim.left, dim.top, dim.right, dim.bottom, blend)); 
} 
// Usage 
case WM_PAINT: 
{ 
    HDC hdc; 
    PAINTSTRUCT ps; 
    hdc = BeginPaint(hwnd, &ps); 

    RECT a = {0,0,100,100}; 
    paintRect(hdc, a, RGB(255,255,0), RGB(255,255,0), 127); // 127 is 50% transparency right? 

    EndPaint(hwnd, &ps); 
} 
break; 

回答

5

這將工作:

bool paintRect(HDC hdc, RECT dim, COLORREF penCol, COLORREF brushCol, unsigned int opacity) 
{ 
     HDC tempHdc   = CreateCompatibleDC(hdc); 
     BLENDFUNCTION blend = {AC_SRC_OVER, 0, 127, 0}; 

     HBITMAP hbitmap;  // bitmap handle 
     BITMAPINFO bmi;  // bitmap header 
     // zero the memory for the bitmap info 
     ZeroMemory(&bmi, sizeof(BITMAPINFO)); 

     // setup bitmap info 
     // set the bitmap width and height to 60% of the width and height of each of the three horizontal areas. Later on, the blending will occur in the center of each of the three areas. 
     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
     bmi.bmiHeader.biWidth = dim.right-dim.left; 
     bmi.bmiHeader.biHeight = dim.bottom-dim.top; 
     bmi.bmiHeader.biPlanes = 1; 
     bmi.bmiHeader.biBitCount = 32;   // four 8-bit components 
     bmi.bmiHeader.biCompression = BI_RGB; 
     bmi.bmiHeader.biSizeImage = (dim.right-dim.left) * (dim.bottom-dim.top) * 4; 

     // create our DIB section and select the bitmap into the dc 
     hbitmap = CreateDIBSection(tempHdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0x0); 
     SelectObject(tempHdc, hbitmap); 

     SetDCPenColor(tempHdc, RGB(0,0,255)); 
     SetDCBrushColor(tempHdc, RGB(0,0,255)); 
     FillRect(tempHdc, &dim, CreateSolidBrush(RGB(0,0,255))); 

     return bool(AlphaBlend(hdc, dim.left, dim.top, dim.right, dim.bottom, tempHdc, dim.left, dim.top, dim.right, dim.bottom, blend)); 
} 
+1

請注意,我忽略保存並重新選擇舊的位圖(並非它不重要,但與問題無關),我有0而不是AC_SRC_ALPHA,強制創建32位位圖,因爲AlphaBlend期望,使用藍色而不是黃色,並填充矩形。 – Tony

+0

你能解釋一下AC_SRC_ALPHA,並且更詳細地設置0嗎? –

+0

我認爲'//將位圖寬度和高度設置爲三個水平區域中的每一個的寬度和高度的60%。稍後,混合將發生在三個區域中的每一個的中心.'是複製粘貼錯誤。 – sergiol

2

CreateCompatibleDC函數返回一個尺寸爲1x1的defualt位圖兼容直流。爲了繪製一些有用的東西,首先你應該選擇一個合適的大小合適的位圖。您可以使用CreateCompatibleBitmap函數。

基本上你應該做這樣的事情:

HDC tempHdc   = CreateCompatibleDC(hdc); 
// create a bitmap of a size you need, let's say it 100x100 
int width = 100; 
int height = 100; 
HBITMAP canvas = CreateCompatibleBitmap(hdc, width, height); 
// select new bitmap into context, don't forget to save old bitmap handle 
HBITMAP oldBmp = SelectObject(tepmHdc, canvas); 

BLENDFUNCTION blend = {AC_SRC_OVER, 0, 127, AC_SRC_ALPHA}; 

SetDCPenColor(tempHdc, RGB(255,255,0)); 
SetDCBrushColor(tempHdc, RGB(255,255,0)); 
Rectangle(tempHdc, dim.left, dim.top, dim.right, dim.bottom); 

bool res = AlphaBlend(hdc, dim.left, dim.top, dim.right, dim.bottom, tempHdc, dim.left, dim.top, dim.right, dim.bottom, blend); 
// reset the old bitmap 
SelectObect(tempHdc, oldBmp); 
// canvas is no longer needed and should be deleted to avoid GDI leaks 
DeleteObject(canvas); 

return res; 

但嚴重的是,你應該重新考慮GDI +,揣摩爲什麼你所有的編譯器錯誤和解決這些問題。 GDI很老,不太友善,手動資源管理,使用起來非常痛苦。

祝你好運。

+0

打我的那一個。事實上,GDI +更像是一個GDI v2,具有很好的C++功能,可以更好地組織它。它對你的作用與GDI差不多。 – chris

+0

我修復了用於創建位圖的HDC參數。使用'tempHdc'可以在繪製時發生各種瘋狂的事情,這是因爲您首先解釋了爲什麼需要位圖。當我在我的繪畫中不斷看到怪異的橫艙口的東西時,這對我來說是一件非常頭疼的事情。你還需要一個來自'SelectObject'的強制轉換。 – chris