AlphaBlend失败,错误码87

2020-03-19 10:33:41 浏览数 (1)

如题,写测试程序的时候遇到了AlphaBlend函数失败,使用getlasterror获取错误码是87。找错找了好久,下面记录下。

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

源DC就是指该函数的第二个HDC,第一个是目标DC,这个在微软的BLENDFUNCTION结构体说明(见msdn)里有提到。排查起来也容易,利用

代码语言:javascript复制
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等函数进行上屏,那么肯定要上屏完毕才释放出来使用权啦。)

示例:

代码语言:javascript复制
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,也就是全透明了,可能就显示(渲染)不出任何东西了。

0 人点赞