Error creating window handle in vb translated class

B

Berryl Hesh

I am trying to use a class that I translated from a vb class posted on
CodeProject, but am getting the error below. The intent of the class is to
modify some of the mouse over behavior of a Forms.NumericUpDown control. I'm
particularly suspicious of the method GetPrivateInfo which uses refelction
to get hold of the TextBox portion of of the control; and of the event
handlers which are written in vb as Shadows and which I changed to "new".

Those two sections are below, after the rror message, and the entire
translated class is below that. Can someone help me narrow down the problem?

Thanks, BH

<---------------error msg------------------------------------ -->
System.ComponentModel.Win32Exception: Error creating window handle.
at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at Smack.Win.Tests.Controls.NumericUpDownExTest.Create_CanCreateHandle() in
NumericUpDownExTest.cs: line 20


<---------------suspect code------------------------------------ -->

///<summary>Extracts a reference to the private underlying textbox
field</summary>
private static TextBox GetPrivateField(NumericUpDownEx ctrl) {
// find internal TextBox
var textFieldInfo = typeof(NumericUpDown).GetField("upDownEdit",
BindingFlags.FlattenHierarchy | BindingFlags.NonPublic |
BindingFlags.Instance);
// take some caution... they could change field name in the future!
if (textFieldInfo == null) return null;
return (TextBox)textFieldInfo.GetValue(ctrl);
}

// these events will be raised correctly, when mouse enters on the textbox
new EventHandler<EventArgs> MouseEnter;
new EventHandler<EventArgs> MouseLeave;


