使用 CreateWindowEx() 的 WPF 自定义 MainWindow
Posted
技术标签:
【中文标题】使用 CreateWindowEx() 的 WPF 自定义 MainWindow【英文标题】:WPF Custom MainWindow using CreateWindowEx() 【发布时间】:2021-04-28 06:44:29 【问题描述】:我正在使用 WPF 开发一个项目,我想修改 MainWindow
以获得一些扩展的窗口样式。我参考了一些文档,发现我可以使用SetWindowLong()
设置窗口样式,但在我的情况下它不起作用,因为我试图使用WS_EX_NOREDIRECTIONBITMAP
作为扩展窗口样式。当我使用SetWindowLong()
时,它什么也不做。我在某处读到 WS_EX_NOREDIRECTIONBITMAP
只能在创建窗口时设置。那么有什么方法可以修改 WPF MainWindow
的 CreateWindowEx()
。
我找到了另一种实现此目的的替代方法,但它是通过使用未记录的 API 函数。(SetWindowCompositionAttribute()
)。我需要我的项目稳定,那么还有其他方法可以实现吗?
如果SetWindowCompositionAttribute()
可以在运行时设置WS_EX_NOREDIRECTIONBITMAP
,则必须有解决方法来执行此操作。
这是我想要实现的截图:
在 C++ 中可以做到这一点,但在 C# WPF 中我还没有找到一种方法来做到这一点。
【问题讨论】:
您不能使用现有的“托管”桌面 15 年前的 UI 框架(例如 Winforms 或 WPF)并用它来做自己的低级工作。要么你使用它们是因为它们相对容易编程(并且在当今的 Windows 技术方面确实缺乏现代性,即:Direct Composition 或 Windows.UI.Composition、DirectX 等),要么去编写你自己的 Win32 桌面您可以访问所有内容的东西。理论上,WinUI3 (docs.microsoft.com/en-us/windows/apps/winui/winui3) 会填补这个空白,但目前还没有,细节还不确定。 您希望窗口在更改后具体做什么/看起来像什么? @o_w 您想要使用WS_EX_NOREDIRECTIONBITMAP
窗口样式的原因只有一个:它可以防止系统为您不需要它的情况分配重定向位图。 This Q&A 提供更多信息。
使用 WS_EX_NOREDIRECTIONBITMAP 将创建一个窗口而不会丢失它的阴影。由于 WPF 使用 DirectX 来呈现控件,因此不需要重定向表面。我试过了。 WPF 能够使用 WS_EX_NOREDIRECTIONBITMAP 绘制到一个窗口(我使用了未记录的 api)。如果我将所有边距设置为 11 以下,DWMExtendFrameIntoClient 区域将产生黑色边框,所以如果我使用 WS_EX_NOREDIRECTIONBITMAP,这个问题就解决了,这就是我需要它的原因
我不知道为什么每个人都反对投票,我已经尽可能多地解释了。我无法添加任何代码,因为我不知道我将在那里添加什么。我只想做一个带有 WS_EX_NOREDIRECTIONBITMAP 的空白 wpf 窗口。
【参考方案1】:
如果您想在创建MainWindow
的过程中设置WS_EX_NOREDIRECTIONBITMAP
,那么您可以手动创建MainWindow
。只需从 App.xaml 中删除 StartupUri
并为 Startup
事件创建新的事件处理程序。
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="App_Startup">
App.xaml.cs
void App_Startup(object sender, StartupEventArgs e)
// replace with your code
MainWindow window = new MainWindow();
window.Show();
但如果你能支持更多的代码会很有用。
【讨论】:
但是你能告诉我我将如何设置它以上是关于使用 CreateWindowEx() 的 WPF 自定义 MainWindow的主要内容,如果未能解决你的问题,请参考以下文章