使用 AlphaBlend 绘制略微透明的矩形失败

Using AlphaBlend to draw slightly transparent rectangle fails

本文关键字:失败 透明 AlphaBlend 绘制 使用      更新时间:2023-10-16

我正在尝试在本机 Win32 C++中绘制一个略微透明的蓝色矩形。我正在使用函数 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;

这将起作用:

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)); 
}

CreateCompatibleDC 函数返回一个兼容的 dc,其大小为 1x1 的确定位图。为了首先绘制有用的东西,您应该选择大小合适的更合适的位图。您可以使用创建兼容位图功能。

基本上你应该做这样的事情:

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 非常古老且不那么友好,需要手动资源管理,使用起来非常痛苦。

祝你好运。