(i'm using win7)
i can use the Region functions for get the transparent control. but, in some cases, i can get bad resoltes(.
i have read that i can use brushes for get the transparent control. can anyone explain better?

What do you mean transparent controls? Are you trying to make a button 100% transparent? If that's the case, just hide the control.

Are you trying to round a button (transparent corners)?
Are you trying to make the button semi-transparent?

doing an irregular control without using Regions.
please correct me: hide a backcolor(or other color) is called transparent?
or i'm using the wrong terms\words or i don't know. please correct me

Irregular control without Regions? I've never seen such a thing.

However, if you are using Regions then the below code will work..

Specifically the CreateRegion function. That will create a region via a mask. If you provide an image with a certain colour that should be transparent, and you call CreateRegion with that colour, any part of the button with that colour will be transparent.

I've used this to create Windows with holes in the middle. Windows with multiple holes are random locations. Windows with rounded corners, etc..

Example of a black spot on my background being black:

http://i.imgur.com/D2piO8f.png
http://i.imgur.com/IGzivwk.png

And if you click anywhere that is transparent, whatever is below it will receive the click. Hopefully that helps. If it doesn't, let me know and I'll see if I can understand the problem better and help out.

#include <windows.h>
#include "Resource.h"

typedef struct
{
    HDC destDC;
    HDC memDC;
    HBITMAP hBitmap;
    HRGN hRgn;
    BITMAP bmp;
} REGION_INFO;

typedef struct
{
    HWND hwnd;
    unsigned ID;
    HBITMAP hBackgroundNormal;
    HBITMAP hBackgroundPressed;
} BUTTON_INFO;

void PaintRegion(REGION_INFO* info)
{
    if (info)
    {
        BitBlt(info->destDC, 0, 0, info->bmp.bmWidth, info->bmp.bmHeight, info->memDC, 0, 0, SRCCOPY);
    }
}

void DeleteRegion(HWND hwnd, REGION_INFO* info)
{
    if (info)
    {
        DeleteObject(info->hBitmap);
        DeleteObject(info->hRgn);
        DeleteDC(info->memDC);
        ReleaseDC(hwnd, info->destDC);
        memset(info, 0, sizeof(REGION_INFO));
    }
}

void CreateRegion(HWND hwnd, REGION_INFO* info, long backgroundID, COLORREF crTransparent)
{
    if (!info)
    {
        return;
    }

    info->destDC = GetDC(hwnd);
    info->memDC = CreateCompatibleDC(nullptr);
    info->hRgn = CreateRectRgn(0, 0, 0, 0);
    info->hBitmap = (HBITMAP)LoadImage(GetModuleHandle(nullptr), MAKEINTRESOURCE(backgroundID), IMAGE_BITMAP, 0, 0, LR_SHARED);

    GetObject(info->hBitmap, sizeof(info->bmp), &info->bmp);
    DeleteObject(SelectObject(info->memDC, info->hBitmap));

    int iX = 0;
    int iY = 0;
    int iRet = 0;

    for (int iY = 0; iY < info->bmp.bmHeight; ++iY)
    {
        do
        {
            while (iX < info->bmp.bmWidth && GetPixel(info->memDC, iX, iY) == crTransparent)
            {
                ++iX;
            }

            int iLeftX = iX;

            while (iX < info->bmp.bmWidth && GetPixel(info->memDC, iX, iY) != crTransparent)
            {
                ++iX;
            }

            HRGN hRgnTemp = CreateRectRgn(iLeftX, iY, iX, iY + 1);
            iRet = CombineRgn(info->hRgn, info->hRgn, hRgnTemp, RGN_OR);
            if(iRet == ERROR)
            {
                DeleteObject(hRgnTemp);
                DeleteRegion(hwnd, info);
                return;
            }
            DeleteObject(hRgnTemp);
        } while(iX < info->bmp.bmWidth);
        iX = 0;
    }

    iRet = SetWindowRgn(hwnd, info->hRgn, true);
    if(!iRet)
    {
        DeleteRegion(hwnd, info);
        return;
    }

    iX = (GetSystemMetrics(SM_CXSCREEN)) / 2 - (info->bmp.bmWidth / 2);
    iY = (GetSystemMetrics(SM_CYSCREEN)) / 2 - (info->bmp.bmHeight / 2);
    iRet = SetWindowPos(hwnd, HWND_TOPMOST, iX, iY, info->bmp.bmWidth, info->bmp.bmHeight, SWP_DRAWFRAME);

    PaintRegion(info);
    DeleteObject(info->hBitmap);
    info->hBitmap = nullptr;
    ValidateRect(hwnd, FALSE);
}

void SetWindowTransparency(HWND hwnd, BYTE Transperancy = 0)
{
    LONG wAttr = GetWindowLong(hwnd, GWL_EXSTYLE);
    SetWindowLong(hwnd, GWL_EXSTYLE, wAttr | WS_EX_LAYERED);
    SetLayeredWindowAttributes(hwnd, 0, Transperancy, 2);
}

void DrawButton(LPARAM lParam, unsigned ButtonID, HBITMAP BackgroundNormal, HBITMAP BackgroundPressed)
{
    LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
    HDC memDC = CreateCompatibleDC(lpdis->hDC);

    if (lpdis->CtlID == ButtonID)
    {
        if (lpdis->itemState & ODS_SELECTED)
        {
            SelectObject(memDC, BackgroundNormal);
        }
        else
        {
            SelectObject(memDC, BackgroundPressed);
        }
    }

    BitBlt(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, lpdis->rcItem.right - lpdis->rcItem.left, lpdis->rcItem.bottom - lpdis->rcItem.top, memDC, 0, 0, SRCCOPY);
    DeleteDC(memDC);
}

void RedrawControl(HWND hwnd)
{
    InvalidateRect(hwnd, nullptr, false);
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static REGION_INFO WindowRegion = {0};
    static BUTTON_INFO CloseButton = {0};
    static BUTTON_INFO OtherButton = {0};

    static REGION_INFO ButtonRegion = {0};

    switch(message)
    {
        case WM_PAINT:
        {
            PAINTSTRUCT PS = {0};
            BeginPaint(hwnd, &PS);
            PaintRegion(&WindowRegion);

            RedrawControl(OtherButton.hwnd);
            RedrawControl(CloseButton.hwnd);
            EndPaint(hwnd, &PS);
        }
        break;

        case WM_CREATE:
        {
            //WindowRegion = reinterpret_cast<REGION_INFO*>(reinterpret_cast<LPCREATESTRUCT>(lParam)->lpCreateParams);
            CreateRegion(hwnd, &WindowRegion, IDB_BACKGROUND, RGB(0, 0, 0));
            SetWindowTransparency(hwnd, 235);

            OtherButton.ID = IDI_BUTTON;
            OtherButton.hBackgroundNormal = (HBITMAP)LoadImage(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_BUTTON), IMAGE_BITMAP, 0, 0, LR_SHARED);
            OtherButton.hBackgroundPressed = (HBITMAP)LoadImage(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_BUTTON), IMAGE_BITMAP, 0, 0, LR_SHARED);
            OtherButton.hwnd = CreateWindowEx(WS_EX_TRANSPARENT, "Button", "Test", BS_OWNERDRAW | BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 26, 77, 75, 23, hwnd, (HMENU)IDI_BUTTON, NULL, 0);

            CloseButton.ID = IDI_CLOSE;
            CloseButton.hBackgroundNormal = (HBITMAP)LoadImage(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_CLOSE), IMAGE_BITMAP, 0, 0, LR_SHARED);
            CloseButton.hBackgroundPressed = (HBITMAP)LoadImage(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_CLOSE), IMAGE_BITMAP, 0, 0, LR_SHARED);
            CloseButton.hwnd = CreateWindowEx(WS_EX_TRANSPARENT, "Button", "", BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 267, 10, 13, 13, hwnd, (HMENU)IDI_CLOSE, NULL, 0);

            CreateRegion(OtherButton.hwnd, &ButtonRegion, IDI_BUTTON, RGB(0, 0, 0));
        }
        break;

        case WM_DRAWITEM:
        {
            DrawButton(lParam, CloseButton.ID, CloseButton.hBackgroundNormal, CloseButton.hBackgroundPressed);
            PaintRegion(&ButtonRegion);
            //DrawButton(lParam, OtherButton.ID, OtherButton.hBackgroundNormal, OtherButton.hBackgroundPressed);
        }
        break;

        /*case WM_CTLCOLORBTN:
        {
            HDC DC = (HDC)wParam;
            SetBkMode(DC, TRANSPARENT);
        }
        return NULL_BRUSH;*/

        case WM_DESTROY:
        {
            DeleteRegion(hwnd, &WindowRegion);
            PostQuitMessage(0);
        }
        break;

        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
    }

    return 0;
}

int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
    HWND hwnd;
    MSG messages;

    WNDCLASSEX wincl;
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = "Regions";
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof(WNDCLASSEX);
    wincl.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
    wincl.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wincl.lpszMenuName = nullptr;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    if(!RegisterClassEx(&wincl))
        return 0;

    hwnd = CreateWindowEx(WS_EX_TOOLWINDOW, wincl.lpszClassName, "Regions", WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, 291, 157, HWND_DESKTOP, nullptr, hThisInstance, nullptr);
    ShowWindow (hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&messages, nullptr, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}

Edited 1 Year Ago by triumphost

This article has been dead for over six months. Start a new discussion instead.