it-swarm.com.de

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

In Windows 8 und Windows 10 vor dem Anniversary-Update war es möglich, die Touch-Tastatur beim Start anzuzeigen 

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 programmgesteuert anzuzeigen?

UPDATE

Ich habe eine Problemumgehung gefunden - einen falschen Mausklick auf das 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 gefunden habe, ist, dass das Setzen dieses Registrierungsschlüssels die alte Funktionalität wiederherstellt, wenn TabTip.exe die Berührungs-Tastatur zeigt

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

OK, ich habe das, was Explorer tut, rückgängig gemacht, wenn der Benutzer diese Taste in der Taskleiste drückt.

Im Grunde erstellt es eine Instanz einer undokumentierten Schnittstelle ITipInvocation und ruft die Toggle(HWND)-Methode auf, wobei das Desktopfenster als Argument übergeben wird. Wie der Name vermuten lässt, zeigt oder versteckt die Methode die Tastatur je nach aktuellem Status. 

Bitte beachten Sie dass der Explorer bei jedem Klicken der Schaltfläche eine Instanz von ITipInvocation erstellt. Ich glaube also, dass die Instanz nicht zwischengespeichert werden sollte. Ich habe auch bemerkt, dass der Explorer niemals Release() für die erhaltene Instanz aufruft. Ich bin nicht so vertraut mit COM, aber das sieht nach einem Fehler aus.

Ich habe dies in Windows 8.1, Windows 10 und Windows 10 Anniversary Edition getestet und funktioniert einwandfrei. Hier ist ein minimales Beispiel in C, dem offensichtlich einige Fehlerprüfungen fehlen.

#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;
}

Hier ist auch die C # -Version:

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();
}

Update: per @EugeneK-Kommentare. Ich glaube, dass tabtip.exe der COM-Server für die betreffende COM-Komponente ist. Wenn Ihr Code REGDB_E_CLASSNOTREG erhält, sollte er tabtip.exe wahrscheinlich ausführen und es erneut versuchen.

21
torvin

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

[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,
}
5
mikesl

Ich hatte auch das gleiche Problem. Es hat mir viel Zeit und Kopfschmerzen gekostet, aber dank Alexei und Torvin konnte ich endlich Win 10 1709 zum Laufen bringen. Sichtprüfung war die Schwierigkeit. Vielleicht könnte das OSKlib-Nuget aktualisiert werden. Lassen Sie mich die vollständige Zusammenfassung zusammenfassen (Natürlich hat mein Code 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;

    }
}
4
lama

Ich entdecke 4 Situationen, wenn ich versuche, die Touch-Tastatur unter Windows 10 Anniversary Update zu öffnen

  1. Tastatur ist sichtbar - wenn "IPTIP_Main_Window" vorhanden ist, NICHT deaktiviert ist und sichtbar ist
  2. Tastatur ist nicht sichtbar - wenn "IPTIP_Main_Window" vorhanden ist, aber deaktiviert ist
  3. Tastatur ist nicht sichtbar - wenn "IPTIP_Main_Window" vorhanden ist, aber NICHT deaktiviert ist und NICHT sichtbar ist
  4. Tastatur ist nicht sichtbar - wenn "IPTIP_Main_Window" NICHT vorhanden ist

1 - nichts zu tun

2 + 3 - Aktivierung über COM

4 - interessantestes Szenario. Bei einigen Geräten wird beim Starten des TabTip-Prozesses die Touch-Tastatur geöffnet, bei einigen nicht. Wir müssen also den TabTip-Prozess starten, auf das erscheinende Fenster "IPTIP_Main_Window" warten, es auf Sichtbarkeit prüfen und falls nötig über COM aktivieren.

Ich mache eine kleine Bibliothek für mein Projekt, Sie können es verwenden - osklib

4

Es ist immer noch ein Rätsel, wie die Touch-Tastatur durch das Windows 10 Anniversary Update sichtbar gemacht wird. Ich habe genau das gleiche Problem und hier sind die neuesten Infos, die ich gefunden habe:

  • Windows 10 1607 arbeitet in zwei Modi: Desktop und Tablet. Im Desktop-Modus kann TabTip.exe aufgerufen werden, wird jedoch nicht angezeigt. Im Tablet-Modus funktioniert alles einwandfrei: TabTip.exe zeigt sich beim Aufruf. Eine 100% ige Problemumgehung besteht darin, Ihren Computer in den Tablet-Modus zu versetzen. Wer möchte jedoch, dass sein Desktop/Laptop im Tablet-Modus arbeitet? Nicht ich sowieso!

  • Sie können die Taste "EnableDesktopModeAutoInvoke" (HKCU, DWORD auf 1) verwenden. Auf einigen Computern, auf denen 1607 ausgeführt wird, hat es im Desktop-Modus hervorragend funktioniert. Aus unbekannten Gründen funktioniert es jedoch 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 ist> touch  

  • Sie können den Code von Torvin verwenden, um TabTip.exe anzuzeigen (wie bereits erwähnt, sollte TabTip.exe ausgeführt werden, wenn Sie den COM-Kram erledigen). Auf einigen Computern mit 1607 (einschließlich meines HP-Touchpads! Yay!) Funktioniert der Code einwandfrei Bei einigen anderen Comps mit demselben Windows-Build.

Bis jetzt auf 4 verschiedenen Computern getestet und ich kann nicht, dass irgendetwas bei allen funktioniert ...

4
Usul

Die Implementierung des IValueProvider/ITextProviders in Ihrem Steuerelement ist ein korrekter Weg, um dies zu erreichen, wie hier beschrieben: https://stackoverflow.com/a/43886052/1184950

3
tombam

Das Problem scheint bei der Einstellung des Windows-Betriebssystems zu liegen. Ich habe mit der App, die ich entwickelt habe, das gleiche Problem. Unter Windows 8 und 10 (vor dem Update) funktionierte der Code mit der Tastatur einwandfrei, aber nach dem Update funktionierte dies nicht. Nachdem ich diesen Artikel gelesen habe, habe ich folgendes gemacht:

  1. Drücken Sie Win + I, um die App Einstellungen zu öffnen

  2. Klicken Sie auf Geräte> Eingabe 

  3. Deaktiviert "Zeigt die Touch-Tastatur automatisch in Anwendungen mit Fenstern an, wenn an Ihrem Gerät keine Tastatur angeschlossen ist".

    Gleich danach erscheint die Tastatur auch in Windows 10.

3
user3480038

Der folgende Code funktioniert immer, da er die neueste MS-API verwendet
Ich habe es in eine DLL (Erforderlich für ein Delphi-Projekt), aber es ist ein einfaches C.
Auch nützlich, um die Tastaturgröße zu erhalten und das Layout der Anwendung 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;
}
2
Sevast

Verwenden Sie diese Methode:

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

  2. Tippe in diese osk.bat den folgenden cmd 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.)

0
Vinny