本文介绍了在Windows 10周年纪念版中显示触摸键盘(TabTip.exe)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Windows 8和Windows 10周年更新之前,可以通过启动

In Windows 8 and Windows 10 before Anniversary update it was possible to show touch keyboard by starting

C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe

它不再适用于Windows 10周年更新; TabTip.exe进程正在运行,但未显示键盘.

It no longer works in Windows 10 Anniversary update; the TabTip.exe process is running, but the keyboard is not shown.

有没有办法以编程方式显示它?

Is there a way to show it programmatically?

更新

我找到了一种解决方法-假鼠标单击系统任务栏中的触摸键盘图标.这是Delphi中的代码

I found a workaround - fake mouse click on touch keyboard icon in system tray. Here is code in 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, 0, 'TrayNotifyWnd', nil);
    if TrayNotifyWnd > 0 then
    begin
      Result := FindWindowEx(TrayNotifyWnd, 0, '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, 0, $00010001);
end;

更新2

我发现的另一件事是,设置此注册表项会在启动TabTip.exe显示触摸键盘时恢复旧功能

Another thing I found is that setting this registry key restores old functionality when starting TabTip.exe shows touch keyboard

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TabletTip\1.7\EnableDesktopModeAutoInvoke=1

推荐答案

好,我对用户按下系统托盘中的按钮时的资源管理器进行了反向工程.

OK, I reverse engineered what explorer does when the user presses that button in the system tray.

基本上,它创建未记录接口ITipInvocation的实例并调用其Toggle(HWND)方法,并将桌面窗口作为参数传递.顾名思义,该方法根据其当前状态显示或隐藏键盘.

Basically it creates an instance of an undocumented interface ITipInvocation and calls its Toggle(HWND) method, passing desktop window as an argument. As the name suggests, the method either shows or hides the keyboard depending on its current state.

请注意,资源管理器在每次单击按钮时都会创建ITipInvocation的实例.因此,我认为不应缓存该实例.我还注意到,资源管理器从未在获得的实例上调用Release().我对COM不太熟悉,但这看起来像是个错误.

Please note that explorer creates an instance of ITipInvocation on every button click. So I believe the instance should not be cached. I also noticed that explorer never calls Release() on the obtained instance. I'm not too familiar with COM, but this looks like a bug.

我在Windows 8.1,Windows 10和更高版本中对此进行了测试. Windows 10周年纪念版,它可以完美运行.这是C语言中的一个最小示例,显然缺少一些错误检查.

I tested this in Windows 8.1, Windows 10 & Windows 10 Anniversary Edition and it works perfectly. Here's a minimal example in C that obviously lacks some error checks.

#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, 0, 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然后重试.

Update: per @EugeneK comments, I believe that tabtip.exe is the COM server for the COM component in question, so if your code gets REGDB_E_CLASSNOTREG, it should probably run tabtip.exe and try again.

这篇关于在Windows 10周年纪念版中显示触摸键盘(TabTip.exe)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 16:07
查看更多