<---------------entire class------------------------------------ -->
[DesignerCategory("code")]
public class NumericUpDownEx : NumericUpDown
{
private readonly TextBox _underlyingTextBox;
public NumericUpDownEx() {
InterceptMouseWheel = InterceptMouseWheelMode.Always;
// extract a reference to the underlying TextBox field
_underlyingTextBox = GetPrivateField(this);
if (_underlyingTextBox==null) throw new AgumentNullException("...");
// add handlers (MouseEnter and MouseLeave events of NumericUpDown are not
working properly)
_underlyingTextBox.MouseEnter += _underlyingTextBox_MouseEnter;
_underlyingTextBox.MouseLeave += _underlyingTextBox_MouseLeave;
}
///<summary>Extracts a reference to the private underlying textbox
field</summary>
private static TextBox GetPrivateField(NumericUpDownEx ctrl) {
// find internal TextBox
var textFieldInfo = typeof(NumericUpDown).GetField("upDownEdit",
BindingFlags.FlattenHierarchy | BindingFlags.NonPublic |
BindingFlags.Instance);
// take some caution... they could change field name in the future!
if (textFieldInfo == null) return null;
return (TextBox)textFieldInfo.GetValue(ctrl);
}
#region New Properties
[DefaultValue(false), Category("Behavior"), Description("Automatically
select control text when it receives focus.")]
public bool AutoSelect { get; set; }

[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int SelectionStart {
get { return _underlyingTextBox.SelectionStart; }
set { _underlyingTextBox.SelectionStart = value; }
}

[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int SelectionLength {
get { return _underlyingTextBox.SelectionLength; }
set { _underlyingTextBox.SelectionLength = value; }
}
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string SelectedText {
get { return _underlyingTextBox.SelectedText; }
set { _underlyingTextBox.SelectedText = value; }
}
[DefaultValue(typeof(InterceptMouseWheelMode), "Always"),
Category("Behavior"), Description("Enables MouseWheel only under certain
conditions.")]
public InterceptMouseWheelMode InterceptMouseWheel { get; set; }
public enum InterceptMouseWheelMode
{
/// <summary>MouseWheel always works (default behavior)</summary>
Always,
/// <summary>MouseWheel works only when mouse is over the (focused)
control</summary>
WhenMouseOver,
/// <summary>MouseWheel never works</summary>
Never
}
#endregion
#region Text Selection
// MouseUp will kill the SelectAll made on GotFocus.
protected override void OnGotFocus(EventArgs e) {
if (AutoSelect)
_underlyingTextBox.SelectAll();
base.OnGotFocus(e);
}
protected override void OnMouseUp(MouseEventArgs mevent) {
if (AutoSelect && _underlyingTextBox.SelectionLength == 0)
_underlyingTextBox.SelectAll();
base.OnMouseUp(mevent);
}
#endregion
#region Additional Events
// these events will be raised correctly, when mouse enters on the textbox
new EventHandler<EventArgs> MouseEnter;
new EventHandler<EventArgs> MouseLeave;
// flag to track mouse position
private bool _mouseOver;
private void _underlyingTextBox_MouseEnter(object sender, EventArgs e) {
_mouseOver = true;
MouseEnter(this, EventArgs.Empty);
}
private void _underlyingTextBox_MouseLeave(object sender, EventArgs e) {
_mouseOver = false;
MouseLeave(this, EventArgs.Empty);
}
#endregion
///<summary>WndProc override to kill WN_MOUSEWHEEL message</summary>
protected override void WndProc(ref Message m) {
const int WM_MOUSEWHEEL = 0x020A;
if (m.Msg == WM_MOUSEWHEEL) {
switch (InterceptMouseWheel) {
case InterceptMouseWheelMode.Always:
// standard message
base.WndProc(ref m);
break;
case InterceptMouseWheelMode.WhenMouseOver:
if (_mouseOver)
base.WndProc(ref m);
break;
case InterceptMouseWheelMode.Never:
// kill the message
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
 
D

Dario

Hi Berryl,
to fix your error you only have to cast the upDownEdit as TextBoxBase
instead of TextBox.

These are the changes you have to do:
1) Declare the _underlyingTextBox as TextBoxBase
2) Modify the GetPrivateField to return a TextBoxBase
3) Cast the upDownEdit as TextBoxBase:
(TextBoxBase)textFieldInfo.GetValue(ctrl);



Berryl Hesh said:
I am trying to use a class that I translated from a vb class posted on
CodeProject, but am getting the error below. The intent of the class is to
modify some of the mouse over behavior of a Forms.NumericUpDown control. I'm
particularly suspicious of the method GetPrivateInfo which uses refelction
to get hold of the TextBox portion of of the control; and of the event
handlers which are written in vb as Shadows and which I changed to "new".

Those two sections are below, after the rror message, and the entire
translated class is below that. Can someone help me narrow down the problem?

Thanks, BH

<---------------error msg------------------------------------ -->
System.ComponentModel.Win32Exception: Error creating window handle.
at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at Smack.Win.Tests.Controls.NumericUpDownExTest.Create_CanCreateHandle() in
NumericUpDownExTest.cs: line 20


<---------------suspect code------------------------------------ -->

///<summary>Extracts a reference to the private underlying textbox
field</summary>
private static TextBox GetPrivateField(NumericUpDownEx ctrl) {
// find internal TextBox
var textFieldInfo = typeof(NumericUpDown).GetField("upDownEdit",
BindingFlags.FlattenHierarchy | BindingFlags.NonPublic |
BindingFlags.Instance);
// take some caution... they could change field name in the future!
if (textFieldInfo == null) return null;
return (TextBox)textFieldInfo.GetValue(ctrl);
}

// these events will be raised correctly, when mouse enters on the textbox
new EventHandler<EventArgs> MouseEnter;
new EventHandler<EventArgs> MouseLeave;


<---------------entire class------------------------------------ -->
[DesignerCategory("code")]
public class NumericUpDownEx : NumericUpDown
{
private readonly TextBox _underlyingTextBox;
public NumericUpDownEx() {
InterceptMouseWheel = InterceptMouseWheelMode.Always;
// extract a reference to the underlying TextBox field
_underlyingTextBox = GetPrivateField(this);
if (_underlyingTextBox==null) throw new AgumentNullException("...");
// add handlers (MouseEnter and MouseLeave events of NumericUpDown are not
working properly)
_underlyingTextBox.MouseEnter += _underlyingTextBox_MouseEnter;
_underlyingTextBox.MouseLeave += _underlyingTextBox_MouseLeave;
}
///<summary>Extracts a reference to the private underlying textbox
field</summary>
private static TextBox GetPrivateField(NumericUpDownEx ctrl) {
// find internal TextBox
var textFieldInfo = typeof(NumericUpDown).GetField("upDownEdit",
BindingFlags.FlattenHierarchy | BindingFlags.NonPublic |
BindingFlags.Instance);
// take some caution... they could change field name in the future!
if (textFieldInfo == null) return null;
return (TextBox)textFieldInfo.GetValue(ctrl);
}
#region New Properties
[DefaultValue(false), Category("Behavior"), Description("Automatically
select control text when it receives focus.")]
public bool AutoSelect { get; set; }

[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int SelectionStart {
get { return _underlyingTextBox.SelectionStart; }
set { _underlyingTextBox.SelectionStart = value; }
}

[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int SelectionLength {
get { return _underlyingTextBox.SelectionLength; }
set { _underlyingTextBox.SelectionLength = value; }
}
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string SelectedText {
get { return _underlyingTextBox.SelectedText; }
set { _underlyingTextBox.SelectedText = value; }
}
[DefaultValue(typeof(InterceptMouseWheelMode), "Always"),
Category("Behavior"), Description("Enables MouseWheel only under certain
conditions.")]
public InterceptMouseWheelMode InterceptMouseWheel { get; set; }
public enum InterceptMouseWheelMode
{
/// <summary>MouseWheel always works (default behavior)</summary>
Always,
/// <summary>MouseWheel works only when mouse is over the (focused)
control</summary>
WhenMouseOver,
/// <summary>MouseWheel never works</summary>
Never
}
#endregion
#region Text Selection
// MouseUp will kill the SelectAll made on GotFocus.
protected override void OnGotFocus(EventArgs e) {
if (AutoSelect)
_underlyingTextBox.SelectAll();
base.OnGotFocus(e);
}
protected override void OnMouseUp(MouseEventArgs mevent) {
if (AutoSelect && _underlyingTextBox.SelectionLength == 0)
_underlyingTextBox.SelectAll();
base.OnMouseUp(mevent);
}
#endregion
#region Additional Events
// these events will be raised correctly, when mouse enters on the textbox
new EventHandler<EventArgs> MouseEnter;
new EventHandler<EventArgs> MouseLeave;
// flag to track mouse position
private bool _mouseOver;
private void _underlyingTextBox_MouseEnter(object sender, EventArgs e) {
_mouseOver = true;
MouseEnter(this, EventArgs.Empty);
}
private void _underlyingTextBox_MouseLeave(object sender, EventArgs e) {
_mouseOver = false;
MouseLeave(this, EventArgs.Empty);
}
#endregion
///<summary>WndProc override to kill WN_MOUSEWHEEL message</summary>
protected override void WndProc(ref Message m) {
const int WM_MOUSEWHEEL = 0x020A;
if (m.Msg == WM_MOUSEWHEEL) {
switch (InterceptMouseWheel) {
case InterceptMouseWheelMode.Always:
// standard message
base.WndProc(ref m);
break;
case InterceptMouseWheelMode.WhenMouseOver:
if (_mouseOver)
base.WndProc(ref m);
break;
case InterceptMouseWheelMode.Never:
// kill the message
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top