开发者

Window regions, moving children, DWM, and the white blocky mess it can create

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).

Window regions, moving children, DWM, and the white blocky mess it can create

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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