heres the code that i use for put the form transparent:

LONG style= GetWindowLong(hwnd, GWL_EXSTYLE);
                style=style |  WS_EX_LAYERED;
                SetWindowLong(hwnd, GWL_EXSTYLE, style);
                SetLayeredWindowAttributes(hwnd, clrBackColor, NULL, LWA_COLORKEY);

but i see problems :(
the form and the controls are showed, but the mouse events are ignored.
if i click on button or form, the form on back(even if it's from another aplication) wins the focus.... why these effect happens?

Recommended Answers

All 18 Replies

WS_EX_TRANSPARENT - Specifies that a window created with this style is to be transparent. That is, any windows that are beneath the window are not obscured by the window. A window created with this style receives WM_PAINT messages only after all sibling windows beneath it have been updated.

MSDN

It means that if you use this flag, the windows below yours will get all the messages. In other words, if you click on your window, the click does not register. Instead, the window below/behind yours will get the click and your window will no longer be in focus.

To fix this, do:

CreateWindowEx(0, Title, WS_.... | WS_...., .....);

Notice that the first parameter is NOT WS_EX_TRANSPARENT.

Then use:

void SetTransparency(HWND hwnd, std::uint8_t Transperancy)
{
    long wAttr = GetWindowLong(hwnd, GWL_EXSTYLE);
    SetWindowLong(hwnd, GWL_EXSTYLE, wAttr | WS_EX_LAYERED);
    SetLayeredWindowAttributes(hwnd, 0, Transperancy, 0x02);
}

The usage can be as such:

SetTransparency(MyWindow, 0xFF); //255 = Full / 100% opacity.
SetTransparency(MyWindow, 0xFF / 2); //Half / 50% transparent.
SetTransparency(MyWindow, 0x00); //Full transparency/invisible.

The reason this works is because you are changing the Window's style to WS_EX_LAYERED. A layered window can be transparent or opaque and optionally have child windows. You do NOT need WS_EX_TRANSPARENT.

If you set the transparency to 0x00, your window will NOT receive clicks because it is NOT drawn on screen. This is equivalent to hiding it or minimising it.

thanks for all.
but i need ask: the form that i use these function have the border and the close button... so why they aren't working?

You need to implement it. Handle the WM_DESTROY message.

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:  //Not necessary. Nice to have though.
            DestroyWindow(hwnd); //Destroys the Window. Application does not have to quit.
            break;

        case WM_DESTROY: //Must have in order to close the window.
            PostQuitMessage(0); //Tells the application to quit.
            break;

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

    return 0;
}

sorry.. not that. think in these way: the form is above the word(for exemple) and the mouse is above the form title bar. why the cursor is changed to text cursor icon?(the form title bar is above the word text)
if i click on form border, the word wins focus....
i just want hide the backcolor(or other color) on form, nothing more

I have no clue what you mean in this case. I'd need a picture or code to know what you mean.

sorry.. the mouse isn't showed with PrintScreen.
the form is transparent, but, when i move the mouse above the 'X' button(for exemple).. the select effect don't happens and i can't click on it. if i click on that button, the form, on back, or even other application control, on back, recives the focus :(
is there another way for hide the backcolor?

I don't know what back colour you are trying to hide. My first solution works for fixing the focus. Other than that, I can't understand what it is you need fixing without seeing the code or a snippet of it or even a picture.

I can't figure out exactly what you are asking. :S

"My first solution works for fixing the focus. Other than that, I can't understand what it is you need fixing without seeing the code or a snippet of it or even a picture."
yes the child controls works normaly.
my form have the title bar: include the maxbox, minibox and closebox. if i click on them, the form loses the focus and the form\other aplication, that is on back, win the focus.
the form lose the backcolor(it's transparent) and loses more than that. the title bar is there, but it's same there isn't :(
sorry my english, but i'm trying :(
can i print the screen without lose the mouse icon?

No doing a print screen will remove the mouse icon. You could always draw on the picture though to show where the mouse was when you took the print screen. I do agree with triumphost that you really need to post a picture of what is happening.

sorry.. i'm not good on design, but it's for show you the problem.
https://onedrive.live.com/?cid=C3EF456E15C8DEB6&id=C3EF456E15C8DEB6!1255&v=3
like you see the mouse icon is changed to text icon(see above the close form button). on back of my aplication theres the codeblocks ide(where i do the code).
like you see the form close button don't change for selection way(when the mouse icon is anbove of it). these is the problem.
the child buttons works normaly

Try this.. It has the transparent client area as shown in your picture with a clickable close button and clickable child button. Uses the Layered window as described in my first post on this thread.

#include <windows.h>

LRESULT __stdcall WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
        case WM_CREATE:
        {
            CreateWindow("BUTTON", "Btn", WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD, 100, 100, 95, 25, Hwnd, (HMENU)1, NULL, NULL);
        }
        break;

        case WM_ERASEBKGND:
        {
            SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
            SetLayeredWindowAttributes(Hwnd, GetSysColor(COLOR_WINDOW), 0, LWA_COLORKEY);
        }
        return 1;


        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(Hwnd, Msg, wParam, lParam);
    }
    return 0;
}


int main()
{
    WNDCLASSEX FormClass;
    FormClass.cbSize        = sizeof(WNDCLASSEX);
    FormClass.style         = CS_DBLCLKS;
    FormClass.lpfnWndProc   = WindowProcedure;
    FormClass.cbClsExtra    = 0;
    FormClass.cbWndExtra    = 0;
    FormClass.hInstance     = GetModuleHandle(NULL);
    FormClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    FormClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    FormClass.hbrBackground = NULL;
    FormClass.lpszMenuName  = NULL;
    FormClass.lpszClassName = "Class";
    FormClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&FormClass);
    HWND hwnd = CreateWindowEx(WS_EX_LAYERED, "Class", "Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
    SetLayeredWindowAttributes(hwnd, 0, 0xFF, LWA_ALPHA);

    MSG Messages = {0};
    ShowWindow(hwnd, SW_SHOW);

    while(GetMessage(&Messages, NULL, 0, 0))
    {
        TranslateMessage(&Messages);
        DispatchMessage(&Messages);
    }
    return Messages.wParam;
}

now works.. but if i maximizate the form, i get the same problem. do i need repeat these when i change the form size?

Ahh I see.. Apparently the problem is with Aero and hbrBackground being NULL as well as using Magenta (0xFF, 0x00, 0xFF) as the transparent colour. Try the following..

#include <windows.h>

LRESULT __stdcall WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
        case WM_CREATE:
        {
            CreateWindow("BUTTON", "Btn", WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD, 100, 100, 95, 25, Hwnd, (HMENU)1, nullptr, nullptr);
        }
        break;

        /*case WM_ERASEBKGND:
        {
            SetLayeredWindowAttributes(Hwnd, RGB(0x80,0x00, 0xFF), 0, LWA_COLORKEY);
        }
        return 1;*/


        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(Hwnd, Msg, wParam, lParam);
    }
    return 0;
}


