I’m trying to make a custom control inherited from TextBox. I’m looking to do some custom drawing of the border of the control. I’ve run into a few issues in my test application:
1) The TextBox.HandleCreated event is never called when I debug the program. The textbox is visible on the form and I can interact with it, so I know the handle was created. I guess this is being called before I subscribe to the event?
2) WM_NCPAINT message is never received when I debug the program. I know this is called early on in the lifetime of the control. I assume I have the same problem here as I do with issue #1.
Is there any way to resolve these issues using Compact Framework 3.5? Am I doing this the preferred way?
Here is the relevant code:
public class ETextBox : TextBox
{
private IntPtr mOldWndProc;
private Win32Helper.WndProcDelegate mNewWndProc;
public ETextBox(Rectangle rc)
{
HandleCreated += new EventHandler(ETextBox_HandleCreated);
HandleDestroyed += new EventHandler(ETextBox_HandleDestroyed);
Bounds = rc;
}
public ETextBox(String s, Rectangle rc)
: this(rc)
{
Text = s;
}
private void SubclassWindow()
{
mOldWndProc = Win32Helper.GetWindowLong(Handle, Win32Helper.GWL_WNDPROC);
mNewWndProc = new Win32Helper.WndProcDelegate(WindowProc);
Win32Helper.SetWindowLong(Handle, Win32Helper.GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(mNewWndProc));
}
private void UnsubclassWindow()
{
if (mOldWndProc == IntPtr.Zero)
throw new InvalidOperationException();
Win32Helper.SetWindowLong(Handle, Win32Helper.GWL_WNDPROC, mOldWndProc);
}
private void ETextBox_HandleDestroyed(object sender, EventArgs e)
{
UnsubclassWindow();
}
private void ETextBox_HandleCreated(object sender, EventArgs e)
{
SubclassWindow();
}
private IntPtr WindowProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch (msg)
{
case Win32Helper.WM_ERASEBKGND:
return IntPtr.Zero;
case Win32Helper.WM_NCPAINT:
return IntPtr.Zero;
default:
return Win32Helper.CallWindowProc(mOldWndProc, hwnd, msg, wParam, lParam);
}
}
}
Is there a way to implement a flat TextBox in C#?
This answer contains code for doing this (it will work on CF). This isn’t technically sub-classing, but it’s a much easier way to achieve this effect.