Zeigen Sie Touch-Tastatur(TabTip.exe) in Windows 10 Anniversary Edition




winapi windows-10 (7)

Das Problem scheint mit der Einstellung von Windows OS zu sein. Ich habe das gleiche Problem mit der App, die ich entwickelt habe, konfrontiert. Mit Windows 8 und 10 (vor dem Update) funktionierte Code, der die Tastatur ansprach, aber nach dem Update fehlgeschlagen zu arbeiten. Nachdem ich diesen Artikel gelesen habe , habe ich folgendes getan:

  1. Win + I gedrückt, um die Einstellungen App zu öffnen

  2. Auf Geräte> Tippen geklickt

  3. " Die Touch-Tastatur in Anwendungen mit Fenster automatisch anzeigen, wenn keine Tastatur an Ihrem Gerät angeschlossen ist ".

    Direkt danach erscheint die Tastatur in Windows 10.

In Windows 8 und Windows 10 vor dem Jahrestagupdate war es möglich, die Touch-Tastatur beim Start zu zeigen

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

Es funktioniert nicht mehr in Windows 10 Anniversary Update; Der TabTip.exe Prozess wird ausgeführt, aber die Tastatur wird nicht angezeigt.

Gibt es eine Möglichkeit, es programmatisch zu zeigen?

AKTUALISIEREN

Ich habe einen Workaround gefunden - gefälschte Mausklick auf Touch-Tastatur-Symbol in der Taskleiste. Hier ist 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;

UPDATE 2

Eine andere Sache, die ich fand, ist, dass das Setzen dieses Registrierungsschlüssels alte Funktionalität wiederherstellt, wenn TabTip.exe gestartet wird, berühre Tastatur

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

Der folgende Code wird immer funktionieren, da er den letzten MS Api verwendet
Ich lege es in eine DLL (benötigt für ein Delphi-Projekt), aber es ist ein einfaches C
Auch nützlich, um die Tastaturgröße zu erhalten und das Anwendungslayout anzupassen

//*******************************************************************
//
// RETURNS KEYBOARD RECTANGLE OR EMPTY ONE IF KEYBOARD IS NOT VISIBLE
//
//*******************************************************************
RECT __stdcall  GetKeyboardRect()
{
    IFrameworkInputPane *inputPane = NULL;
    RECT prcInputPaneScreenLocation = { 0,0,0,0 };
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);    
    if (SUCCEEDED(hr))
    {
        hr = CoCreateInstance(CLSID_FrameworkInputPane, NULL, CLSCTX_INPROC_SERVER, IID_IFrameworkInputPane, (LPVOID*)&inputPane);
        if (SUCCEEDED(hr))
        {
            hr=inputPane->Location(&prcInputPaneScreenLocation);
            if (!SUCCEEDED(hr))
            {                   
            }
            inputPane->Release();
        }
    }       
    CoUninitialize();   
    return prcInputPaneScreenLocation;
}

Die einzige Lösung, die ich gefunden habe, ist das Senden von PostMessage, wie Sie in Antwort 1 erwähnt haben. Hier ist die C # -Version, falls jemand sie benötigt.

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern IntPtr FindWindow(string sClassName, string sAppName);

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle); 

