0

我在 WPF 应用程序中创建了一个从 HwndHost 派生的控件。HwndHost 派生控件位于 UserControl 内。

我希望能够设置在 HwndHost 中创建的窗口的背景颜色(默认为白色,我希望它为黑色)。最简单的方法是什么?

4

1 回答 1

1

我在更改 HwndHost 的背景颜色时也遇到了同样的问题,我在 StackOverflow 上找到了这个:

从 C# 注册一个自定义的 win32 窗口类

我已经修改了它,将背景颜色更改为黑色,它看起来像这样:

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 中的父窗口。

于 2015-06-12T15:42:04.420 回答