使用 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 MainWindowCreateWindowEx()

我找到了另一种实现此目的的替代方法,但它是通过使用未记录的 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的主要内容,如果未能解决你的问题,请参考以下文章

这个 CreateWindowEx 函数有啥问题?

为啥 CreateWindowEx 返回 0

CreateWindowEx 怎么老是参数错误

CreateWindowEx 不支持新风格控件,如何解决

windows API 关于CreateWindowEX CreateThread和获取windows时间等问题

如何将 CreateWindowEx 限制为仅限字母数字输入?