[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
    static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

var trayWnd = FindWindow("Shell_TrayWnd", null);
var nullIntPtr = new IntPtr(0);

if (trayWnd != nullIntPtr)
{
    var trayNotifyWnd = FindWindowEx(trayWnd, nullIntPtr, "TrayNotifyWnd", null);
    if (trayNotifyWnd != nullIntPtr)
    {
        var tIPBandWnd = FindWindowEx(trayNotifyWnd, nullIntPtr, "TIPBand", null);

        if (tIPBandWnd != nullIntPtr)
        {
            PostMessage(tIPBandWnd, (UInt32)WMessages.WM_LBUTTONDOWN, 1, 65537);
            PostMessage(tIPBandWnd, (UInt32)WMessages.WM_LBUTTONUP, 1, 65537);
        }
    }
}


public enum WMessages : int
{
    WM_LBUTTONDOWN = 0x201,
    WM_LBUTTONUP = 0x202,
    WM_KEYDOWN = 0x100,
    WM_KEYUP = 0x101,
    WH_KEYBOARD_LL = 13,
    WH_MOUSE_LL = 14,
}

Es gibt noch einige Rätsel darüber, wie die Touch-Tastatur durch Windows 10 Anniversary Update sichtbar gemacht wird. Ich habe genau das gleiche Problem und hier sind die neuesten Informationen, die ich gefunden habe:

  • Windows 10 1607 funktioniert in zwei Modi: Desktop und Tablet. Im Desktop-Modus kann TabTip.exe aufgerufen werden, wird aber nicht angezeigt. Im Tablet-Modus funktioniert alles einwandfrei: TabTip.exe zeigt sich beim Aufruf. Ein Workaround, der zu 100% funktioniert, besteht darin, den Computer im Tablet-Modus einzurichten, aber er möchte, dass sein Desktop / Laptop im Tablet-Modus funktioniert. Ich jedenfalls nicht!

  • Sie können den Schlüssel " EnableDesktopModeAutoInvoke " (HKCU, DWORD auf 1 gesetzt) ​​verwenden und auf einigen Computern, auf denen 1607 ausgeführt wird, hat es im Desktop-Modus funktioniert. Aber aus unbekannten Gründen funktioniert es nicht auf meinem HP Touchpad.

Bitte beachten Sie, dass dieser Registrierungswert die Option "Touch-Tastatur im Desktop-Modus anzeigen, wenn keine Tastatur angeschlossen ist" in den Windows-Parametern> berühren

  • Sie können Torvins Code verwenden, um TabTip.exe anzuzeigen (wie erwähnt TabTip.exe sollte ausgeführt werden, wenn Sie die COM-Sachen tun), es funktioniert gut auf einigen Computern mit 1607 (einschließlich meiner HP Touchpad! Yay!) Aber es wird nichts tun Bei einigen anderen Comps mit dem gleichen Windows Build.

Bisher getestet auf 4 verschiedenen Computern und ich kann nichts auf allen ...


Ich hatte das gleiche Problem. Ich brauchte viel Zeit und Kopfschmerzen, aber Dank Alexei und Torvin konnte ich endlich mit Win 10 1709 arbeiten. Sichtkontrolle war die Schwierigkeit. Vielleicht könnte das OSKlib Nuget aktualisiert werden. Lassen Sie mich die komplette Lösung zusammenfassen (Mein Code enthält jetzt einige unnötige Zeilen):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel;

using Osklib.Interop;
using System.Runtime.InteropServices;
using System.Threading;

namespace OSK
{
    public static class OnScreenKeyboard
    {
        static OnScreenKeyboard()
        {
            var version = Environment.OSVersion.Version;
            switch (version.Major)
            {
                case 6:
                    switch (version.Minor)
                    {
                        case 2:
                            // Windows 10 (ok)
                            break;
                    }
                    break;
                default:
                    break;
            }
        }

        private static void StartTabTip()
        {
            var p = Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
            int handle = 0;
            while ((handle = NativeMethods.FindWindow("IPTIP_Main_Window", "")) <= 0)
            {
                Thread.Sleep(100);
            }
        }

        public static void ToggleVisibility()
        {
            var type = Type.GetTypeFromCLSID(Guid.Parse("4ce576fa-83dc-4F88-951c-9d0782b4e376"));
            var instance = (ITipInvocation)Activator.CreateInstance(type);
            instance.Toggle(NativeMethods.GetDesktopWindow());
            Marshal.ReleaseComObject(instance);
        }

        public static void Show()
        {
            int handle = NativeMethods.FindWindow("IPTIP_Main_Window", "");
            if (handle <= 0) // nothing found
            {
                StartTabTip();                
                Thread.Sleep(100);                
            }
            // on some devices starting TabTip don't show keyboard, on some does  ¯\_(ツ)_/¯
            if (!IsOpen())
            {
                ToggleVisibility();
            }
        }

        public static void Hide()
        {
            if (IsOpen())
            {
                ToggleVisibility();
            }
        }        


        public static bool Close()
        {
            // find it
            int handle = NativeMethods.FindWindow("IPTIP_Main_Window", "");
            bool active = handle > 0;
            if (active)
            {
                // don't check style - just close
                NativeMethods.SendMessage(handle, NativeMethods.WM_SYSCOMMAND, NativeMethods.SC_CLOSE, 0);
            }
            return active;
        }

        public static bool IsOpen()
        {
            return GetIsOpen1709() ?? GetIsOpenLegacy();
        }


        [DllImport("user32.dll", SetLastError = false)]
        private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr after, string className, string title = null);

        [DllImport("user32.dll", SetLastError = false)]
        private static extern uint GetWindowLong(IntPtr wnd, int index);

        private static bool? GetIsOpen1709()
        {
            // if there is a top-level window - the keyboard is closed
            var wnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, WindowClass1709, WindowCaption1709);
            if (wnd != IntPtr.Zero)
                return false;

            var parent = IntPtr.Zero;
            for (;;)
            {
                parent = FindWindowEx(IntPtr.Zero, parent, WindowParentClass1709);
                if (parent == IntPtr.Zero)
                    return null; // no more windows, keyboard state is unknown

                // if it's a child of a WindowParentClass1709 window - the keyboard is open
                wnd = FindWindowEx(parent, IntPtr.Zero, WindowClass1709, WindowCaption1709);
                if (wnd != IntPtr.Zero)
                    return true;
            }
        }

        private static bool GetIsOpenLegacy()
        {
            var wnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, WindowClass);
            if (wnd == IntPtr.Zero)
                return false;

            var style = GetWindowStyle(wnd);
            return style.HasFlag(WindowStyle.Visible)
                && !style.HasFlag(WindowStyle.Disabled);
        }

        private const string WindowClass = "IPTip_Main_Window";
        private const string WindowParentClass1709 = "ApplicationFrameWindow";
        private const string WindowClass1709 = "Windows.UI.Core.CoreWindow";
        private const string WindowCaption1709 = "Microsoft Text Input Application";

        private enum WindowStyle : uint
        {
            Disabled = 0x08000000,
            Visible = 0x10000000,
        }

        private static WindowStyle GetWindowStyle(IntPtr wnd)
        {
            return (WindowStyle)GetWindowLong(wnd, -16);
        }

    }


    [ComImport]
    [Guid("37c994e7-432b-4834-a2f7-dce1f13b834b")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface ITipInvocation
    {
        void Toggle(IntPtr hwnd);
    }

    internal static class NativeMethods
    {
        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        internal static extern int FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "SendMessage")]
        internal static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow", SetLastError = false)]
        internal static extern IntPtr GetDesktopWindow();

        [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
        internal static extern int GetWindowLong(int hWnd, int nIndex);

        internal const int GWL_STYLE = -16;
        internal const int GWL_EXSTYLE = -20;        
        internal const int WM_SYSCOMMAND = 0x0112;
        internal const int SC_CLOSE = 0xF060;

        internal const int WS_DISABLED = 0x08000000;

        internal const int WS_VISIBLE = 0x10000000;

    }
}

