SendKeys in WPF
在以往Windows Form的程式開發當中,當要送出鍵盤的相關資料時,會使用SendKeys的方式來處理,例如說要把一個字加到TextBox上這樣;用SendKeys的好處不用去處理當輸入的游標在文字中間的問題,會比像是
TextBox1.Text &= "1"
這樣的方式來的方便些。而到了WPF,沒有SendKeys可以用了,那麼應該怎麼辦呢?在網路上搜尋了一下,可以利用呼叫API的方式來做,可以參考一下下面 SendInput 的說明,所有需要的東西都在裡面了。動作原理大概是下面過程
紀錄要輸入的控制項在畫面上的位置
使用SendInput模擬滑鼠的動作,點擊要輸入的控制項(主要是要取得Focus)
使用SendInput模擬KeyDown的動作
使用 SendInput模擬KeyUp的動作
大概的過程是這樣子了;而我自己的使用方式有點偷懶,直接略過模擬滑鼠的部分,直接傳控制項的參考過去 XDD
下面是目前的程式碼,還沒詳細測試,大致就是上面列出的SendInput中的程式碼了,參考看看了;首先是宣告的部分
而外面的UerControl多加了一個Property,使用方式大約會像是這樣子
TextBox1.Text &= "1"
這樣的方式來的方便些。而到了WPF,沒有SendKeys可以用了,那麼應該怎麼辦呢?在網路上搜尋了一下,可以利用呼叫API的方式來做,可以參考一下下面 SendInput 的說明,所有需要的東西都在裡面了。動作原理大概是下面過程
紀錄要輸入的控制項在畫面上的位置
使用SendInput模擬滑鼠的動作,點擊要輸入的控制項(主要是要取得Focus)
使用SendInput模擬KeyDown的動作
使用 SendInput模擬KeyUp的動作
大概的過程是這樣子了;而我自己的使用方式有點偷懶,直接略過模擬滑鼠的部分,直接傳控制項的參考過去 XDD
下面是目前的程式碼,還沒詳細測試,大致就是上面列出的SendInput中的程式碼了,參考看看了;首先是宣告的部分
#Region "Const" Const INPUT_MOUSE As UInt32 = 0 Const INPUT_KEYBOARD As Integer = 1 Const INPUT_HARDWARE As Integer = 2 Const KEYEVENTF_EXTENDEDKEY As UInt32 = &H1 Const KEYEVENTF_KEYUP As UInt32 = &H2 Const KEYEVENTF_UNICODE As UInt32 = &H4 Const KEYEVENTF_SCANCODE As UInt32 = &H8 Const XBUTTON1 As UInt32 = &H1 Const XBUTTON2 As UInt32 = &H2 Const MOUSEEVENTF_MOVE As UInt32 = &H1 Const MOUSEEVENTF_LEFTDOWN As UInt32 = &H2 Const MOUSEEVENTF_LEFTUP As UInt32 = &H4 Const MOUSEEVENTF_RIGHTDOWN As UInt32 = &H8 Const MOUSEEVENTF_RIGHTUP As UInt32 = &H10 Const MOUSEEVENTF_MIDDLEDOWN As UInt32 = &H20 Const MOUSEEVENTF_MIDDLEUP As UInt32 = &H40 Const MOUSEEVENTF_XDOWN As UInt32 = &H80 Const MOUSEEVENTF_XUP As UInt32 = &H100 Const MOUSEEVENTF_WHEEL As UInt32 = &H800 Const MOUSEEVENTF_VIRTUALDESK As UInt32 = &H4000 Const MOUSEEVENTF_ABSOLUTE As UInt32 = &H8000 #End Region #Region "Enums" Public Enum InputType As Integer Mouse = 0 Keyboard = 1 Hardware = 2 End Enum <Flags()> _ Public Enum MOUSEEVENTF As Integer MOVE = &H1 LEFTDOWN = &H2 LEFTUP = &H4 RIGHTDOWN = &H8 RIGHTUP = &H10 MIDDLEDOWN = &H20 MIDDLEUP = &H40 XDOWN = &H80 XUP = &H100 VIRTUALDESK = &H400 WHEEL = &H800 ABSOLUTE = &H8000 End Enum <Flags()> _ Public Enum KEYEVENTF As Integer EXTENDEDKEY = 1 KEYUP = 2 [UNICODE] = 4 SCANCODE = 8 End Enum #End Region #Region "Structure" <StructLayout(LayoutKind.Explicit)> _ Public Structure INPUT <FieldOffset(0)> Dim dwType As Integer <FieldOffset(4)> Dim mouseInput As MOUSEINPUT <FieldOffset(4)> Dim keyboardInput As KEYBDINPUT <FieldOffset(4)> Dim hardwareInput As HARDWAREINPUT End Structure <StructLayout(LayoutKind.Explicit)> _ Public Structure KEYBDINPUT <FieldOffset(0)> Public wVk As Short <FieldOffset(2)> Public wScan As Short <FieldOffset(4)> Public dwFlags As Integer <FieldOffset(8)> Public time As Integer <FieldOffset(12)> Public dwExtraInfo As IntPtr End Structure <StructLayout(LayoutKind.Explicit)> _ Public Structure HARDWAREINPUT <FieldOffset(0)> Public uMsg As Integer <FieldOffset(4)> Public wParamL As Short <FieldOffset(6)> Public wParamH As Short End Structure <StructLayout(LayoutKind.Explicit)> _ Public Structure MOUSEINPUT <FieldOffset(0)> Public dx As Integer <FieldOffset(4)> Public dy As Integer <FieldOffset(8)> Public mouseData As Integer <FieldOffset(12)> Public dwFlags As Integer <FieldOffset(16)> Public time As Integer <FieldOffset(20)> Public dwExtraInfo As IntPtr End Structure #End Region <DllImport("user32.dll", EntryPoint:="SendInput")> Public Shared Function SendInput(ByVal cInputs As Integer, ByRef pInputs As INPUT, ByVal cbSize As Integer) As Integer End Function Public Shared Sub DoKeyBoard(ByVal flags As KEYEVENTF, ByVal key As Char) Dim _input As New INPUT Dim ki As New KEYBDINPUT _input.dwType = InputType.Keyboard _input.keyboardInput = ki _input.keyboardInput.wVk = Convert.ToInt16(key) _input.keyboardInput.wScan = 0 _input.keyboardInput.time = 0 _input.keyboardInput.dwFlags = flags _input.keyboardInput.dwExtraInfo = IntPtr.Zero Dim cbSize As Integer = Marshal.SizeOf(GetType(INPUT)) Dim result As Integer = SendInput(1, _input, cbSize) 'If result = 0 Then Debug.WriteLine(Marshal.GetLastWin32Error) _input = Nothing ki = Nothing End Sub
而外面的UerControl多加了一個Property,使用方式大約會像是這樣子
Public Property FoucedCtl As TextBox Private Sub Button_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) If Me.FoucedCtl Is Nothing Then Exit Sub End If Me.FoucedCtl.Focus() Win32Helper.DoKeyBoard(0, CType(sender, Button).Content.ToString.Chars(0)) System.Threading.Thread.Sleep(5) Win32Helper.DoKeyBoard(Win32Helper.KEYEVENTF.KEYUP, CType(sender, Button).Content.ToString.Chars(0)) End Sub
留言