A IP Control

T

Tom Shelton

I was goofing around tonight and decided to write a little IP address
control. I had written a simple one a long time ago, but I decided I
should try to write one that was half way correct :) Anyway, here is the
result of about an hour and half of work...

// IPControl.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Net;
using System.Runtime.InteropServices;

namespace FireAnt.Controls
{

/// <summary>
/// Simple API Based IP Control
/// </summary>
public class IPControl : System.Windows.Forms.UserControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private NativeIPControl ipControl;

public event FieldChangedDelegate FieldChanged;

public IPControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();

// create the native ip control
this.ipControl =
new NativeIPControl(this.Handle, this.Height, this.Width);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

/// <summary>
/// Overridden window procedure
/// </summary>
/// <param name="m">Window message to process</param>
protected override void WndProc(ref Message m)
{
// we need to over ride this so that we
// can receive notification messages from the
// native ip control window...
switch (m.Msg)
{
case Win32Interop.WM_NOTIFY:
unsafe
{
Win32Interop.NMHDR* nmhdr = (Win32Interop.NMHDR*) m.LParam;
if (nmhdr->code == Win32Interop.IPN_FIELDCHANGED)
{
Win32Interop.NMIPADDRESS* nmaddr
= (Win32Interop.NMIPADDRESS*) m.LParam;

// fire a field changed event...
FieldChangedEventArgs e
= new FieldChangedEventArgs(nmaddr->iField, nmaddr->iValue);
if (this.FieldChanged != null)
{
this.FieldChanged (this, e);
}

// change the feild value...
nmaddr->iValue = e.Value;
}
else
{
base.WndProc(ref m);
}
}
break;
default:
base.WndProc (ref m);
break;
}
}

#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// FAIPControl
//
this.Name = "IPControl";
this.Size = new System.Drawing.Size(132, 20);
this.Enter += new System.EventHandler(this.IPControl_Enter);

}
#endregion

/// <summary>
/// Get/Set the IP address for the control
/// </summary>
[Browsable(false),
ReadOnly(true)]
public IPAddress Address
{
get
{
uint address = 0;

if (Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_ISBLANK,
0,
0) == 0)
{
// get the address
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_GETADDRESS,
0,
out address
);

// we need to reverse the order...
byte[] buffer = BitConverter.GetBytes(address);
System.Array.Reverse(buffer, 0, buffer.Length);
address = BitConverter.ToUInt32(buffer, 0);
}

return new IPAddress(address);
}
set
{
// we need to get the bytes, and reverse the order
byte[] buffer = value.GetAddressBytes();
System.Array.Reverse(buffer, 0, buffer.Length);
uint address = BitConverter.ToUInt32(buffer, 0);

// now set the value
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETADDRESS,
0,
address
);
}
}

/// <summary>
/// Clear the control
/// </summary>
public void Clear()
{
// clear the ip values...
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_CLEARADDRESS,
0,
0
);
}

/// <summary>
/// Set focus to a particular field in the control
/// </summary>
/// <param name="field">The zero based field index to set focus
to</param>
public void Focus(int field)
{
if (field < 0 || field > 3)
{
throw new ArgumentOutOfRangeException (
"field",
field,
"Field must be between 0 and 3");
}

Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETFOCUS,
(uint) field, 0
);
}

private void IPControl_Enter(object sender, System.EventArgs e)
{
// set the focus to our ip control...
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETFOCUS,
0,
0
);
}


/// <summary>
/// Native Windows IP Control Class
/// </summary>
private class NativeIPControl : System.Windows.Forms.NativeWindow
{
public NativeIPControl(IntPtr parent, int height, int width)
{
// create the create params structure
CreateParams cp = new CreateParams();

// fill it in...
cp.ClassName = Win32Interop.WC_IPADDRESS;
cp.Style = Win32Interop.WS_CHILD | Win32Interop.WS_VISIBLE;
cp.X = 0;
cp.Y = 0;
cp.Height = height;
cp.Width = width;
cp.Parent = parent;

// create the window
this.CreateHandle(cp);
}

// we'll probably need this latter...
protected override void WndProc(ref Message m)
{
// for now just call the default procedure
base.DefWndProc(ref m);
}


}

}

