在很多Windows应用程序上我们都会用到类似Windows自带的IP地址输入框,如下图所示:

在.NET中,有很多开发人员的做法是通过用普通的文本框加正则表达式的方式来实现这一功能或者干脆就使用文本框,但是其在方便性和实用性上很难跟MS系统自己的IP地址框相比。本文章实现的就是一个从Windows中“借”来个一个文本输入框,代码如下:
Imports System.Runtime.InteropServices

 Namespace FormsNamespace Forms
 Public Class IPTextBoxClass IPTextBox
Inherits System.Windows.Forms.Control

 组件设计器生成的代码#Region " 组件设计器生成的代码 "

 Public Sub New()Sub New()
MyBase.New()

‘ 该调用是组件设计器所必需的。
InitializeComponent()

‘在 InitializeComponent() 调用之后添加任何初始化
Dim CommCtrl As User32.Structures.InitCommonControls
CommCtrl.dwSize = 8
CommCtrl.dwICC = User32.Constants.ICC_INTERNET_CLASSES
If User32.InitCommonControlsEx(CommCtrl) Then
CtlHwnd = User32.CreateWindowEx(0, "SysIPAddress32", "", _
User32.Constants.WS_CHILD Or User32.Constants.WS_TABSTOP Or User32.Constants.WS_VISIBLE, 0, 0, 132, 21, _
Me.Handle, IntPtr.Zero, GetInstance, IntPtr.Zero)

If CtlHwnd.Equals(IntPtr.Zero) = False Then
‘将IP控件的字体设置的根窗体一样 用宋体
Dim hFont As IntPtr = Me.Font.ToHfont()
User32.SendMessage(CtlHwnd, User32.WindowsMessages.WM_SETFONT, hFont, IntPtr.Zero)
End If
Else
End If
End Sub

‘Control 重写 dispose 以清理组件列表。
 Protected Overloads Overrides Sub Dispose()Sub Dispose(ByVal disposing As Boolean)
If CtlHwnd.Equals(IntPtr.Zero) = False Then User32.DestroyWindow(CtlHwnd)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

‘控件设计器所必需的
Private components As System.ComponentModel.IContainer

‘注意: 以下过程是组件设计器所必需的
‘ 可以使用组件设计器修改此过程。不要使用
‘ 代码编辑器修改它。
 <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()Sub InitializeComponent()
components = New System.ComponentModel.Container
End Sub

