Notre Poubelle
2007-07-01 23:00:02 UTC
Hello,
I'm trying to figure out how to change the border colour of the TextBox
control. I can't find a property that does this. I've researched this but
couldn't find a complete sample of anyone achieving this.
For the Textbox control, the overriden OnPaint method is not called unless
the control takes full responsibility for drawing the Textbox control but
that's not something I want to do; I just want to change the border colour.
A suggestion I found was to override the WM_PAINT message in WndProc. I did
this, and could use the Graphics.FromHwnd method to get access to GDI. I
could then draw a rectangle, but it was only in the interior of the TextBox,
not the outside so it was clipping the user entered text.
I think I need to draw to the non-client area (is that right?) of the
TextBox control. I handled the WM_NCPAINT message in WndProc and then
borrowed & adapted a routine I found on the web that looks like this (after
the WndProc):
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x85) //WM_NCPAINT
{
PaintNonClientArea(m.HWnd, (IntPtr)m.WParam);
return;
}
base.WndProc(ref m);
}
private void PaintNonClientArea(IntPtr hWnd, IntPtr hRgn)
{
RECT windowRect = new RECT();
if (NativeMethods.GetWindowRect(hWnd, out windowRect) == false)
return;
Rectangle bounds = new Rectangle(0, 0,
windowRect.Right - windowRect.Left,
windowRect.Bottom - windowRect.Top);
if (bounds.Width == 0 || bounds.Height == 0)
return;
Region clipRegion = null;
if (hRgn != (IntPtr)1)
clipRegion = System.Drawing.Region.FromHrgn(hRgn);
IntPtr hDC = NativeMethods.GetDCEx(hWnd, hRgn,
(DeviceContextValues.Window | DeviceContextValues.IntersectRgn
| DeviceContextValues.Cache |
DeviceContextValues.ClipChildren));
if (hDC == IntPtr.Zero)
throw new
System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
using (Graphics g = Graphics.FromHdc(hDC))
{
using (Pen pen = new Pen(Brushes.Green))
{
Rectangle myRect2 = new Rectangle();
myRect2.X = 0;
myRect2.Y = 0;
myRect2.Width = bounds.Width - 1;
myRect2.Height = bounds.Height - 1;
g.DrawRectangle(pen, myRect2);
}
}
}
The problem is that the call to GetDCEx always returns 0, and the Win32
exception thrown says invalid 'The parameter is incorrect'. The second
argument hdC seems to be what's causing the problem. This usually evaluates
to 1 (from the WM_NCPAINT message) but when it gets passed into GetDCEx, I
get the failure. Any idea what I'm doing wrong?
Thanks,
Notre
I'm trying to figure out how to change the border colour of the TextBox
control. I can't find a property that does this. I've researched this but
couldn't find a complete sample of anyone achieving this.
For the Textbox control, the overriden OnPaint method is not called unless
the control takes full responsibility for drawing the Textbox control but
that's not something I want to do; I just want to change the border colour.
A suggestion I found was to override the WM_PAINT message in WndProc. I did
this, and could use the Graphics.FromHwnd method to get access to GDI. I
could then draw a rectangle, but it was only in the interior of the TextBox,
not the outside so it was clipping the user entered text.
I think I need to draw to the non-client area (is that right?) of the
TextBox control. I handled the WM_NCPAINT message in WndProc and then
borrowed & adapted a routine I found on the web that looks like this (after
the WndProc):
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x85) //WM_NCPAINT
{
PaintNonClientArea(m.HWnd, (IntPtr)m.WParam);
return;
}
base.WndProc(ref m);
}
private void PaintNonClientArea(IntPtr hWnd, IntPtr hRgn)
{
RECT windowRect = new RECT();
if (NativeMethods.GetWindowRect(hWnd, out windowRect) == false)
return;
Rectangle bounds = new Rectangle(0, 0,
windowRect.Right - windowRect.Left,
windowRect.Bottom - windowRect.Top);
if (bounds.Width == 0 || bounds.Height == 0)
return;
Region clipRegion = null;
if (hRgn != (IntPtr)1)
clipRegion = System.Drawing.Region.FromHrgn(hRgn);
IntPtr hDC = NativeMethods.GetDCEx(hWnd, hRgn,
(DeviceContextValues.Window | DeviceContextValues.IntersectRgn
| DeviceContextValues.Cache |
DeviceContextValues.ClipChildren));
if (hDC == IntPtr.Zero)
throw new
System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
using (Graphics g = Graphics.FromHdc(hDC))
{
using (Pen pen = new Pen(Brushes.Green))
{
Rectangle myRect2 = new Rectangle();
myRect2.X = 0;
myRect2.Y = 0;
myRect2.Width = bounds.Width - 1;
myRect2.Height = bounds.Height - 1;
g.DrawRectangle(pen, myRect2);
}
}
}
The problem is that the call to GetDCEx always returns 0, and the Win32
exception thrown says invalid 'The parameter is incorrect'. The second
argument hdC seems to be what's causing the problem. This usually evaluates
to 1 (from the WM_NCPAINT message) but when it gets passed into GetDCEx, I
get the failure. Any idea what I'm doing wrong?
Thanks,
Notre