public class FieldChangedEventArgs : System.EventArgs
{
private int field;
private int newValue;

internal FieldChangedEventArgs(int field, int newValue)
{
this.field = field;
this.newValue = newValue;
}

public int Field
{
get
{
return this.field;
}
}

public int Value
{
get
{
return this.newValue;
}
set
{
if (value >= 0 && value <= 255)
{
this.newValue = value;
}
}
}
}

public delegate void FieldChangedDelegate (
object sender, FieldChangedEventArgs e);

}

// Win32Interop.cs
using System;
using System.Runtime.InteropServices;

namespace FireAnt.Controls
{
/// <summary>
/// Win32 Interop Definitions
/// </summary>
internal sealed class Win32Interop
{
// Window Style Constants
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000;

// Window Class Names
public const string WC_IPADDRESS = "SysIPAddress32";

// IP Control Window Messages
public const uint IPM_CLEARADDRESS = (WM_USER+100); // no parameters
public const uint IPM_SETADDRESS = (WM_USER+101); // lparam = TCP/IP
address
public const uint IPM_GETADDRESS = (WM_USER+102); // lresult = # of non
black fields. lparam = LPDWORD for TCP/IP address
public const uint IPM_SETRANGE = (WM_USER+103); // wparam = field,
lparam = range
public const uint IPM_SETFOCUS = (WM_USER+104); // wparam = field
public const uint IPM_ISBLANK = (WM_USER+105); // no parameters

// IP Control Notification Messages
public const int WM_NOTIFY = 0x004E;
public const uint IPN_FIELDCHANGED = (IPN_FIRST - 0);

// IP Control Structures
[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public uint idFrom;
public uint code;
}

[StructLayout(LayoutKind.Sequential)]
public struct NMIPADDRESS
{
public NMHDR hdr;
public int iField;
public int iValue;
}

#region API Function Calls
[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern uint SendMessage (
IntPtr hWnd,
uint Msg,
uint wParam,
uint lParam
);

[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern uint SendMessage (
IntPtr hWnd,
uint Msg,
uint wParam,
out uint lParam
);
#endregion

#region Private Data
// private window message constants
private const uint WM_USER = 0x0400;
private const uint IPN_FIRST = unchecked(0U-860U); // internet address
private const uint IPN_LAST = unchecked(0U-879U); // internet address
private Win32Interop() {}
#endregion

}
}

Sorry, the code is in C# - but I thought I'd share it with you guys anyway.

HTH
 
C

Cor Ligthert

Hi Tom,

Thanks for sending this, however when I would do it this way I had the
change to be flamed by Herfried.

:)

And than I would laugh.

Cor
I was goofing around tonight and decided to write a little IP address
control. I had written a simple one a long time ago, but I decided I
should try to write one that was half way correct :) Anyway, here is the
result of about an hour and half of work...

// IPControl.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Net;
using System.Runtime.InteropServices;

namespace FireAnt.Controls
{

/// <summary>
/// Simple API Based IP Control
/// </summary>
public class IPControl : System.Windows.Forms.UserControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private NativeIPControl ipControl;

public event FieldChangedDelegate FieldChanged;

public IPControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();

// create the native ip control
this.ipControl =
new NativeIPControl(this.Handle, this.Height, this.Width);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

/// <summary>
/// Overridden window procedure
/// </summary>
/// <param name="m">Window message to process</param>
protected override void WndProc(ref Message m)
{
// we need to over ride this so that we
// can receive notification messages from the
// native ip control window...
switch (m.Msg)
{
case Win32Interop.WM_NOTIFY:
unsafe
{
Win32Interop.NMHDR* nmhdr = (Win32Interop.NMHDR*) m.LParam;
if (nmhdr->code == Win32Interop.IPN_FIELDCHANGED)
{
Win32Interop.NMIPADDRESS* nmaddr
= (Win32Interop.NMIPADDRESS*) m.LParam;

// fire a field changed event...
FieldChangedEventArgs e
= new FieldChangedEventArgs(nmaddr->iField, nmaddr->iValue);
if (this.FieldChanged != null)
{
this.FieldChanged (this, e);
}

// change the feild value...
nmaddr->iValue = e.Value;
}
else
{
base.WndProc(ref m);
}
}
break;
default:
base.WndProc (ref m);
break;
}
}

#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// FAIPControl
//
this.Name = "IPControl";
this.Size = new System.Drawing.Size(132, 20);
this.Enter += new System.EventHandler(this.IPControl_Enter);

}
#endregion

