如何更改WPF HwndHost内窗口的背景?
我在WPF应用程序中创建了一个从HwndHost派生的控件。HwndHost派生控件位于UserControl内部如何更改WPF HwndHost内窗口的背景?,wpf,interop,hwndhost,Wpf,Interop,Hwndhost,我在WPF应用程序中创建了一个从HwndHost派生的控件。HwndHost派生控件位于UserControl内部 我希望能够设置在HwndHost内创建的窗口的背景色(默认为白色,我希望为黑色)。最简单的方法是什么?我在更改HwndHost的背景色时也遇到了同样的问题,我在StackOverflow上发现了这个问题: 我对其进行了修改,将背景颜色更改为黑色,其外观如下: public class CustomWindow : IDisposable { #region Constant
我希望能够设置在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;
}
}
公共类自定义窗口:IDisposable
{
#区域常数
private const int ERROR_CLASS_已存在=1410;
#端区
#区域字段
私人布卢姆;
私人IntPtr m_hwnd;
私人WndProc m_wnd_程序代表;
#端区
#区域构造函数和析构函数
///
///初始化类的新实例。
///
///类名。
///
///类名称为空
///或
///类名为空
///或
///无法注册窗口类
///
公共自定义窗口(字符串类\名称)
{
if(class_name==null)
{
抛出新异常(“class_name为null”);
}
if(class_name==String.Empty)
{
抛出新异常(“class_name为空”);
}
this.m_wnd_proc_delegate=CustomWndProc;
//创建WNDCLASS
var wind_class=新WNDCLASS();
wind_class.lpszClassName=类别名称;
风力等级lpfnWndProc=
Marshal.GetFunctionPointerForDelegate(此.m_wnd_proc_委托);
wind_class.hbrBackground=CreateSolidBrush(0);
var等级=寄存器等级(参考风等级);
var last_error=Marshal.GetLastWin32Error();
如果(类原子==0&&last错误!=错误类已存在)
{
抛出新异常(“无法注册窗口类”);
}
//创建窗口
this.m_hwnd=CreateWindowExW(
0,
类名,
字符串。空,
0,
0,
0,
0,
0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.0);
}
#端区
///
///创建实体笔刷。
///
///颜色。
///IntPtr。
[DllImport(“gdi32.dll”,EntryPoint=“CreateSolidBrush”,CharSet=CharSet.Unicode)]
内部静态外部IntPtr CreateSolidBrush(输入颜色);
///
///获取黑色窗口。
///
///黑色的窗户。
公共IntPtr黑窗
{
得到
{
返回此文件,m_hwnd;
}
}
#区域代表
私人代表IntPtr WndProc(IntPtr hWnd、uint msg、IntPtr wParam、IntPtr lParam);
#端区
#区域公共方法和运算符
///
///执行与释放、释放或重置非托管资源相关的应用程序定义的任务。
///
公共空间处置()
{
这个。处置(真实);
总干事(本);
}
#端区
#区域方法
[DllImport(“user32.dll”,SetLastError=true)]
私有静态外部IntPtr CreateWindowExW(
UInt32 dwExStyle,
[Marshallas(UnmanagedType.LPWStr)]字符串lpClassName,
[Marshallas(UnmanagedType.LPWStr)]字符串lpWindowName,
UInt32 dwStyle,
Int32 x,
Int32 y,
Int32 nWidth,
Int32 nHeight,
IntPtr hWndParent,
国际华努,
IntPtr hInstance,
IntPtr-lpParam);
私有静态IntPtr CustomWndProc(IntPtr hWnd、uint msg、IntPtr wParam、IntPtr lParam)
{
返回DefWindowProcW(hWnd、msg、wParam、lParam);
}
[DllImport(“user32.dll”,SetLastError=true)]
私有静态外部IntPtr deffwindowprocw(IntPtr hWnd、uint msg、IntPtr wParam、IntPtr lParam);
[DllImport(“user32.dll”,SetLastError=true)]
专用静态外部窗口(IntPtr hWnd);
[DllImport(“user32.dll”,SetLastError=true)]
专用静态外部UInt16寄存器类([In]参考WNDCLASS lpWndClass);
///
///释放非托管和(可选)托管资源。
///
///如果为true,则同时释放托管和非托管资源;如果为false,则仅释放非托管资源。
私有无效处置(bool处置)
{
如果(!this.m_disposed)
{
如果(处置)
{
//处置托管资源
}
//处置非托管资源
if(this.m_hwnd!=IntPtr.Zero)
{
销毁窗口(this.m_hwnd);
此值为m_hwnd=IntPtr.Zero;
}
此.m_=true;
}
}
#端区
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
私有结构WNDCLASS
{
公共只读uint样式;
公共IntPtr lpfnWndProc;
公共只读int cbClsExtra;
公共只读int cbWndExtra;
公共只读IntPtr hInstance;
公共只读IntPtr hIcon;
公共只读IntPtr hCursor;
公共IntPtr hbrBackground;
[Marshallas(UnmanagedType.LPWStr)]
公共只读字符串lpszMenuName;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串lpszClassName;
}
}
然后我使用了CustomWindow创建的窗口和HwndHost中的父窗口。我们最终不得不在BuildWindowCore中注册一个自定义WNDCLASS。然后,您可以使用GetStockObject的p/invoke来获得一个新的笔刷(例如StockObjects.BLACK_笔刷),并在自定义WNDCLASS上设置hbrBackground。您可以发布代码,说明您是如何完成这项工作的吗?