在很多Windows應用程序上我們都會用到類似Windows自帶的IP地址輸入框,如下圖所示:
在.NET中,有很多開發(fā)人員的做法是通過用普通的文本框加正則表達式的方式來實現(xiàn)這一功能或者干脆就使用文本框,但是其在方便性和實用性上很難跟MS系統(tǒng)自己的IP地址框相比。本文章實現(xiàn)的就是一個從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()
‘ 該調(diào)用是組件設計器所必需的。
InitializeComponent()
‘在 InitializeComponent() 調(diào)用之后添加任何初始化
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