在无边框 WPF 窗口上启用 Vista 玻璃效果
我编写了一个附加属性,可以在窗口上设置该属性,以将玻璃框架延伸到客户区(使用 DwmExtendFrameIntoClientArea
API)。在大多数情况下它工作得很好。现在我希望我的窗口是无边框的,所以我在窗口上设置了以下属性:
WindowStyle="None"
ResizeMode="NoResize"
Background="Transparent"
u:WinUtil.EnableGlass="True"
ShowInTaskbar="False"
但是使用这些属性,玻璃根本不显示:我的窗口只有透明背景。如果我将 ResizeMode
设置为 CanResize
,则会显示玻璃,但我不希望窗口可调整大小。
我怀疑这是因为玻璃效果是通过将非客户端框架延伸到客户端区域来获得的:使用 WindowStyle = None
和 ResizeMode = NoResize
,有不是非客户端框架,因此无需扩展。当我启用调整大小时,它会在窗口周围创建一个框架,因此可以扩展该框架。
我想应该可以通过设置适当的 WS_* 位来创建一个具有细边框、没有标题栏且无法调整大小的窗口,但我不知道到底是哪些
我的问题是:
- 所以 应该设置或取消设置样式位以获得所需的外观和行为?
- 如何初始化窗口的样式位? Window 类似乎没有类似 Windows 窗体
CreateParams
属性的内容...在创建句柄后设置这些位可以吗? - 我发现
HwndSource
类可以作为问题 2 的答案,但如果您不是 Win32 专家,那么使用起来似乎有点复杂...这对我的问题来说是一个明智的解决方案吗?
欢迎任何建议
I wrote an attached property that I can set on a window to extend the glass frame into the client area (using the DwmExtendFrameIntoClientArea
API). It works fine in most cases. Now I want my window to be borderless, so I set the following attributes on my window :
WindowStyle="None"
ResizeMode="NoResize"
Background="Transparent"
u:WinUtil.EnableGlass="True"
ShowInTaskbar="False"
But with these attributes, the glass doesn't show up at all : my window just has a transparent background. If I set ResizeMode
to CanResize
, the glass is shown, but I don't want the window to be resizable.
I suspect it is due to the fact that the glass effect is obtained by extending the non-client frame into the client area : with WindowStyle = None
and ResizeMode = NoResize
, there is no non-client frame, so there's nothing to extend. When I enable resizing, it creates a frame around the window, so the frame can be extended.
I guess it should be possible to create a window that has a thin border, no title bar, and can't be resized, by setting the appropriate WS_* bits, but I don't know which ones exactly
So my questions are :
- Which style bits should be set or unset to have the desired appearance and behavior ?
- How can I initialize the window's style bits ? The Window class doesn't seem to have anything like Windows Forms
CreateParams
property... Is it OK to set these bits after the handle has been created ? - I found the
HwndSource
class that could be an answer to question 2, but it seems a bit complex to use if you're not a Win32 expert... Would it be a sensible solution to my problem ?
Any advice is welcome
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否尝试过使用DwmEnableBlurBehindWindow?这使您能够使窗口客户区的特定部分透明。
Have you tried using DwmEnableBlurBehindWindow? This enables you to make a specific part of a window's client area transparent.
我有一个窗口,我只想给它一个玻璃边框(没有标题栏且不可调整大小),但遇到了与您相同的问题。仅通过设置窗口的样式无法实现此目的。我的解决方案是设置 ResizeMode="CanResize" 和 WindowStyle="None",然后处理 WM_NCHITTEST 事件,将可调整大小的边框点击转换为不可调整大小的边框点击。还需要修改窗口的样式以禁用最大化和最小化(使用 Windows 快捷方式)和系统菜单:
这为您提供了 Windows 7 中适合通知区域弹出窗口(例如时钟或音量弹出窗口)的窗口。顺便说一句,您可以通过创建高度 44 的控件并设置其背景来重现弹出按钮底部的阴影:
I had a Window that I wanted to give just a glass boarder (no title bar and non-resizable) and ran into the same problem as you. You cannot accomplish this just by setting the Window's style. My solution was to set ResizeMode="CanResize" and WindowStyle="None" then handle the WM_NCHITTEST event to convert resizable border hits to non-resizable border hits. It was also necessary to modify the Window's style to disable maximizing and minimizing (using Windows shortcuts) and the system menu:
This gives you a Window in Windows 7 suitable for notification area flyouts (e.g. the clock or volume flyouts). BTW, you can reproduce the shading at the bottom of the flyout by creating a control of height 44 and setting it's background: