螢幕式輸入

透過 .NET Framework 自訂螢幕鍵盤

Christopher Frenz

下載代碼示例

近年來穩步增長需要開發的應用程式需要基於螢幕的投入。 開發人員一直使用螢幕上讓人無法使用電腦鍵盤輸入的資料登錄資料或做出的選擇,尤其是在 kiosk 應用程式。

平板電腦和行動計算裝置的快速增長使螢幕上輸入更普遍和有用比以往任何時候。 一個不需要看過去的咖啡館或者找人全神貫注在最新的"應用程式"中為他們的行動電話或平板電腦設備的公共交通模式。 鑒於對在移動計算市場持續增長的預期,不難想像理解的螢幕上輸入方法將對任何開發人員很有益處。

此外,在手機市場,螢幕鍵盤也獲得更受歡迎,在應用程式中在安全性至關重要的因為基於螢幕的輸入的設備可以説明防止使用者資訊被盜使用基於硬體的擊鍵記錄程式。 網上股票經紀公司,如 TradeKing 為例,要求使用者輸入所有密碼使用螢幕鍵盤來説明提高安全性。 不過,即使螢幕鍵盤可以説明提高安全性,他們有自己考慮的潛在風險。 螢幕鍵盤減少任何基於硬體的擊鍵記錄程式的風險,但它們仍然可能容易基於軟體的輸入日誌記錄方法,以及更為常見技術"肩衝浪"以查看使用者按輸入按鈕。 例如,一個應用程式中使用捕捉到的視頻,一個人到 iPad 打字的標識哪些鍵輸入的對齊的圖像的 iPad 鍵盤按下的鍵的位置 (請參見 onforb.es/oobLp2)。

一些技術減輕肩衝浪的成效。 一個最常見的是不斷的隨機化的項,以防止任何特定的鍵來捕獲的 keypress 座標的映射。 在本文中,我將創建使用 Microsoft 的用途主要隨機化的螢幕鍵盤。NET 框架。 應用程式將允許螢幕鍵盤都連結到特定的應用­螢幕上,輸入是可取的陽離子。 然而,這篇文章介紹了生成所需的技術螢幕鍵盤和示例應用程式為了說明這些技術,不是要提供一個功能全面的鍵盤應用程式。

螢幕鍵盤圖形化使用者介面

每個字母的字母表和每個號碼的第一步鋪設 GUI 上,其中包括一把"鑰匙"(請參見圖 1)。 在開始拖動到表單上的控制項之前,然而,有需要考慮的幾個問題。 在大多數。網路應用程式 (和以及其他應用程式),每當您希望使用者提交輸入通過點擊要使用的標準控制項的東西,將一個按鈕。 您不能使用的按鈕控制項,但因為一個按鈕控制項上按一下,將自動獲得焦點的 Windows 作業系統的螢幕鍵盤。 因為鍵盤輸入打算去主動前臺應用程式 (也就是說,應用焦點),螢幕鍵盤應該永遠不會獲得作業系統的焦點。 而不是使用按鈕控制項的金鑰,我就改用標籤控制項,因為它們支援的 Click 事件,如按鈕,但不像按鈕不被允許獲得焦點。 標籤,因此使一個理想的選擇,能夠回應按一下而不啟動應用焦點的變化 — — 帶著一些額外的編碼,您將看到下一節。 示例應用程式而言,這些標籤將命名通過 Label36 label1 的標籤。 比較使用者輸入,輸入到文字方塊中,TextBox1,還會創建與外部應用程式中出現的螢幕鍵盤 (請參見圖 1)。

The Design View of the On-Screen Keyboard GUI
圖 1 設計檢視的螢幕鍵盤圖形化使用者介面

留出的焦點

雖然使用控制項,如標籤是要避免導致應用程式接收焦點的作業系統,它是不夠本身因為螢幕鍵盤應用程式還可以接收焦點時載入表單本身和滑鼠按一下表單或表單上的任何控制項時。 為了糾正這種情況下,我需要一些額外的代碼添加到鍵盤應用。

