如何强制 Aero 绘制无边框窗口,就好像它处于活动状态一样,即使它不是?
Posted
技术标签:
【中文标题】如何强制 Aero 绘制无边框窗口,就好像它处于活动状态一样,即使它不是?【英文标题】:How can I force Aero to draw a borderless window as if it were active, even if it's not? 【发布时间】:2011-12-29 08:13:15 【问题描述】:我想要和 windows 7 任务栏一样的效果。 我看过这个问题: Keep Window Looking Active 它工作得很好,但前提是窗口有非客户区。
我的窗口是无边框的,无论我做什么,它的内容(只是黑色背景)都会呈现为非活动状态。
我已将我的窗口标志设置为 Windows 7 任务栏,但它没有帮助。
我目前唯一的想法是用边框绘制它并剪掉它们,有没有更好的方法来实现我想要的?
编辑 1: 裁剪不起作用,裁剪边框后,窗口内容被呈现为非活动窗口。 那么 Windows 7 任务栏到底是如何工作的呢?
EDIT2: 添加一些照片更好地解释自己,以下窗口内容是黑色背景。
这是一个非活动窗口(内容呈现有点暗):
这是一个活动窗口:
如果窗口没有客户区,则内容始终呈现为非活动窗口,但是 Windows 任务栏始终呈现为活动窗口并且它没有任何 NC 区域(至少根据 spy++)。这就是我想要模仿的。
EDIT3: 分享我最近的发现。 explorer.exe 主窗口是无框架的,并具有以下标志:
我深入研究了资源管理器的进程 dwmapi.dll 导出函数:
它使用 DwmEnableBlurBehindWindow,就像我一样。 我检查了未记录的序数函数,它们都与将航空玻璃渲染为活动状态有关。
会不会是 DWM 规则不适用于资源管理器?
【问题讨论】:
您如何注意到无边框窗口处于非活动状态? 添加了一些照片以更清晰。 我在最后一段中写道“如果窗口没有客户区,则内容总是呈现为非活动窗口”,无边框窗口看起来就像非活动窗口,即使它是活动的。 @Omer,既然你想模仿任务栏,我想你的窗口有WS_EX_TOPMOST
和WS_EX_TOOLWINDOW
样式?当您依赖WM_NCACTIVATE
技巧时,您是否致电DwmExtendFrameIntoClientArea()
将玻璃扩展到您的客户区域?
@Omer:你说过你想做,但你没有说为什么。您似乎正在努力颠覆 Windows 的设计工作方式。是什么让您的应用(或至少该窗口)如此特别,以至于用户无法一眼看出它是否处于活动状态?
【参考方案1】:
棘手的一个.. 使用“DwmSetWindowAttribute”API 将 NCRenderingPolicy 设置为 Enabled。http://msdn.microsoft.com/en-us/library/windows/desktop/aa969524(v=vs.85).aspx
[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
[Flags]
public enum DwmWindowAttribute
NCRenderingEnabled = 1,
NCRenderingPolicy,
TransitionsForceDisabled,
AllowNCPaint,
CaptionButtonBounds,
NonClientRtlLayout,
ForceIconicRepresentation,
Flip3DPolicy,
ExtendedFrameBounds,
HasIconicBitmap,
DisallowPeek,
ExcludedFromPeek,
Last
[Flags]
public enum DwmNCRenderingPolicy
UseWindowStyle,
Disabled,
Enabled,
Last
public static bool SetNCRenderingActive(IntPtr Handle)
int renderPolicy = (int)DwmNCRenderingPolicy.Enabled;
return (DwmSetWindowAttribute(Handle, (int)DwmWindowAttribute.NCRenderingPolicy, ref renderPolicy, sizeof(int) ) == 0);
【讨论】:
以上是关于如何强制 Aero 绘制无边框窗口,就好像它处于活动状态一样,即使它不是?的主要内容,如果未能解决你的问题,请参考以下文章
运行 Aero 时如何确定实际窗口窗体大小(包含所有非客户端元素)?