簡體   English   中英

在 WinForms 輸入焦點上自動彈出平板觸摸鍵盤

[英]Automatically pop up tablet touch keyboard on WinForms input focus

當我以平板電腦模式在 Windows 10 上運行 WinForms(或 Delphi,見文末)應用程序時,當輸入框聚焦時,觸摸鍵盤不會自動彈出。

我相信這應該自動發生,沒有任何額外的代碼/設置。


為了測試,我有一個最簡單的 VS 2015 WinForms 桌面應用程序,帶有一個TextBox控件

在此處輸入圖片說明

它只是 Visual Studio 創建的默認 Windows 窗體應用程序 C# 項目。 未添加代碼,未更改任何屬性。 通過從工具箱中刪除(同樣沒有更改屬性),只添加了TextBox

this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox1.Location = new System.Drawing.Point(64, 27);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 0;

為了驗證我的假設,彈出窗口應該是自動的:

  • 我嘗試在 Windows 10 上運行 Windows XP 版本的notepad.exe 。它會自動彈出觸摸鍵盤。 我懷疑 Windows XP 是否明確支持觸摸鍵盤。

  • 我還嘗試了一些古老的 MFC 應用程序(例如 2005 年的 FileZilla 2.2.15)。 它還會在其所有輸入框上彈出觸摸鍵盤。 同樣,我很確定,MFC 也沒有明確支持觸摸鍵盤。

  • 構建在 wxWidgets 上的應用程序(例如 FileZilla 3.x)也是如此。


看起來 WinForms 中的某些東西阻止了自動彈出窗口。 有趣的是,自動彈出的工作原理是:

  • 對於(可編輯的)組合框( ComboBox with DropDownStyle = DropDown
  • 用於密碼模式下的文本框 ( TextBox.PasswordChar )
  • 對於富文本框 ( RichTextBox )
  • 當輸入框在硬件鍵盤被“移除”的那一刻有焦點時(我通過在聯想瑜伽筆記本上翻轉屏幕來測試),但永遠不會。

我已經通過運行TabTip.exe看到了有關顯式彈出窗口的所有提示。 例如:

大多數“解決方案”都提供這樣的代碼:

var progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
var keyboardPath = Path.Combine(progFiles, "TabTip.exe");
this.keyboardProc = Process.Start(keyboardPath);

但我無法相信這可能是“官方”方式。 如果沒有別的,那么因為沒有干凈的方法來隱藏通過運行TabTip.exe打開的鍵盤(解決方案包括諸如終止進程或發送Esc鍵之類的黑客攻擊)。

實際上,上述 hack 在 Windows 10 周年更新中似乎不再起作用:


有趣的是,我在 Delphi/C++ Builder/VCL 應用程序中看到了相同的行為。 鍵盤不會彈出編輯框( TEdit )。 它確實會彈出組合框 ( TComboBox ) 和密碼模式下的編輯框 ( PasswordChar )。 有趣的是,對於TRichEdit ,與 .NET RichTextBox什么顯着區別,這可能值得研究。

這個(未回答的)問題描述了一個相同的行為:
在編輯框鍵盤中編寫的應用程序 Delphi XE8 touch 不會出現在 Windows 10 中

我已經在這條路上走了幾次,但只能實現taptip.exe選項。 然后通過終止進程關閉窗口。 我還發現,如果您願意,可以通過一些注冊表技巧使鍵盤默認為手寫面板。 但那只能在 Win8 中有效,在 Win10 中失敗。 這是我所做的,以防其他人發現這很有用:

RegistryKey registryKey = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\TabletTip\\1.7");

registryKey?.SetValue("KeyboardLayoutPreference", 0, RegistryValueKind.DWord);
registryKey?.SetValue("LastUsedModalityWasHandwriting", 1, RegistryValueKind.DWord);

Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");

我需要感謝這篇文章的注冊表想法: Windows 8 桌面應用程序:打開 tabtip.exe 到輔助鍵盤(用於數字文本框)

根本原因似乎是 Winforms 的 textBox 不是 AutomationElement,而其余提到的控件(ComboBoxes 等)是。

在這里引用 Markus von und zu Heber 接受的答案

我們在“ Windows 8+ 上的 WPF 應用程序中的文本框的自動觸摸鍵盤”一文中找到了它,但它對於 winforms 也非常有效(甚至更容易!)。 謝謝你,德米特里萊林!

  1. 將 UIAutomationClient.dll 的引用插入到您的項目中

  2. 在應用程序主窗口的表單加載處理程序中,插入以下代碼:

     var asForm = System.Windows.Automation.AutomationElement.FromHandle(this.Handle);

據我所知,啟動osk.exetabtip.exe幾乎是完成這項工作的“標准”方式。 到目前為止,我還沒有找到“官方”解決方案。

但是,如果是我這樣做,我不會終止進程或發送鍵來嘗試關閉鍵盤。 相反,您可以在啟動進程時獲取窗口句柄,並使用它來最小化窗口並將其從任務欄中隱藏。

這里有人得到了窗口句柄只是為了關閉它,但它給了你一個想法: 從 WPF 在屏幕鍵盤上顯示和隱藏 Windows 8

如果你需要我,讓我知道,我會看看我是否能找到時間做一個完整的例子。

正如Ofek Shilon 的回答所暗示的那樣,觸摸鍵盤似乎可以利用UI 自動化


可以使用UIAutomationClient.dll的 UI 自動化實現。

為了將 UI 自動化神奇地注入應用程序,必須觸發程序集內部類UiaCoreApi類初始化程序。

例如,可以通過調用看似無操作來實現這一點:

AutomationElement.FromHandle(IntPtr)(-1)

另一種方法是顯式實現自動化 UI。 為此,為相應的輸入控件實現ITextProvider / IValueProvider接口。

要將接口的實現綁定到控件,請使用lParam = RootObjectId處理WM_GETOBJECT窗口消息

有關實現的示例,請參閱


盡管有趣的是,觸摸鍵盤開箱即用的控件(如組合框或密碼編輯框,請參閱答案)並未實現WM_GETOBJECT / RootObjectId 他們背后一定有不同的機器。

使用 RichTextBox 而不是 TextBox 控件。 RichTextBox 支持觸摸鍵盤,獲得焦點時會自動彈出鍵盤。 (類似於組合框等其他輸入控件)

RichTextBox 還支持與 TextBox 相同的屬性,因此在大多數情況下它應該是一個變化。 (兩個控件都源自 TextBoxBase)

我注意到如果觸摸鍵盤在彈出后被關閉,您可能需要在控件上點擊兩次才能讓它重新彈出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM