[英]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 也非常有效(甚至更容易!)。 謝謝你,德米特里萊林!
將 UIAutomationClient.dll 的引用插入到您的項目中
在應用程序主窗口的表單加載處理程序中,插入以下代碼:
var asForm = System.Windows.Automation.AutomationElement.FromHandle(this.Handle);
據我所知,啟動osk.exe
或tabtip.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.