In Win10 Ver 1803, DesktopMode gibt es keinen zuverlässigen Weg
Schalten Sie die "Touch-Tastatur" ein | aus [ITipInvocation.Toggle ()];
noch können Sie zuverlässig feststellen, ob es "oben" ist (auf dem Bildschirm)
[IFrameworkInputPane.Location ()]; beide Routinen schlagen zufällig fehl.

Stellen Sie stattdessen sicher, dass "TabTIP.EXE" und ".... InputApp.EXE"
nur ausgeführt, wenn die Tastatur "hoch" ist (auf dem Bildschirm).

Um die Tastatur ein- und auszuschalten (von X.CPP in Jeff-Relf.Me/X.ZIP):

if ( WM == WM_HOTKEY && C == 'K' ) {

  //  A mouse button takes me here.  Jeff-Relf.Me/g600.PNG

  if ( KillProc = 1, Running( L"TabTIP.EXE" ), KillProc = 1, Running( 
      L"WindowsInternal.ComposableShell.Experiences.TextInput.InputApp.EXE"
  ) )  

    //  The keyboard was _On_ ( i.e. its processes were running ), 
    //  so it was "turned _Off_" (killed); and we're done.

    goto Done ;

  //  The keyboard was _Off_ ( i.e. no running processes ). 
  //  Turn it _On_: 

  Launch( L"%CommonProgramFiles%/microsoft shared/ink/TabTIP.EXE" );
  Sleep(99);

  static const GUID CLSID_UIHostNoLaunch = {  0x4CE576FA, 0x83DC,
    0x4f88,  0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76 };
  static const GUID IID_ITipInvocation = {  0x37c994e7, 0x432b,
    0x4834, 0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b };
  static struct ITipInvocation : IUnknown {  virtual HRESULT 
    STDMETHODCALLTYPE  Toggle( HWND wnd ) = 0 ;  }  * Tog ;

  Tog = 0, CoCreateInstance( CLSID_UIHostNoLaunch, 0, CLSCTX_INPROC_HANDLER
    | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**) & Tog );

  //  Firefox and Chrome need this: 

  Tog ? Tog->Toggle( GetDesktopWindow() ), Tog->Release() : 0 ;    }
