天天看點

AlphaBlend失敗,錯誤碼87

如題,寫測試程式的時候遇到了AlphaBlend函數失敗,使用getlasterror擷取錯誤碼是87。找錯找了好久,下面記錄下。

1.源DC的位圖不是32位的。

源DC就是指該函數的第二個HDC,第一個是目标DC,這個在微軟的BLENDFUNCTION結構體說明(見msdn)裡有提到。排查起來也容易,利用

BITMAP bmp;
GetObject(hBitmap, sizeof(BITMAP), (LPBYTE)&bmp);           

複制

下斷點調試下,看看bmp的資訊就知道了。

2.目标DC或者源DC的寬高有負值。msdn上面關于AlphaBlend函數的說明中有提到。

3.目标DC和源DC都是both the screen or the same memory bitmap(同一個螢幕或者同一個記憶體位圖),并且源DC和目标DC的區域還有重合(交叉)。msdn上面關于AlphaBlend函數的說明中有提到。

4.源DC的寬高超出了源DC裡位圖的寬高。msdn上面關于AlphaBlend函數的說明中有提到。

5.源DC的位圖(HBITMAP)正在被别的DC使用。這個特别标出來,比如建立相容DC,建立相容位圖,然後将相容位圖選入到DC中(SelectObject函數),然後在位圖上做各種操作(畫圖、寫字等),最後一定要把這個位圖的使用權給從dc裡釋放出來(SelectObject舊的到相容DC裡),這樣後續這個HBITMAP才能繼續被其他DC正确使用。(如果直接從這個相容DC來使用AlphaBlend等函數進行上屏,那麼肯定要上屏完畢才釋放出來使用權啦。)

示例:

HDC hDc = GetDC(NULL);
HDC hMemDC = ::CreateCompatibleDC(hDc);
HBITMAP hBitmap = ::CreateCompatibleBitmap(hDc,200,200);	
HGDIOBJ hOld = ::SelectObject(hMemDC,hBitmap);
RECT rcBMP = {0,0,200,200};

//這個上duilib裡面的繪制顔色的函數,帶有alpha通道。也可以用其他的繪圖函數加載圖檔等等。
CRenderEngine::DrawColor(hMemDC,rcBMP,0xFFFFFFFF);

SelectObject(hMemDC,hOld);//必須把舊的obj給選入到DC裡,以釋放我們需要的hBitmap的使用權給其他DC用
DeleteDC(hMemDC);
ReleaseDC(hDc);

//這裡這個hBitmap就可以給其他dc用了。           

複制

最後再提醒一點:如果上用AlphaBlend來進行渲染(上屏),你的位圖一定是32位的,一定要注意位圖的alpha通道。gdi的畫圖函數都是不包含alpha通道的,如果建立了空白的32位位圖,然後用gdi繪制,AlphaBlend會認為alpha通道值是0,也就是全透明了,可能就顯示(渲染)不出任何東西了。