gpt4 book ai didi

c# - 使用自定义 chrome 和 DWM 时重新绘制窗口标题

转载 作者:行者123 更新时间:2023-11-30 18:41:10 25 4
gpt4 key购买 nike

我正在使用 WPF Shell 集成库 ( http://archive.msdn.microsoft.com/WPFShell ),但是当我将自定义 chrome 与 Aero 一起使用时,标题栏被删除。

我知道我需要使用 DrawThemeTextEx 函数来重新绘制窗口标题,但是我找不到执行此操作的任何 C# 示例。我在 Custom Window Frame using DWM (Windows) 找到了指南详细说明了这幅画的标题。

我不太确定(我对 pinvoke 的经验很少)如何在 C# 中执行此操作,以便使用正确的系统字体等。是否有人能够提供一个 C# 示例,我可以将其集成到 WPF Shell 集成库中?

更新#1:我已经在 Windows 窗体项目中尝试过这段代码,它工作正常。我注意到如果我将窗体移出屏幕,Windows 窗体将丢失标题文本。所以我相信这个问题可能与此有关。我已尝试在 OnRender 事件中绘制标题文本,但这并不能解决问题。

我已将以下代码添加到 WindowChromeWorker.cs:

    private void _DrawCustomTitle(IntPtr hwnd)
{
if (NativeMethods.DwmIsCompositionEnabled())
{

Standard.RECT rcClient = new Standard.RECT();
NativeMethods.GetClientRect(hwnd, ref rcClient);

Standard.RECT rcPaint = rcClient;
rcPaint.Top += 8;
rcPaint.Right -= 125;
rcPaint.Left += 8;
rcPaint.Bottom = 50;

IntPtr destdc = NativeMethods.GetDC(hwnd);
IntPtr Memdc = NativeMethods.CreateCompatibleDC(destdc); // Set up a memory DC where we'll draw the text.
IntPtr bitmap;
IntPtr bitmapOld = IntPtr.Zero;
IntPtr logFont;

uint uFormat = NativeMethods.DT_SINGLELINE | NativeMethods.DT_TOP | NativeMethods.DT_LEFT | NativeMethods.DT_WORD_ELLIPSIS;

BITMAPINFO dib = new BITMAPINFO();
dib.bmiHeader.biHeight = -(rcClient.Bottom - rcClient.Top); // negative because DrawThemeTextEx() uses a top-down DIB
dib.bmiHeader.biWidth = rcClient.Right - rcClient.Left;
dib.bmiHeader.biPlanes = 1;
dib.bmiHeader.biSize = Marshal.SizeOf(typeof(BITMAPINFOHEADER));
dib.bmiHeader.biBitCount = 32;
dib.bmiHeader.biCompression = NativeMethods.BI_RGB;

if (!(NativeMethods.SaveDC(Memdc) == 0))
{
bitmap = NativeMethods.CreateDIBSection(Memdc, ref dib, NativeMethods.DIB_RGB_COLORS, 0, IntPtr.Zero, 0); // Create a 32-bit bmp for use in offscreen drawing when glass is on
if (!(bitmap == IntPtr.Zero))
{
bitmapOld = NativeMethods.SelectObject(Memdc, bitmap);

System.Drawing.Font font = new System.Drawing.Font("Segoe UI", 9f);
IntPtr hFont = font.ToHfont();
logFont = NativeMethods.SelectObject(Memdc, hFont);
try
{

System.Windows.Forms.VisualStyles.VisualStyleRenderer renderer = new System.Windows.Forms.VisualStyles.VisualStyleRenderer(System.Windows.Forms.VisualStyles.VisualStyleElement.Window.Caption.Active);

NativeMethods.DTTOPTS dttOpts = new NativeMethods.DTTOPTS();
dttOpts.dwSize = (int)Marshal.SizeOf(typeof(NativeMethods.DTTOPTS));
dttOpts.dwFlags = NativeMethods.DTT_COMPOSITED | NativeMethods.DTT_GLOWSIZE;
dttOpts.iGlowSize = 15;

string title = "Windows Title";
NativeMethods.DrawThemeTextEx(renderer.Handle, Memdc, 0, 0, title, -1, uFormat, ref rcPaint, ref dttOpts);

NativeMethods.BitBlt(destdc, rcClient.Left, rcClient.Top, rcClient.Right - rcClient.Left, rcClient.Bottom - rcClient.Top, Memdc, 0, 0, NativeMethods.SRCCOPY);

}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}

// Clean Up
NativeMethods.SelectObject(Memdc, bitmapOld);
NativeMethods.SelectObject(Memdc, logFont);
NativeMethods.DeleteObject(bitmap);
NativeMethods.DeleteObject(hFont);

NativeMethods.ReleaseDC(Memdc, -1);
NativeMethods.DeleteDC(Memdc);
}

}
}

}

在扩展 DWM 玻璃后,我将在以下函数中调用 DrawCustomTitle。知道为什么这不起作用。

    private void _ExtendGlassFrame()
{
Assert.IsNotNull(_window);

// Expect that this might be called on OSes other than Vista.
if (!Utility.IsOSVistaOrNewer)
{
// Not an error. Just not on Vista so we're not going to get glass.
return;
}

if (IntPtr.Zero == _hwnd)
{
// Can't do anything with this call until the Window has been shown.
return;
}

// Ensure standard HWND background painting when DWM isn't enabled.
if (!NativeMethods.DwmIsCompositionEnabled())
{
_hwndSource.CompositionTarget.BackgroundColor = SystemColors.WindowColor;
}
else
{
// This makes the glass visible at a Win32 level so long as nothing else is covering it.
// The Window's Background needs to be changed independent of this.

// Apply the transparent background to the HWND
_hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent;

// Thickness is going to be DIPs, need to convert to system coordinates.
Point deviceTopLeft = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Left, _chromeInfo.GlassFrameThickness.Top));
Point deviceBottomRight = DpiHelper.LogicalPixelsToDevice(new Point(_chromeInfo.GlassFrameThickness.Right, _chromeInfo.GlassFrameThickness.Bottom));

var dwmMargin = new MARGINS
{
// err on the side of pushing in glass an extra pixel.
cxLeftWidth = (int)Math.Ceiling(deviceTopLeft.X),
cxRightWidth = (int)Math.Ceiling(deviceBottomRight.X),
cyTopHeight = (int)Math.Ceiling(deviceTopLeft.Y),
cyBottomHeight = (int)Math.Ceiling(deviceBottomRight.Y),
};

NativeMethods.DwmExtendFrameIntoClientArea(_hwnd, ref dwmMargin);

this._DrawCustomTitle(_hwnd);
}
}

最佳答案

您不必经历所有这些麻烦。在下面查看我的代码示例。带有 Text={TemplateBinding Title} 的标签可以满足您的需求。

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell"
Title="MainWindow" Height="350" Width="525">
<Window.Style>
<Style TargetType="Window">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome GlassFrameThickness="4,40,4,4" ResizeBorderThickness="5" CaptionHeight="30"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Grid x:Name="PART_ComponentRoot">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition/>
<RowDefinition Height="4"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>

<TextBlock Grid.Column="1" Text="{TemplateBinding Title}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>

<ContentPresenter Grid.Row="1" Grid.Column="1" Content="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>

<Grid Background="White">

</Grid>

关于c# - 使用自定义 chrome 和 DWM 时重新绘制窗口标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7199386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com