/// <summary>
/// Get/Set the IP address for the control
/// </summary>
[Browsable(false),
ReadOnly(true)]
public IPAddress Address
{
get
{
uint address = 0;

if (Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_ISBLANK,
0,
0) == 0)
{
// get the address
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_GETADDRESS,
0,
out address
);

// we need to reverse the order...
byte[] buffer = BitConverter.GetBytes(address);
System.Array.Reverse(buffer, 0, buffer.Length);
address = BitConverter.ToUInt32(buffer, 0);
}

return new IPAddress(address);
}
set
{
// we need to get the bytes, and reverse the order
byte[] buffer = value.GetAddressBytes();
System.Array.Reverse(buffer, 0, buffer.Length);
uint address = BitConverter.ToUInt32(buffer, 0);

// now set the value
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETADDRESS,
0,
address
);
}
}

/// <summary>
/// Clear the control
/// </summary>
public void Clear()
{
// clear the ip values...
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_CLEARADDRESS,
0,
0
);
}

/// <summary>
/// Set focus to a particular field in the control
/// </summary>
/// <param name="field">The zero based field index to set focus
to</param>
public void Focus(int field)
{
if (field < 0 || field > 3)
{
throw new ArgumentOutOfRangeException (
"field",
field,
"Field must be between 0 and 3");
}

Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETFOCUS,
(uint) field, 0
);
}

private void IPControl_Enter(object sender, System.EventArgs e)
{
// set the focus to our ip control...
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETFOCUS,
0,
0
);
}


/// <summary>
/// Native Windows IP Control Class
/// </summary>
private class NativeIPControl : System.Windows.Forms.NativeWindow
{
public NativeIPControl(IntPtr parent, int height, int width)
{
// create the create params structure
CreateParams cp = new CreateParams();

// fill it in...
cp.ClassName = Win32Interop.WC_IPADDRESS;
cp.Style = Win32Interop.WS_CHILD | Win32Interop.WS_VISIBLE;
cp.X = 0;
cp.Y = 0;
cp.Height = height;
cp.Width = width;
cp.Parent = parent;

// create the window
this.CreateHandle(cp);
}

// we'll probably need this latter...
protected override void WndProc(ref Message m)
{
// for now just call the default procedure
base.DefWndProc(ref m);
}


}

}

public class FieldChangedEventArgs : System.EventArgs
{
private int field;
private int newValue;

internal FieldChangedEventArgs(int field, int newValue)
{
this.field = field;
this.newValue = newValue;
}

public int Field
{
get
{
return this.field;
}
}

public int Value
{
get
{
return this.newValue;
}
set
{
if (value >= 0 && value <= 255)
{
this.newValue = value;
}
}
}
}

public delegate void FieldChangedDelegate (
object sender, FieldChangedEventArgs e);

}

// Win32Interop.cs
using System;
using System.Runtime.InteropServices;

