3

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

Alexey Ivanov
  • 11,541
  • 4
  • 39
  • 68
guy mininberg
  • 67
  • 2
  • 7
  • 2
    Note that if you call `InvalidateRect` with `NULL` as the rect, it invalidates the entire client rect – K-ballo Dec 26 '12 at 17:27
  • yes i know and i wanted all the client area to invalidate... isn't that the way to do it? – guy mininberg Dec 26 '12 at 17:29
  • 1
    This: `InvalidateRect(hWnd, NULL, TRUE)` is equivalent to this: `RECT rcClient; GetClientRect(hWnd, &rcClient); InvalidateRect(hWnd,&rcClient,TRUE);`. None are wrong, both do the same... – K-ballo Dec 26 '12 at 17:32

3 Answers3

3

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.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
2

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.

Alexey Ivanov
  • 11,541
  • 4
  • 39
  • 68
  • I keep forgetting about layered windows. And I never realized they were introduced all the way back in Windows 2000. – Mark Ransom Dec 26 '12 at 18:24
  • when i use WS_EX_LAYERED window with crKey the boarders of the image and the transparent areas are not clear and we have some leftovers of the transparent color. – guy mininberg Dec 27 '12 at 07:09
  • @guymininberg Can you post a screen shot? When you use `crKey`, only the areas painted in this exact color will be rendered as transparent. If your icon has semitransparent areas, and you want to preserve them, then you have to use `UpdateLayeredWindow`. – Alexey Ivanov Dec 27 '12 at 08:06
0

If you're trying to create a non-rectangular window, this is not sufficient. Setting "no background" simply means the background will not be drawn, and you'll see whatever happens to be in memory at that location.

To create a non-rectangular window, have a look at the SetWindowRgn function.

Thomas
  • 174,939
  • 50
  • 355
  • 478