Using AlphaBlend to draw slightly transparent rectangle fails

微笑、不失礼 提交于 2019-12-23 12:18:41

问题


I am attempting to draw a slightly transparent blue rectangle in Native Win32 C++. I am using the function AlphaBlend() but its not drawing anything onto the window, nothing happens.

My Problem: When I run my function to draw a slightly transparent rectangle, it doesn't get shown on my window. I have a feeling I am doing this wrong, maybe I should be using a HBITMAP?

Can you tell me what I need to do to get my function to draw a slightly transparent rectangle on the window?

Also I'm aware of GDI+ but I want to avoid it for now because I am getting alot of compile/include errors when I use that library plus I want to go as low/native as possible without the help of libraries that do everything for me.

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;

回答1:


This will work:

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



回答2:


CreateCompatibleDC function returns a compatible dc with a defualt bitmap of a size 1x1. In order to draw something usefull first of all you should select a more suitable bitmap of a right size. You can use CreateCompatibleBitmap function.

Basically you should do something like this:

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;

But seriously you should reconsider GDI+, try to figure out why you have all those compiler errors and fix them. GDI is very old and not so friendly, with manual resource management and quite painful to use.

Good luck.



来源:https://stackoverflow.com/questions/10975180/using-alphablend-to-draw-slightly-transparent-rectangle-fails

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!