我在 WPF 应用程序中创建了一个从 HwndHost 派生的控件。HwndHost 派生控件位于 UserControl 内。
我希望能够设置在 HwndHost 中创建的窗口的背景颜色(默认为白色,我希望它为黑色)。最简单的方法是什么?
我在更改 HwndHost 的背景颜色时也遇到了同样的问题,我在 StackOverflow 上找到了这个:
我已经修改了它,将背景颜色更改为黑色,它看起来像这样:
public class CustomWindow : IDisposable
{
#region Constants
private const int ERROR_CLASS_ALREADY_EXISTS = 1410;
#endregion
#region Fields
private bool m_disposed;
private IntPtr m_hwnd;
private WndProc m_wnd_proc_delegate;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="CustomWindow"/> class.
/// </summary>
/// <param name="class_name">The class_name.</param>
/// <exception cref="System.Exception">
/// class_name is null
/// or
/// class_name is empty
/// or
/// Could not register window class
/// </exception>
public CustomWindow(string class_name)
{
if (class_name == null)
{
throw new Exception("class_name is null");
}
if (class_name == String.Empty)
{
throw new Exception("class_name is empty");
}
this.m_wnd_proc_delegate = CustomWndProc;
// Create WNDCLASS
var wind_class = new WNDCLASS();
wind_class.lpszClassName = class_name;
wind_class.lpfnWndProc =
Marshal.GetFunctionPointerForDelegate(this.m_wnd_proc_delegate);
wind_class.hbrBackground = CreateSolidBrush(0);
var class_atom = RegisterClassW(ref wind_class);
var last_error = Marshal.GetLastWin32Error();
if (class_atom == 0 && last_error != ERROR_CLASS_ALREADY_EXISTS)
{
throw new Exception("Could not register window class");
}
// Create window
this.m_hwnd = CreateWindowExW(
0,
class_name,
String.Empty,
0,
0,
0,
0,
0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
}
#endregion
/// <summary>
/// Creates the solid brush.
/// </summary>
/// <param name="theColor">The color.</param>
/// <returns>IntPtr.</returns>
[DllImport("gdi32.dll", EntryPoint = "CreateSolidBrush", CharSet = CharSet.Unicode)]
internal static extern IntPtr CreateSolidBrush(uint theColor);
/// <summary>
/// Gets the black window.
/// </summary>
/// <value>The black window.</value>
public IntPtr BlackWindow
{
get
{
return this.m_hwnd;
}
}
#region Delegates
private delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
#endregion
#region Public Methods and Operators
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region Methods
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr CreateWindowExW(
UInt32 dwExStyle,
[MarshalAs(UnmanagedType.LPWStr)] string lpClassName,
[MarshalAs(UnmanagedType.LPWStr)] string lpWindowName,
UInt32 dwStyle,
Int32 x,
Int32 y,
Int32 nWidth,
Int32 nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);
private static IntPtr CustomWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr DefWindowProcW(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool DestroyWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
private static extern UInt16 RegisterClassW([In] ref WNDCLASS lpWndClass);
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
private void Dispose(bool disposing)
{
if (!this.m_disposed)
{
if (disposing)
{
// Dispose managed resources
}
// Dispose unmanaged resources
if (this.m_hwnd != IntPtr.Zero)
{
DestroyWindow(this.m_hwnd);
this.m_hwnd = IntPtr.Zero;
}
this.m_disposed = true;
}
}
#endregion
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct WNDCLASS
{
public readonly uint style;
public IntPtr lpfnWndProc;
public readonly int cbClsExtra;
public readonly int cbWndExtra;
public readonly IntPtr hInstance;
public readonly IntPtr hIcon;
public readonly IntPtr hCursor;
public IntPtr hbrBackground;
[MarshalAs(UnmanagedType.LPWStr)]
public readonly string lpszMenuName;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpszClassName;
}
}
然后我使用了 CustomWindow 创建的窗口和 HwndHost 中的父窗口。