Search code examples
cwindowsuser-interfacewinapiwindow

Making some parts of the window transparent in WinAPI


I want to make only certain(rectangular) parts of the window transparent. I have set the window as WS_EX_LAYERED and the WM_PAINT function is as follows:

    case WM_PAINT:;
        RECT rect;
        GetWindowRect(hwnd, &rect);
        HDC hdc = GetDC(hwnd);
        HDC hdc1 = CreateCompatibleDC(hdc);
        HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
        SelectObject(hdc, hBitmap);
        SIZE size = {rect.right - rect.left, rect.bottom - rect.top};
        BLENDFUNCTION blendFunc = {AC_SRC_OVER, 0, 0, AC_SRC_ALPHA};
        UpdateLayeredWindow(hwnd, hdc1, NULL, &size, hdc, NULL, RGB(0, 0, 0), &blendFunc, ULW_ALPHA);
        DeleteObject(hBitmap);
        DeleteDC(hdc);
        ReleaseDC(hwnd, hdc1);
        break;

I tried creating a child window, but that doesn't seem to work if I change it's opacity through SetLayeredWindowAttributes, possibly because it mimics the parent windows opacity. I am currently trying to use UpdateLayeredWindow to make certain parts transparent, but I can't even make the entire part transparent using UpdateLayeredWindow. What is the general way to make certain parts of the window transparent?


Solution

  • I suggest you could refer to the Doc:Using Layered Windows

    To have a dialog box come up as a translucent window, first create the dialog as usual. Then, on WM_INITDIALOG, set the layered bit of the window's extended style and call SetLayeredWindowAttributes with the desired alpha value.

    The third parameter of SetLayeredWindowAttributes is a value that ranges from 0 to 255, with 0 making the window completely transparent and 255 making it completely opaque.

    In order to use layered child windows, the application has to declare itself Windows 8-aware in the manifest. Refer to the thread: How to use WS_EX_LAYERED on child controls