窗口区域、移动子项、DWM 以及它可能造成的白色块状混乱

发布于 2024-11-19 21:37:33 字数 832 浏览 9 评论 0原文

设置:我有一个定义了区域的顶级窗口(使用 SetWindowRgn() 创建),并且我有一个移动的子元素(使用 SetWindowPos()),这样它的一些像素就会与父窗口区域的剪切部分重叠。

结果:这些像素被完全不透明、全白的像素填充,而不是保持完全透明(因为它位于其父级区域之外)。这并不是说子窗口在不应该被绘制的时候被绘制了,因为无论子窗口看起来是什么样子,有问题的像素都是白色的。

下面,橙色的小子窗口已沿着父窗口的边缘移动了一点。这只发生在具有透明窗口区域的边缘(因此白色像素始终被限制在父窗口的最大矩形内)。

在此处输入图像描述

如果父窗口隐藏然后显示,事情会自行纠正(只是无效并强制重绘并不清楚)白色像素)。

在 Vista 和 7 上都观察到了这种情况。如果我禁用桌面窗口管理器 (DWM),这种行为就会消失。在一种情况下,更新图形驱动程序后它也消失了。也许与此问题有关?:SetWindowRgn 的 Vista 实时缩略图问题。我原本打算将此作为一个罕见的错误归档,但它的出现足以值得进行更多的审查。

以前有其他人遇到过这个吗?关于 DWM 和窗口区域如何交互有什么见解吗?

另外,我知道我可以禁用每个应用程序的 DWM,但这会在应用程序运行时禁用所有内容,此外还会导致屏幕在启动和关闭时闪烁,这确实不是一个更好的问题。

The setup: I have a top-level window with a region defined (created with SetWindowRgn()), and I have a child element that is moved (with SetWindowPos()) such that some of its pixels then overlap the clipped portion of the parent's window region.

The result: Those pixels become filled with fully opaque, fully white pixels, instead of remaining fully transparent (since it's outside its parent's region). It isn't that the child window is being drawn when it shouldn't, as the offending pixels are white regardless of what the child window looks like.

Below, the small orange child window has been moved around a bit along the edge of the parent. This only happens along the edges that have a transparent window region (so the white pixels are always constrained within the maximum rectangle of the parent window).

enter image description here

Things correct themselves if the parent window is hidden and then shown (just invalidating and forcing a redraw does not clear the white pixels).

This has been observed on both Vista and 7. This behavior goes away if I disable the Desktop Window Manager (DWM). In one case, it also went away after updating graphics drivers. Perhaps it's related to this issue?: Vista live thumbnail issue with SetWindowRgn. I was originally going to just file this away as a rare bug, but it's cropped up enough to warrant a lot more scrutiny.

Has anyone else run up against this before? Any insights into how DWM and window regions interact?

Also, I'm aware I can disable DWM per-application, but that disables it for everything while the app is running, in addition to causing the screen to blip on startup and shutdown, and that's really not a much better problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷…雨湿花 2024-11-26 21:37:34

我不想再次回答我自己的问题,但我找到了解决方法。我发现再次设置窗口区域可以清除任何杂散的白色像素,而不会导致任何难看的重画或在其他地方闪烁。即使我设置的区域与现有区域相同,这也有效,所以像这样简单的事情就有效:

HRGN hRgn = CreateRectRgn(0,0,0,0);
GetWindowRgn( hWnd, hRgn );
SetWindowRgn( hWnd, hRgn, true );
DeleteObject( hRgn );

作为一个额外的好处(或者更确切地说作为这个问题的另一个奇怪的方面),如果我在移动窗口之前不久调用它,然后没有任何白色像素出现,但为了覆盖我的基础,我让它在任何窗口的平移动画之前和之后执行此步骤。

问题可能在于我在创建窗口后将其置于某种状态,通过重新设置区域可以清除该状态。很高兴知道根本原因,但由于这感觉就像我正在解决驱动程序错误,也许我永远不会知道根本原因是什么。

I hate to answer my own question again, but I've found a work-around. I found that setting the window's region again clears any of the stray white pixels without causing any ugly redrawing or flashing anywhere else. This works even if the region I am setting is the same as the existing region, so something as simple as this works:

HRGN hRgn = CreateRectRgn(0,0,0,0);
GetWindowRgn( hWnd, hRgn );
SetWindowRgn( hWnd, hRgn, true );
DeleteObject( hRgn );

As an added bonus (or rather as another bizarre aspect of this problem), if I call this shortly before moving the window, then none of the white pixels show up, but to just cover my bases I have it perform this step both before and after animating the translation of any windows.

It may be possible that the issue then lies with some state I'm putting the window into after its creation, which gets cleared by re-setting the region. It'd be nice to know the root cause, but as this feels like I'm working around a driver bug, perhaps I'll just never know what's the root cause.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文