Создание прозрачного окна в C++ Win32

Я создаю то, что должно быть очень простым приложением Win32 c++, которое предназначено только для отображения полупрозрачного PNG. Окно не должно иметь хрома, и вся непрозрачность должна контролироваться в самом PNG.

моя проблема в том, что окно не перекрашивается при изменении содержимого под окном, поэтому прозрачные области PNG "застревают" с тем, что было под окном, когда приложение было первоначально запущено.

вот строка, где я установка нового окна:

hWnd = CreateWindowEx(WS_EX_TOPMOST, szWindowClass, szTitle, WS_POPUP, 0, height/2 - 20, 40, 102, NULL, NULL, hInstance, 0);

для вызова RegisterClassEx у меня есть этот набор для фона:

wcex.hbrBackground = (HBRUSH)0;

вот мой обработчик для сообщения WM_PAINT:

 case WM_PAINT:
 {
   hdc = BeginPaint(hWnd, &ps);
   Gdiplus::Graphics graphics(hdc);
   graphics.DrawImage(*m_pBitmap, 0, 0);
   EndPaint(hWnd, &ps);
   break;
 }

следует отметить, что приложение всегда закреплено слева от экрана и не перемещается. Но то, что находится под приложением, может измениться по мере того, как пользователь открывает, закрывает или перемещает окна под ним.

при первом запуске приложения, она выглядит идеально. Этот прозрачные (и simi-прозрачные) части PNG показывают отлично. Но когда фон под приложением изменяется, фон не обновляется, он просто остается неизменным с момента первого запуска приложения. Фактически, WM_PAINT (или WM_ERASEBKGND не вызывается при изменении фона).

я играл с этим довольно долго и приблизился к получению 100% права, но не совсем там. Например, я попытался установить фон на (HBRUSH) NULL_BRUSH и я пробовали обрабатывать WM_ERASEBKGND.

что можно сделать, чтобы перекрасить окно при изменении содержимого под ним?

2 ответов


я смог сделать именно то, что хотел, используя код из части 1 и части 2 этой серии: http://code.logos.com/blog/2008/09/displaying_a_splash_screen_with_c_introduction.html

эти сообщения в блоге говорят о отображении заставки в Win32 C++, но это было почти идентично тому, что мне нужно было сделать. Я считаю, что часть, которую я пропустил, заключалась в том, что вместо того, чтобы просто рисовать PNG в окне с помощью GDI+, мне нужно было использовать UpdateLayeredWindow


используйте SetLayeredWindowAttributes, это позволяет установить цвет маски, который станет прозрачным, таким образом, позволяя фон через.

http://msdn.microsoft.com/en-us/library/ms633540 (VS.85).aspx

вам также нужно будет настроить окно с многоуровневым флагом, например

SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);

после этого это довольно просто:

// Make red pixels transparent:
SetLayeredWindowAttributes(hwnd, RGB(255,0,0), 0, LWA_COLORKEY);

когда ваш PNG содержит полупрозрачные пиксели, которые вы хотите смешать с на заднем плане все усложняется. Вы можете попробовать взглянуть на подход в этой статье CodeProject:

прохладный, полупрозрачный и формы диалоги со стандартными элементами управления для Windows 2000 и выше