首先,要防止表單獲得焦點,它首次載入時,會添加下麵的代碼 (我使用 Visual Basic。淨) 應用程式:

Private Const WS_EX_NOACTIVATE As Integer = &H8000000
Protected Overrides ReadOnly Property CreateParams() As CreateParams
  Get
    CreateParams = MyBase.CreateParams
    CreateParams.ExStyle = CreateParams.ExStyle And WS_EX_NOACTIVATE
    Return CreateParams
  End Get
End Property

此代碼將覆蓋表單的 CreateParams 屬性,用於創建表單物件。 通過重寫此屬性為 WS_EX_NOACTIVATE 視窗樣式,我阻止表單來載入,這意味著該載入時前臺螢幕鍵盤不會把焦點從任何其他應用程式在啟動時處於活動狀態。 此代碼到位,一旦,重要的是下一步確保應用程式不能實現通過滑鼠按一下的焦點。 添加此代碼來實現的:

Private Const WM_MOUSEACTIVATE As Integer = &H21
Private Const MA_NOACTIVATE As Integer = &H3
Protected Overrides Sub WndProc(ByRef m As Message)
  If (m.Msg = WM_MOUSEACTIVATE) Then
      m.Result = MA_NOACTIVATE
    Else
      MyBase.WndProc(m)
    End If
End Sub

此代碼將表單的 WndProc 函數,它接收所有使用者輸入的表單使用重寫。 重寫函數截獲 WM_MOUSEACTIVATE 消息,非使用中視窗上按一下時發送。 它還能確保螢幕鍵盤應用不通過函數返回值設置為 MA_NOACTIVATE 獲得焦點,滑鼠點擊的結果。 此代碼"Else"條件確保所有其他滑鼠輸入的消息都變通過,從而使螢幕鍵盤應用檢測標籤,按一下沒有過獲得焦點。

添加鍵盤功能

在這一點上,我有一個 GUI 應用程式和代碼以確保它保持無焦點。 它現在是時候添加實際鍵盤功能。 此功能的第一位將創建要分配給每個標籤的隨機但唯一鍵的子常式 (AssignKeys) (請參見圖 2)。

圖 2 為每個標籤控制項分配隨機的唯一鍵

Private Sub AssignKeys()
  Dim Character() As Char =
    {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", _
     "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", _
     "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", _
     "X", "C", "V", "B", "N", "M"}
  Dim Keys(36) As Char
  Dim I, X As Integer
  Dim Rand As New Random()
  Dim Used(36) As Integer
  Dim Unique As Boolean = False
    Used(0) = -1
    For I = 0 To 35
      Unique = False
      X = Rand.Next(0, 36)
      If Character(X) <> " " Then
        Keys(I) = Character(X)
        Character(X) = " "
      Else
        Do Until Unique = True
          X = Rand.Next(0, 36)
          If Character(X) <> " " Then
            Keys(I) = Character(X)
            Character(X) = " "
            Unique = True
          End If
        Loop
        End If
  Next
    Label1.Text = Keys(0)
    Label2.Text = Keys(1)
    Label3.Text = Keys(2)
    Label4.Text = Keys(3)
    Label5.Text = Keys(4)
    Label6.Text = Keys(5)
    Label7.Text = Keys(6)
    Label8.Text = Keys(7)
    Label9.Text = Keys(8)
    Label10.Text = Keys(9)
    Label11.Text = Keys(10)
    Label12.Text = Keys(11)
    Label13.Text = Keys(12)
    Label14.Text = Keys(13)
    Label15.Text = Keys(14)
    Label16.Text = Keys(15)
    Label17.Text = Keys(16)
    Label18.Text = Keys(17)
    Label19.Text = Keys(18)
    Label20.Text = Keys(19)
    Label21.Text = Keys(20)
    Label22.Text = Keys(21)
    Label23.Text = Keys(22)
    Label24.Text = Keys(23)
    Label25.Text = Keys(24)
    Label26.Text = Keys(25)
    Label27.Text = Keys(26)
    Label28.Text = Keys(27)
    Label29.Text = Keys(28)
    Label30.Text = Keys(29)
    Label31.Text = Keys(30)
    Label32.Text = Keys(31)
    Label33.Text = Keys(32)
    Label34.Text = Keys(33)
    Label35.Text = Keys(34)
    Label36.Text = Keys(35)
  End Sub

