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();
}
}
}
}
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();
}
}
}
}