Antiusninja
Antiusninja

Reputation: 167

Win32 LayeredWindow gives bad visual effect

I'm developing a UI system that has all those smart features like panel tearing off and docking, etc. Right now my task is to create an overlay on the screen that shows the position where the teared off or dockable panel would land. Pretty much same thing that visual studio has got. For that I'm using a custom layered window class that would show up when it is needed. After that I've started digging to achieve the needed effect. I was working with standart GDI functions before and basicly they are ok. But this time I followed the documentation advice to use UpdateLayeredWindow for my tasks and to load 32bit image from bitmap instead of drawing it with GDI functions. So here I have a 128x128pixel wide bmp with 222 in alpha channel and 255 0 0 in RGB

Here are methods which I use for initialization and drawing.

void Init(HDC in_hdc,HWND in_hwnd)
    {
        bf = { 0, 0, 200, AC_SRC_ALPHA };
        hwnd = in_hwnd;
        hdc_mem = CreateCompatibleDC(in_hdc);
        hBitmap_mem = CreateCompatibleBitmap(in_hdc, canvas_size.cx, canvas_size.cy);
        hBitmap_mem_default = (HBITMAP)SelectObject(hdc_mem, hBitmap_mem);
        hdc_bitmap = CreateCompatibleDC(in_hdc);
    }
    void DrawArea(RECT& in_rect)
    {
        hBitmap_area_default = (HBITMAP)SelectObject(hdc_bitmap, hBitmap_area);
        AlphaBlend(hdc_mem, in_rect.left, in_rect.top, in_rect.right, in_rect.bottom, hdc_bitmap, 0, 0, 2, 2, bf);
        hBitmap_area = (HBITMAP)SelectObject(hdc_bitmap, hBitmap_area_default);
    }
    void Update()
    {
        POINT p = { 0, 0 };
        HDC hdc_screen = GetDC(0);
        UpdateLayeredWindow(hwnd, hdc_screen, &p, &canvas_size, hdc_mem, &p, 0, &bf, ULW_ALPHA);
    }

The window style has this extras WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST

And here is what I get. So as you can see the blending that takes place DOES take into account per-pixel alpha, but it does a bad blending job. Any ideas how to tune it? enter image description here

Upvotes: 0

Views: 299

Answers (1)

arx
arx

Reputation: 16896

I suspect the problem is in the source bitmap. This is the kind of effect you get when the RGB values aren't premultiplied with the alpha. But ignore that because there is a far simpler way of doing this.

  • Create a layered window with a solid background colour by setting hbrBackground in the WNDCLASSEX structure.

  • Make the window partially transparent by calling SetLayeredWindowAttributes.

  • Position the window where you want it.

That's it.

This answer has code that illustrates the technique for a slightly different purpose.

Upvotes: 1

Related Questions