namespace FireAnt.Controls
{
/// <summary>
/// Win32 Interop Definitions
/// </summary>
internal sealed class Win32Interop
{
// Window Style Constants
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000;

// Window Class Names
public const string WC_IPADDRESS = "SysIPAddress32";

// IP Control Window Messages
public const uint IPM_CLEARADDRESS = (WM_USER+100); // no parameters
public const uint IPM_SETADDRESS = (WM_USER+101); // lparam = TCP/IP
address
public const uint IPM_GETADDRESS = (WM_USER+102); // lresult = # of non
black fields. lparam = LPDWORD for TCP/IP address
public const uint IPM_SETRANGE = (WM_USER+103); // wparam = field,
lparam = range
public const uint IPM_SETFOCUS = (WM_USER+104); // wparam = field
public const uint IPM_ISBLANK = (WM_USER+105); // no parameters

// IP Control Notification Messages
public const int WM_NOTIFY = 0x004E;
public const uint IPN_FIELDCHANGED = (IPN_FIRST - 0);

// IP Control Structures
[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public uint idFrom;
public uint code;
}

[StructLayout(LayoutKind.Sequential)]
public struct NMIPADDRESS
{
public NMHDR hdr;
public int iField;
public int iValue;
}

#region API Function Calls
[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern uint SendMessage (
IntPtr hWnd,
uint Msg,
uint wParam,
uint lParam
);

[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern uint SendMessage (
IntPtr hWnd,
uint Msg,
uint wParam,
out uint lParam
);
#endregion

#region Private Data
// private window message constants
private const uint WM_USER = 0x0400;
private const uint IPN_FIRST = unchecked(0U-860U); // internet address
private const uint IPN_LAST = unchecked(0U-879U); // internet address
private Win32Interop() {}
#endregion

}
}

Sorry, the code is in C# - but I thought I'd share it with you guys anyway.

HTH
 
S

scorpion53061

This is really cool.

Tom Shelton said:
I was goofing around tonight and decided to write a little IP address
control. I had written a simple one a long time ago, but I decided I
should try to write one that was half way correct :) Anyway, here is the

result of about an hour and half of work...

// IPControl.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Net;
using System.Runtime.InteropServices;

namespace FireAnt.Controls
{

/// <summary>
/// Simple API Based IP Control
/// </summary>
public class IPControl : System.Windows.Forms.UserControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private NativeIPControl ipControl;

public event FieldChangedDelegate FieldChanged;

public IPControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();

// create the native ip control
this.ipControl =
new NativeIPControl(this.Handle, this.Height, this.Width);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

/// <summary>
/// Overridden window procedure
/// </summary>
/// <param name="m">Window message to process</param>
protected override void WndProc(ref Message m)
{
// we need to over ride this so that we
// can receive notification messages from the
// native ip control window...
switch (m.Msg)
{
case Win32Interop.WM_NOTIFY:
unsafe
{
Win32Interop.NMHDR* nmhdr = (Win32Interop.NMHDR*) m.LParam;
if (nmhdr->code == Win32Interop.IPN_FIELDCHANGED)
{
Win32Interop.NMIPADDRESS* nmaddr
= (Win32Interop.NMIPADDRESS*) m.LParam;

// fire a field changed event...
FieldChangedEventArgs e
= new FieldChangedEventArgs(nmaddr->iField, nmaddr->iValue);
if (this.FieldChanged != null)
{
this.FieldChanged (this, e);
}

// change the feild value...
nmaddr->iValue = e.Value;
}
else
{
base.WndProc(ref m);
}
}
break;
default:
base.WndProc (ref m);
break;
}
}

#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// FAIPControl
//
this.Name = "IPControl";
this.Size = new System.Drawing.Size(132, 20);
this.Enter += new System.EventHandler(this.IPControl_Enter);

}
#endregion

/// <summary>
/// Get/Set the IP address for the control
/// </summary>
[Browsable(false),
ReadOnly(true)]
public IPAddress Address
{
get
{
uint address = 0;

if (Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_ISBLANK,
0,
0) == 0)
{
// get the address
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_GETADDRESS,
0,
out address
);

// we need to reverse the order...
byte[] buffer = BitConverter.GetBytes(address);
System.Array.Reverse(buffer, 0, buffer.Length);
address = BitConverter.ToUInt32(buffer, 0);
}

return new IPAddress(address);
}
set
{
// we need to get the bytes, and reverse the order
byte[] buffer = value.GetAddressBytes();
System.Array.Reverse(buffer, 0, buffer.Length);
uint address = BitConverter.ToUInt32(buffer, 0);

// now set the value
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETADDRESS,
0,
address
);
}
}

