Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何更改WPF HwndHost内窗口的背景?_Wpf_Interop_Hwndhost - Fatal编程技术网

如何更改WPF HwndHost内窗口的背景?

如何更改WPF HwndHost内窗口的背景?,wpf,interop,hwndhost,Wpf,Interop,Hwndhost,我在WPF应用程序中创建了一个从HwndHost派生的控件。HwndHost派生控件位于UserControl内部 我希望能够设置在HwndHost内创建的窗口的背景色(默认为白色,我希望为黑色)。最简单的方法是什么?我在更改HwndHost的背景色时也遇到了同样的问题,我在StackOverflow上发现了这个问题: 我对其进行了修改,将背景颜色更改为黑色,其外观如下: public class CustomWindow : IDisposable { #region Constant

我在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;
  }
}
公共类自定义窗口: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。您可以发布代码,说明您是如何完成这项工作的吗?