- - - - - - - - - - - - -
//  To get the process list, and kill stuff: 
#include <tlhelp32.H>

      int  KillProc ;
int Running( wchar * EXE ) {  int  Found ;  HANDLE  PIDs, aProc ;
  PROCESSENTRY32  aPID = { sizeof aPID };
  PIDs = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
  Process32First( PIDs, &aPID );
  while ( Found = !strCmpI( aPID.szExeFile, EXE ),
    KillProc && Found && ( 
      aProc = OpenProcess( PROCESS_TERMINATE, 0, aPID.th32ProcessID ),
      aProc ? TerminateProcess( aProc, 9 ), CloseHandle( aProc ) : 0 ),
    !Found && Process32Next( PIDs, &aPID ) );

  KillProc = 0, CloseHandle( PIDs );  return  Found ;   }


Launch( wchar * Cmd ) {  wchar _Cmd[333];  static PROCESS_INFORMATION Stat ;
  static STARTUPINFO SU = { sizeof SU };
  SetEnvironmentVariable( L"__compat_layer", L"RunAsInvoker" );
  ExpandEnvironmentStrings( Cmd, _Cmd, 333 ), Cmd = _Cmd ;
  if ( CreateProcess( 0, Cmd, 0,0,1,0,0,0, &SU , &Stat ) )
    CloseHandle( Stat.hProcess ), CloseHandle( Stat.hThread );  }

//  CoInitialize(0);

Verwenden Sie diese Methode:

  1. Erstellen Sie die Datei osk.bat und speichern Sie sie unter Ihrem Programmordner, d. C:\My Software\osk.bat

  2. Geben Sie diese osk.bat den folgenden Befehl ein:

    "C:\Program Files\Common Files\Microsoft Shared\Ink\Tabtip.exe"

  3. Verwenden Sie Windows Script, um diese Bat-Datei auszuführen

    oWSH = CREATEOBJECT("wscript.shell")

    oWSH.Run("osk.bat", 0, .T.)





windows-10-desktop