在Windows 8和Windows 10周年纪念更新之前,可以通过启动来显示触摸键盘
C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe
它不再适用于Windows 10周年纪念更新; TabTip.exe进程正在运行,但键盘未显示。
有没有办法以编程方式显示?
UPDATE
我发现一个解决方法 – 假鼠标点击系统托盘中的触摸键盘图标。这里是Delphi中的代码
// Find tray icon window function FindTrayButtonWindow: THandle; var ShellTrayWnd: THandle; TrayNotifyWnd: THandle; begin Result := 0; ShellTrayWnd := FindWindow('Shell_TrayWnd',nil); if ShellTrayWnd > 0 then begin TrayNotifyWnd := FindWindowEx(ShellTrayWnd,'TrayNotifyWnd',nil); if TrayNotifyWnd > 0 then begin Result := FindWindowEx(TrayNotifyWnd,'TIPBand',nil); end; end; end; // Post mouse click messages to it TrayButtonWindow := FindTrayButtonWindow; if TrayButtonWindow > 0 then begin PostMessage(TrayButtonWindow,WM_LBUTTONDOWN,MK_LBUTTON,$00010001); PostMessage(TrayButtonWindow,WM_LBUTTONUP,$00010001); end;
更新2
我发现另一件事是,当启动TabTip.exe显示触摸键盘时,设置此注册表项可恢复旧功能
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TabletTip\1.7\EnableDesktopModeAutoInvoke=1
好的,当用户按下系统托盘中的那个按钮时,我反向设计了什么浏览器。
基本上它创建一个未记录的接口ITipInvocation的实例,并调用其Toggle(HWND)方法,将桌面窗口作为参数传递。顾名思义,该方法根据其当前状态显示或隐藏键盘。
请注意,浏览器会在每个按钮点击创建一个ITipInvocation实例。所以我相信实例不应该被缓存。我也注意到,资源管理器从未在获取的实例上调用Release()。我不太熟悉COM,但这看起来像一个bug。
我在Windows 8.1,Windows 10和Windows 10周年纪念版,它的工作完美。这是C中的一个最小例子,显然没有一些错误检查。
#include <initguid.h> #include <Objbase.h> #pragma hdrstop // 4ce576fa-83dc-4F88-951c-9d0782b4e376 DEFINE_GUID(CLSID_UIHostNoLaunch,0x4CE576FA,0x83DC,0x4f88,0x95,0x1C,0x9D,0x07,0x82,0xB4,0xE3,0x76); // 37c994e7_432b_4834_a2f7_dce1f13b834b DEFINE_GUID(IID_ITipInvocation,0x37c994e7,0x432b,0x4834,0xa2,0xf7,0xdc,0xe1,0xf1,0x3b,0x83,0x4b); struct ITipInvocation : IUnknown { virtual HRESULT STDMETHODCALLTYPE Toggle(HWND wnd) = 0; }; int WinMain(HINSTANCE hInst,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { HRESULT hr; hr = CoInitialize(0); ITipInvocation* tip; hr = CoCreateInstance(CLSID_UIHostNoLaunch,CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER,IID_ITipInvocation,(void**)&tip); tip->Toggle(GetDesktopWindow()); tip->Release(); return 0; }
这是C#版本:
class Program { static void Main(string[] args) { var uiHostNoLaunch = new UIHostNoLaunch(); var tipInvocation = (ITipInvocation)uiHostNoLaunch; tipInvocation.Toggle(GetDesktopWindow()); Marshal.ReleaseComObject(uiHostNoLaunch); } [ComImport,Guid("4ce576fa-83dc-4F88-951c-9d0782b4e376")] class UIHostNoLaunch { } [ComImport,Guid("37c994e7-432b-4834-a2f7-dce1f13b834b")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface ITipInvocation { void Toggle(IntPtr hwnd); } [DllImport("user32.dll",SetLastError = false)] static extern IntPtr GetDesktopWindow(); }
更新:每个@EugeneK注释,我相信tabtip.exe是COM组件的COM服务器,所以如果您的代码获得REGDB_E_CLASSNOTREG,它应该可能运行tabtip.exe并重试。