views:

1792

answers:

3

In c#, I have a handle to a window ( an IntPtr ), I want to change the background color of that window. How can I do this?

I can get the GDI graphics object for that handle like so:

Graphics graphics = Graphics.FromHwnd(theHandle);

So I should somehow be able to change the background color from this?

I also want to ensure the background color remains even after the window moves,resizes,repaints etc.

A: 

I think I'm close: My return values are all good, but the window's background color isn't changing. I'm accessing a window created by .NET, (Not C or C++) so the window may be repainting itself through .NET functionality after the native GDI call.

Here's what I have:


using System.Runtime.InteropServices;

public class NativeWIN32

{
    [DllImport("gdi32")]
    public static extern int SetBkColor(IntPtr hDC, int crColor); 

}


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        IntPtr hWnd = this.Handle;
        Graphics windowGraphics = Graphics.FromHwnd(hWnd);
        IntPtr hdc = windowGraphics.GetHdc();
        int ret = NativeWIN32.SetBkColor(hdc, 0); // Set to black
    }

}


Perhaps this will work for a Win32 window, otherwise I hope this helps someone else find the correct solution.

Perry Pederson
The window I am trying to change is a C\C++ window, and the background is not changing. Although you would think your code *should* work.
zadam
It looks like SetBkColor is not really intended for this usage. From the MSDN docs, it looks like it's used in conjunction with the drawing of shapes and text, not so much as an analogue of Control.BackColor.
Charlie
A: 

Create a control class with the Control.FromHandle method and then set the property.

Something like...

    Control someControl = Control.FromHandle(myHandle);
    someControl.BackColor = SystemColors.Black;
Keith Moore
This doesn't work - probably because the handle I have is not to a .Net created window (so someControl comes back null)
zadam
+1  A: 

I don't think there's a way to do this directly with a native (C/C++) window (i.e. there is no native GDI analogue to Control.BackColor).

From looking in Reflector it appears that Control uses the BackColor property to respond to the various WM_CTLCOLOR* messages (e.g. WM_CTLCOLOREDIT). So, if you want to change the background color of a native control, you may need to subclass that window and respond to that same message. If the native window is not a control, you'll still need to subclass the window, but you'd have to handle WM_PAINT or WM_ERASEBKGND instead.

Try this thread on programmersheaven.com for a suggestion on how to subclass a native window from C#.

Charlie