/// <summary>
/// Clear the control
/// </summary>
public void Clear()
{
// clear the ip values...
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_CLEARADDRESS,
0,
0
);
}

/// <summary>
/// Set focus to a particular field in the control
/// </summary>
/// <param name="field">The zero based field index to set focus
to</param>
public void Focus(int field)
{
if (field < 0 || field > 3)
{
throw new ArgumentOutOfRangeException (
"field",
field,
"Field must be between 0 and 3");
}

Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETFOCUS,
(uint) field, 0
);
}

private void IPControl_Enter(object sender, System.EventArgs e)
{
// set the focus to our ip control...
Win32Interop.SendMessage (
this.ipControl.Handle,
Win32Interop.IPM_SETFOCUS,
0,
0
);
}


/// <summary>
/// Native Windows IP Control Class
/// </summary>
private class NativeIPControl : System.Windows.Forms.NativeWindow
{
public NativeIPControl(IntPtr parent, int height, int width)
{
// create the create params structure
CreateParams cp = new CreateParams();

// fill it in...
cp.ClassName = Win32Interop.WC_IPADDRESS;
cp.Style = Win32Interop.WS_CHILD | Win32Interop.WS_VISIBLE;
cp.X = 0;
cp.Y = 0;
cp.Height = height;
cp.Width = width;
cp.Parent = parent;

// create the window
this.CreateHandle(cp);
}

// we'll probably need this latter...
protected override void WndProc(ref Message m)
{
// for now just call the default procedure
base.DefWndProc(ref m);
}


}

}

public class FieldChangedEventArgs : System.EventArgs
{
private int field;
private int newValue;

internal FieldChangedEventArgs(int field, int newValue)
{
this.field = field;
this.newValue = newValue;
}

public int Field
{
get
{
return this.field;
}
}

public int Value
{
get
{
return this.newValue;
}
set
{
if (value >= 0 && value <= 255)
{
this.newValue = value;
}
}
}
}

public delegate void FieldChangedDelegate (
object sender, FieldChangedEventArgs e);

}

// Win32Interop.cs
using System;
using System.Runtime.InteropServices;

namespace FireAnt.Controls
{
/// <summary>
/// Win32 Interop Definitions
/// </summary>
internal sealed class Win32Interop
{
// Window Style Constants
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000;

// Window Class Names
public const string WC_IPADDRESS = "SysIPAddress32";

// IP Control Window Messages
public const uint IPM_CLEARADDRESS = (WM_USER+100); // no parameters
public const uint IPM_SETADDRESS = (WM_USER+101); // lparam = TCP/IP
address
public const uint IPM_GETADDRESS = (WM_USER+102); // lresult = # of non

black fields. lparam = LPDWORD for TCP/IP address
public const uint IPM_SETRANGE = (WM_USER+103); // wparam = field,
lparam = range
public const uint IPM_SETFOCUS = (WM_USER+104); // wparam = field
public const uint IPM_ISBLANK = (WM_USER+105); // no parameters

// IP Control Notification Messages
public const int WM_NOTIFY = 0x004E;
public const uint IPN_FIELDCHANGED = (IPN_FIRST - 0);

// IP Control Structures
[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public uint idFrom;
public uint code;
}

[StructLayout(LayoutKind.Sequential)]
public struct NMIPADDRESS
{
public NMHDR hdr;
public int iField;
public int iValue;
}

#region API Function Calls
[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern uint SendMessage (
IntPtr hWnd,
uint Msg,
uint wParam,
uint lParam
);

[DllImport("user32", CharSet=CharSet.Auto, SetLastError=true)]
public static extern uint SendMessage (
IntPtr hWnd,
uint Msg,
uint wParam,
out uint lParam
);
#endregion

#region Private Data
// private window message constants
private const uint WM_USER = 0x0400;
private const uint IPN_FIRST = unchecked(0U-860U); // internet address
private const uint IPN_LAST = unchecked(0U-879U); // internet address
private Win32Interop() {}
#endregion

}
}

Sorry, the code is in C# - but I thought I'd share it with you guys
anyway.

HTH
 

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