int main()
{
    WNDCLASSEX FormClass;
    FormClass.cbSize        = sizeof(WNDCLASSEX);
    FormClass.style         = CS_DBLCLKS;
    FormClass.lpfnWndProc   = WindowProcedure;
    FormClass.cbClsExtra    = 0;
    FormClass.cbWndExtra    = 0;
    FormClass.hInstance     = GetModuleHandle(NULL);
    FormClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    FormClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    FormClass.hbrBackground = CreateSolidBrush(RGB(0x80, 0x00, 0xFF));
    FormClass.lpszMenuName  = NULL;
    FormClass.lpszClassName = "Class";
    FormClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&FormClass);
    HWND hwnd = CreateWindowEx(WS_EX_LAYERED, "Class", "Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
    SetLayeredWindowAttributes(hwnd, RGB(0x80, 0x00, 0xFF), 0, LWA_COLORKEY);

    MSG Messages = {0};
    ShowWindow(hwnd, SW_SHOW);

    while(GetMessage(&Messages, NULL, 0, 0))
    {
        TranslateMessage(&Messages);
        DispatchMessage(&Messages);
    }
    return Messages.wParam;
}

now i'm confused :(

"Apparently the problem is with Aero and hbrBackground being NULL as well as using Magenta"
what you bean?
and yes i tryied change for:

RGB(255,255,255)

and i get the same problem :(
(your sample color works fine)

If the sample works fine, why not use it? I doubt you need the colour to be white if you plan on making it transparent. You can have any colour as long as R isn't 0xFF aka 255. I wasn't able to figure out why.. It just seems to be that way.

thanks for that info too ;)
i need ask anotherthing(sorry bored you): where the backcolor is hide, can i make a 'real' hole?(click on aplication that is on back?)
the backcolor is hide.. so why not click what is on form back?

let me ask(i can be confused): the transparent(if i use an image on form) and the shaping forms aren't more or less the same?
or the transparent is only for see(just see and not use) what is behind the form?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.