#End Region

 Protected Overrides Sub OnPaint()Sub OnPaint(ByVal pe As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(pe)

‘在此添加自定义绘画代码
End Sub

 Private Sub IPTextBox_SizeChanged()Sub IPTextBox_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.SizeChanged
If CtlHwnd.Equals(IntPtr.Zero) = False Then User32.SetWindowPos(CtlHwnd, 0, 0, 0, Me.Width, Me.Height, &H22)
End Sub

Private CtlHwnd As IntPtr

 Propertys#Region " Propertys "
 Public Overrides Property Text()Property Text() As String
Get
Dim TempLng As Integer = 0
Dim tmpLng As IntPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(4)
Try
User32.SendMessage(CtlHwnd, User32.Constants.IPM_GETADDRESS, IntPtr.Zero, tmpLng)
TempLng = System.Runtime.InteropServices.Marshal.ReadInt32(tmpLng)
Catch ex As Exception
MsgBox(ex.Message)
End Try
System.Runtime.InteropServices.Marshal.FreeHGlobal(tmpLng)
Return FIRST_IPADDRESS(TempLng) & "." & SECOND_IPADDRESS(TempLng) & "." & THIRD_IPADDRESS(TempLng) & "." & FOURTH_IPADDRESS(TempLng)
End Get
Set(ByVal Value As String)
If Value = String.Empty Then Value = ""
If Value.Split(".").Length <> 4 Then Value = ""
If Value <> "" Then User32.SendMessage(CtlHwnd, User32.Constants.IPM_SETADDRESS, IntPtr.Zero, New IntPtr(MakeIPAddess(Value)))
End Set
End Property
#End Region

 Functions#Region " Functions "

‘‘‘ <summary>
‘‘‘ 获取应用程序的进程句柄
‘‘‘ </summary>
‘‘‘ <returns></returns>
‘‘‘ <remarks></remarks>
 Private Function GetInstance()Function GetInstance() As IntPtr
Dim tmpType As Type = Me.GetType
Dim tmpModule As System.Reflection.Module = tmpType.Module
Return System.Runtime.InteropServices.Marshal.GetHINSTANCE(tmpModule)
End Function

 Private Function FIRST_IPADDRESS()Function FIRST_IPADDRESS(ByVal x As Int32) As Byte
FIRST_IPADDRESS = ((x And &H7F000000) &H1000000) Or (((x And &H80000000) <> 0) And &H80)
End Function

 Private Function SECOND_IPADDRESS()Function SECOND_IPADDRESS(ByVal x As Int32) As Byte
SECOND_IPADDRESS = (x And &HFF0000) &H10000
End Function

 Private Function THIRD_IPADDRESS()Function THIRD_IPADDRESS(ByVal x As Int32) As Byte
THIRD_IPADDRESS = (x And &HFF00&) &H100
End Function

 Public Function FOURTH_IPADDRESS()Function FOURTH_IPADDRESS(ByVal x As Int32) As Byte
FOURTH_IPADDRESS = x And &HFF
End Function

 Private Function MAKEIPRANGE()Function MAKEIPRANGE(ByVal low As Byte, ByVal high As Byte) As Int32
MAKEIPRANGE = high * &H100& Or low
End Function

 Private Function MakeIPAddess()Function MakeIPAddess(ByVal b1 As Byte, ByVal b2 As Byte, ByVal b3 As Byte, ByVal b4 As Byte) As Int32
Return ((b1 And &H7F) * &H1000000 Or (b1 And &H80) <> 0 And &H80000000) Or (b2 * &H10000) Or (b3 * &H100&) Or (b4)
End Function

 Private Function MakeIPAddess()Function MakeIPAddess(ByVal IPAddress As String) As Int32
Dim ips As String() = IPAddress.Split(".")
If ips.Length <> 4 Then ips = New String() {"0", "0", "0", "0"}
Dim cout As Int32 = 0
For i As Integer = 0 To 3
If Not IsNumeric(ips(i)) Then
Throw New Exception("IP地址错误!")
End If
cout = (cout << 8) Or (Val(ips(i)) And &HFF)
Next
Return cout
End Function

#End Region

End Class

 Public Class User32Class User32

<DllImport("user32", EntryPoint:="CreateWindowExA", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
 Public Shared Function CreateWindowEx()Function CreateWindowEx(ByVal dwExStyle As Integer, <MarshalAs(UnmanagedType.VBByRefStr)> ByRef lpClassName As String, <MarshalAs(UnmanagedType.VBByRefStr)> ByRef lpWindowName As String, ByVal dwStyle As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hWndParent As IntPtr, ByVal hMenu As IntPtr, ByVal hInstance As IntPtr, ByVal lpParam As IntPtr) As IntPtr
End Function

<DllImport("user32", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
 Public Shared Function DestroyWindow()Function DestroyWindow(ByVal hwnd As IntPtr) As Integer
End Function

<DllImport("user32", EntryPoint:="SendMessageA", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
 Public Shared Function SendMessage()Function SendMessage(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<DllImport("user32", EntryPoint:="SendMessageA", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
 Public Shared Function SendMessage()Function SendMessage(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function

<DllImport("user32", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
 Public Shared Function SetWindowPos()Function SetWindowPos(ByVal hwnd As IntPtr, ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer
End Function

<DllImport("comctl32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
 Public Shared Function InitCommonControlsEx()Function InitCommonControlsEx(ByRef TLPINITCOMMONCONTROLSEX As Structures.InitCommonControls) As Integer
End Function

‘ Fields
Public Const MENU_CLASS As String = "#32768"

‘ Nested Types
 Public Enum ConstantsEnum Constants
ICC_INTERNET_CLASSES = 2048
IPM_CLEARADDRESS = 1124
IPM_GETADDRESS = 1126
IPM_SETADDRESS = 1125
WS_CHILD = 1073741824
WS_TABSTOP = 65536
WS_VISIBLE = 268435456
End Enum

 Public Class StructuresClass Structures

<StructLayout(LayoutKind.Sequential)> _
 Public Structure InitCommonControlsStructure InitCommonControls
‘ Fields
Public dwICC As Integer
Public dwSize As Integer
End Structure

<StructLayout(LayoutKind.Sequential)> _
 Public Structure WINDOWPOSStructure WINDOWPOS
‘ Fields
Public cx As Integer
Public cy As Integer
Public flags As Integer
Public hWnd As IntPtr
Public hWndInsertAfter As IntPtr
Public x As Integer
Public y As Integer
End Structure
End Class

 Public Enum WindowsMessagesEnum WindowsMessages
WM_SETFONT = 48
End Enum

End Class

End Namespace


|