在該常式圖 2 創建的陣列 (字元),其中包含所有選定要在鍵盤上顯示的字母數位字元,然後應用亂數產生器選擇隨機的元素,從該陣列。 只要該元素沒有了以前的選擇,存儲在該特定元素的陣列中的字元複製到陣列稱為鍵。 重複此過程,直到所有 36 字元分配到鍵陣列中,隨機在陣列中的每個字元的位置。 陣列隨機的一旦鍵陣列的元素分配給每個標籤的 Text 屬性,使其賦值的字元將顯示在螢幕上。 此 AssignKeys 子常式最初呼籲執行 Form_Load 事件的影響。

現在,字元被指派到他們各自的鍵,我需要添加代碼來處理轉換滑鼠點擊螢幕鍵盤,相當於將按鍵發送到目標應用程式的應用。 為此,我要利用 user32.dll API,Windows 用來處理許多 UI 相關的功能,如視窗處理和其他視窗管理功能。 要正確設置應用程式使用此 API 的功能,會添加表單類的 DLL 導入下列語句:

<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function FindWindow(ByVal lpClassName As String, _
    ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
End Function

User32.dll API 將使用每次啟動時的 Label_Click 事件,因為每個此類事件中的代碼類似于圖 3

圖 3 user32.dll API 使用 Label_Click 事件

Private Sub Label1_Click(ByVal sender As System.Object,_
  ByVal e As System.EventArgs) Handles Label1.Click
  Dim X As Char
  X = CChar(Label1.Text)
  Dim theHandle As IntPtr
  theHandle = FindWindow(Nothing, "Untitled - Notepad")
  If theHandle <> IntPtr.Zero Then
    SetForegroundWindow(theHandle)
    SendKeys.Send(X)
  End If
  TextBox1.Text = TextBox1.Text & Label1.Text
  AssignKeys()
End Sub

標籤的 click 事件時,"theHandle"變數用於存儲的應用程式的應用程式控制碼螢幕鍵盤將要發送其輸入。 在這種情況下,應用的控制碼被設置為新鮮載入副本記事本,因為它是普遍適用于所有的 Windows 系統。 如果當前存在於系統中應用的控制碼,應用程式承載該控制碼 (記事本) 移動到前臺和分配給該標籤的字元發送到應用程式。 字元也會附加到任何發現表明在記事本中顯示的字元是收到鍵盤應用程式本身的相同字元鍵盤應用程式的文字方塊內的文本。 作為最後一步是 AssignKeys 子常式又稱 re-randomize 的重要位置,並使肩衝浪更難。 此過程所示圖 4圖 5,其中 圖 4 顯示新載入的應用程式版本和圖 5 演示螢幕鍵盤和記事本上的幾個按鍵後螢幕鍵盤。

A New Instance of the On-Screen Keyboard
圖 4 新實例的螢幕鍵盤

The On-Screen Keyboard Sending Input to Notepad
圖 5:螢幕鍵盤發送到記事本輸入

增強的安全性和移動的移植

這篇文章展示發展的螢幕鍵盤使用。NET 框架。 我希望它提供一些如何在螢幕上鍵盤可以開發,用於提高某些元素的輸入資料的安全,或用於移植的洞察。移動平臺的網路應用。

Christopher M. Frenz 是作者的程式設計書籍,"Visual Basic 和 Visual Basic。科學家和工程師的淨"(很,2002年) 和"Pro Perl 解析"(很,2005年)。他可以通過 cfrenz@gmail.com

多虧了以下技術專家審查這篇文章: Robert Green