Я использую библиотеку интеграции оболочки WPF (http://archive.msdn.microsoft.com/WPFShell), однако при использовании пользовательского Chrome с Aero строка заголовка удаляется.
Я понимаю, что мне нужно использовать функцию DrawThemeTextEx, чтобы перерисовать заголовок окна, однако я не могу найти примеры C #, которые делают это. Я нашел руководство по Пользовательской оконной рамке с использованием DWM (Windows) , в котором подробно описан рисунок заголовка заголовка.
Я не совсем уверен (у меня мало опыта работы с pinvoke), как это сделать в C #, чтобы использовать правильные системные шрифты и т. Д. Кто-то может предоставить пример C #, который я мог бы интегрировать в библиотеку интеграции оболочки WPF
Обновление № 1: Я пробовал этот код в проекте Windows Form, и он работает нормально. Я заметил, что форма 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);
}
}
}
}
Затем я вызываю DrawCustomTitle в следующей функции после расширения стекла DWM. Любая идея, почему это не будет работать.
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);
}
}