Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

window with transparent client area

I register the window class like this:

WNDCLASSEX wctt;
wctt.cbSize        = sizeof(WNDCLASSEX);
wctt.style         = CS_DBLCLKS;
wctt.lpfnWndProc   = WndProcTooltip;
wctt.cbClsExtra    = 0;
wctt.cbWndExtra    = 0;
wctt.hInstance     = m_hAppInstance;
wctt.hIcon         = NULL;
wctt.hCursor       = LoadCursor(NULL, IDC_SIZE);
wctt.hbrBackground = NULL;
wctt.lpszMenuName  = NULL;
wctt.lpszClassName = _T("myWindow");
wctt.hIconSm       = NULL;
RegisterClassEx(&wctt)

As you can see I use wctt.hbrBackground = NULL; so it will have no background.

The window is created like this:

::CreateWindowEx(WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
_T("myWindow"),
NULL,
WS_VISIBLE | WS_POPUP,
50,
50,
150,
100,
NULL,
NULL,
m_hAppInstance,
NULL);

In the paint section I draw icon on the window:

PAINTSTRUCT     ps;
HDC             hdc;
BITMAP          bitmap;
ICONINFO        iconinfo;
hdc = ::BeginPaint(hWnd, &ps);
::SetBkMode(hdc,TRANSPARENT);
::GetIconInfo(localIcon, &iconinfo);
::GetObject(iconinfo.hbmColor, sizeof(bitmap), &bitmap);
::DeleteObject(iconinfo.hbmColor);
::DeleteObject(iconinfo.hbmMask);
::DrawIconEx(hdc, 0,0, localIcon, bitmap.bmWidth, bitmap.bmHeight, 0, NULL, DI_NORMAL);

The icon size is smaller than the window size and I get on the background the current view on the window below the popup.

But now when I move the window (or minimize the window below the popup) the background is not changing.

I was trying to make a timer that each time do the flowing:

RECT rcClient;
GetClientRect(hWnd, &rcClient);
InvalidateRect(hWnd,&rcClient,TRUE);

This makes the print function run again but the background of the icon is not changing.

Should I do anything in WM_ERASEBKGND?
Does Anyone have any idea how to make it work?

thanks, guy

like image 755
guy mininberg Avatar asked Jan 26 '26 09:01

guy mininberg


2 Answers

It's not enough to just let the background stay unpainted; you also need to get the window below yours to repaint itself when necessary.

If the windows are part of the same hierarchy, created by the same thread, it is sufficient to give your window the WS_EX_TRANSPARENT extended style. This causes the window underneath to paint itself first so the background is always up-to-date.

Otherwise you need to use SetWindowRgn so that your window actually doesn't exist outside of the borders you wish to paint.

like image 188
Mark Ransom Avatar answered Jan 28 '26 00:01

Mark Ransom


Look at Layered Window. This feature allows creating semi-transparent windows of different shapes.

Add WS_EX_LAYERED extended attribute in your window class.

You can control the transparency of your window with these two functions:

  1. SetLayeredWindowAttributes:

    1. bAlpha controls the opacity of the entire window, if you pass LWA_ALPHA in dwFlags.

      When bAlpha is 0, the window is completely transparent. When bAlpha is 255, the window is opaque.

    2. crKey sets the color that would transparent.

      All pixels painted by the window in this color will be transparent.

  2. UpdateLayeredWindow gives you precise control over window transparency, you can give different parts of window different levels of transparency.

like image 34
Alexey Ivanov Avatar answered Jan 27 '26 23:01

Alexey Ivanov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!