gpt4 book ai didi

c++ - 在 C++ Win32 中创建透明窗口

转载 作者:IT老高 更新时间:2023-10-28 14:00:28 28 4
gpt4 key购买 nike

我正在创建一个非常简单的 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;
}

需要注意的一点是,应用程序始终停靠在屏幕左侧并且不会移动。但是,当用户打开、关闭或移动它下面的窗口时,应用程序下面的内容可能会发生变化。

当应用程序第一次启动时,它看起来很完美。 PNG 的透明(和半透明)部分完美地显示出来。但是,当应用程序下面的背景发生变化时,背景不会更新,它只是从应用程序首次启动时保持不变。事实上,WM_PAINT(或 WM_ERASEBKGND 在背景变化时不会被调用)。

我玩这个已经有一段时间了,已经接近 100% 正确,但还没有完全做到。例如,我尝试将背景设置为 (HBRUSH) NULL_BRUSH,并尝试处理 WM_ERASEBKGND。

当窗口下的内容发生变化时,如何让窗口重新绘制?

最佳答案

通过使用本系列第 1 部分和第 2 部分中的代码,我能够完全按照我的意愿行事:

Displaying a Splash Screen with C++


那些博客文章谈论的是在 Win32 C++ 中显示启动画面,但这与我需要做的几乎相同。我相信我缺少的部分是,我需要使用 UpdateLayeredWindow,而不是使用 GDI+ 将 PNG 绘制到窗口。使用正确的 BLENDFUNCTION 参数函数。我将在下面粘贴 SetSplashImage 方法,可以在上面链接的第 2 部分中找到:

void SetSplashImage(HWND hwndSplash, HBITMAP hbmpSplash)
{
// get the size of the bitmap
BITMAP bm;
GetObject(hbmpSplash, sizeof(bm), &bm);
SIZE sizeSplash = { bm.bmWidth, bm.bmHeight };

// get the primary monitor's info
POINT ptZero = { 0 };
HMONITOR hmonPrimary = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
MONITORINFO monitorinfo = { 0 };
monitorinfo.cbSize = sizeof(monitorinfo);
GetMonitorInfo(hmonPrimary, &monitorinfo);

// center the splash screen in the middle of the primary work area
const RECT & rcWork = monitorinfo.rcWork;
POINT ptOrigin;
ptOrigin.x = 0;
ptOrigin.y = rcWork.top + (rcWork.bottom - rcWork.top - sizeSplash.cy) / 2;

// create a memory DC holding the splash bitmap
HDC hdcScreen = GetDC(NULL);
HDC hdcMem = CreateCompatibleDC(hdcScreen);
HBITMAP hbmpOld = (HBITMAP) SelectObject(hdcMem, hbmpSplash);

// use the source image's alpha channel for blending
BLENDFUNCTION blend = { 0 };
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;

// paint the window (in the right location) with the alpha-blended bitmap
UpdateLayeredWindow(hwndSplash, hdcScreen, &ptOrigin, &sizeSplash,
hdcMem, &ptZero, RGB(0, 0, 0), &blend, ULW_ALPHA);

// delete temporary objects
SelectObject(hdcMem, hbmpOld);
DeleteDC(hdcMem);
ReleaseDC(NULL, hdcScreen);
}

关于c++ - 在 C++ Win32 中创建透明窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3970066/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com