简体   繁体   English

在 Windows 10 周年版中显示触摸键盘 (TabTip.exe)

[英]Show touch keyboard (TabTip.exe) in Windows 10 Anniversary edition

In Windows 8 and Windows 10 before Anniversary update it was possible to show touch keyboard by starting在周年更新之前的 Windows 8 和 Windows 10 中,可以通过启动来显示触摸键盘

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

It no longer works in Windows 10 Anniversary update;它不再适用于 Windows 10 周年更新; the TabTip.exe process is running, but the keyboard is not shown. TabTip.exe进程正在运行,但未显示键盘。

Is there a way to show it programmatically?有没有办法以编程方式显示它?

UPDATE更新

I found a workaround - fake mouse click on touch keyboard icon in system tray.我找到了一种解决方法 - 假鼠标点击系统托盘中的触摸键盘图标。 Here is code in Delphi这是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更新 2

Another thing I found is that setting this registry key restores old functionality when starting TabTip.exe shows touch keyboard我发现的另一件事是,设置此注册表项会在启动 TabTip.exe 时恢复旧功能显示触摸键盘

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.好的,当用户按下系统托盘中的那个按钮时,我对资源管理器的操作进行了逆向工程。

Basically it creates an instance of an undocumented interface ITipInvocation and calls its Toggle(HWND) method, passing desktop window as an argument.基本上,它创建一个未记录的接口ITipInvocation的实例并调用其Toggle(HWND)方法,将桌面窗口作为参数传递。 As the name suggests, the method either shows or hides the keyboard depending on its current state.顾名思义,该方法根据其当前状态显示或隐藏键盘。

Please note that explorer creates an instance of ITipInvocation on every button click.请注意,资源管理器会在每次单击按钮时创建一个ITipInvocation实例。 So I believe the instance should not be cached.所以我相信实例不应该被缓存。 I also noticed that explorer never calls Release() on the obtained instance.我还注意到资源管理器从不在获得的实例上调用Release() I'm not too familiar with COM, but this looks like a bug.我对COM不太熟悉,但这看起来像一个错误。

I tested this in Windows 8.1, Windows 10 & Windows 10 Anniversary Edition and it works perfectly.我在 Windows 8.1、Windows 10 和 Windows 10 周年版中对此进行了测试,它运行良好。 Here's a minimal example in C that obviously lacks some error checks.这是 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, 0, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER, IID_ITipInvocation, (void**)&tip);
    tip->Toggle(GetDesktopWindow());
    tip->Release();
    return 0;
}

Here's the C# version as well:这也是 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();
}

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.更新:根据@EugeneK 的评论,我相信tabtip.exe是相关 COM 组件的 COM 服务器,因此如果您的代码获取REGDB_E_CLASSNOTREG ,它可能应该运行tabtip.exe试。

I had the same problem too.我也有同样的问题。 It took me much time and headache, but Thanks to Alexei and Torvin I finally got it working on Win 10 1709. Visibility check was the difficulty.我花了很多时间和头痛,但感谢 Alexei 和 Torvin,我终于让它在 Win 10 1709 上运行。可见性检查是困难的。 Maybe The OSKlib Nuget could be updated.也许可以更新 OSKlib Nuget。 Let me sum up the complete sulotion (For sure my code has some unnecessary lines now):让我总结一下完整的内容(当然我的代码现在有一些不必要的行):

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;

    }
}

The only solution I've found to work is by sending PostMessage as you've mentioned in answer 1. Here's the C# version of it in case someone needs it.我发现唯一可行的解​​决方案是发送您在答案 1 中提到的 PostMessage。这是它的 C# 版本,以防有人需要它。

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

I detect 4 situations when trying to open Touch Keyboard on Windows 10 Anniversary Update尝试在 Windows 10 周年更新上打开触控键盘时检测到 4 种情况

  1. Keyboard is Visible - when "IPTIP_Main_Window" is present, NOT disabled and IS visible键盘可见 - 当“ IPTIP_Main_Window ”存在时,禁用且可见
  2. Keyboard is not visible - when "IPTIP_Main_Window" is present but disabled键盘不可见 - 当“IPTIP_Main_Window”存在但禁用时
  3. Keyboard is not visible - when "IPTIP_Main_Window" is present but NOT disabled and NOT visible键盘可见 - 当“ IPTIP_Main_Window ”存在但未禁用且不可见时
  4. Keyboard is not visible - when "IPTIP_Main_Window" is NOT present键盘不可见 - 当“IPTIP_Main_Window”存在时

1 - nothing to do 1 - 无事可做

2+3 - activating via COM 2+3 - 通过 COM 激活

4 - most interesting scenario. 4 - 最有趣的场景。 In some devices starting TabTip process opens touch keyboard, on some - not.在某些设备中,启动 TabTip 进程会打开触摸键盘,在某些设备上 - 不是。 So we must start TabTip process, wait for appearing window "IPTIP_Main_Window", check it for visibility and activate it via COM if nessesary.所以我们必须启动 TabTip 进程,等待出现窗口“IPTIP_Main_Window”,检查它的可见性并在必要时通过 COM 激活它。

I make small library for my project, you can use it - osklib我为我的项目制作了一个小库,你可以使用它 - osklib

The following code will always work since it uses latest MS Api以下代码将始终有效,因为它使用最新的 MS Api
I put it into a dll (Needed for a Delphi project) but it is a plain C我把它放到一个 dll 中(需要一个 Delphi 项目),但它是一个普通的 C
Also useful for obtaining the keyboard size and adjusting application layout对于获取键盘大小和调整应用程序布局也很有用

//*******************************************************************
//
// 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;
}

There is still some mystery about how the touch keyboard is set visible by Windows 10 Anniversary Update. Windows 10 周年更新如何将触摸键盘设置为可见仍然存在一些谜团。 I'm actually having the exact same issue and here are the lastest infos i've found :我实际上遇到了完全相同的问题,这是我发现的最新信息:

  • Windows 10 1607 works in two modes : Desktop and Tablet. Windows 10 1607 在两种模式下工作:台式机和平板电脑。 While in Desktop mode, TabTip.exe can be called but won't show.在桌面模式下,可以调用 TabTip.exe 但不会显示。 While in Tablet mode, everything works fine : TabTip.exe shows itself when called.在平板电脑模式下,一切正常:TabTip.exe 在调用时会显示自己。 So a 100% working workaround is to set your computer in Tablet Mode but who wants his desktop/laptop to work in tablet mode ?因此,100% 的解决方法是将您的计算机设置为平板电脑模式,但谁希望他的台式机/笔记本电脑在平板电脑模式下工作? Not me anyway !反正不是我!

  • You can use the " EnableDesktopModeAutoInvoke " Key (HKCU, DWORD set to 1) and on some computers running 1607 it worked great while in Desktop Mode.您可以使用“ EnableDesktopModeAutoInvoke ”键(HKCU,DWORD 设置为 1),并且在某些运行 1607 的计算机上,它在桌面模式下运行良好。 But for some unknown reasons, it is not working on my HP touchpad.但由于某些未知原因,它无法在我的 HP 触摸板上工作。

Please note that this registry value is the "Show touch keyboard on desktop mode if there is no attached keyboard" option in Windows parameters > touch请注意,此注册表值是 Windows 参数 > 触摸中的“如果没有附加键盘,则在桌面模式下显示触摸键盘”选项

  • You can use Torvin's code to show TabTip.exe (as mentioned TabTip.exe should be running when you do the COM stuff), it is working fine on some computers running 1607 (including my HP touchpad ! yay !) But it will do nothing on some others comps with the same windows Build.您可以使用 Torvin 的代码来显示 TabTip.exe(正如提到的那样,当您执行 COM 操作时 TabTip.exe 应该运行),它在一些运行 1607 的计算机上运行良好(包括我的 HP 触摸板!耶!)但它什么也不做在其他一些具有相同 Windows 构建的组合上。

So far tested on 4 different computers and i'm unable to get something working fine on all...到目前为止,在 4 台不同的计算机上进行了测试,我无法让所有的东西都能正常工作......

The problem seems to be with setting of Windows OS.问题似乎与 Windows 操作系统的设置有关。 I have faced same issue with the app I was developing.我正在开发的应用程序遇到了同样的问题。 With Windows 8 and 10 (before update) code that called keyboard worked fine, but after update failed to work.使用 Windows 8 和 10(更新前)调用键盘的代码工作正常,但更新后无法工作。 After reading this article , I did following:读完这篇文章后,我做了以下事情:

  1. Pressed Win+I to open the Settings app按 Win+I 打开设置应用

  2. Clicked on Devices > Typing点击设备>打字

  3. Turned " Automatically show the touch keyboard in windowed apps when there's no keyboard attached to your device " ON.开启“当您的设备没有连接键盘时,在窗口应用程序中自动显示触摸键盘”。

    Right after that keyboard starting showing up in Windows 10 also.紧接着该键盘也开始出现在 Windows 10 中。

在您的控件中实现 IValueProvider/ITextProvider 是实现此目的的正确方法,如下所述: https ://stackoverflow.com/a/43886052/1184950

I tried multiple things that did not work.我尝试了多种不起作用的方法。 But I discovered that I can use the Shortcut Keys Windows/Ctrl/O to open the On Screen Key Board.但我发现我可以使用快捷键 Windows/Ctrl/O 打开屏幕键盘。
Also there is a Nuget package: Input Simulator by Michael Noonan.还有一个 Nuget 包:Michael Noonan 的 Input Simulator。

If you install the InputSimulator NuGet package in your Winforms project - then add code like this to an event, like a button:如果您在 Winforms 项目中安装 InputSimulator NuGet 包 - 然后将这样的代码添加到事件中,例如按钮:

private void button1_Click(object sender, EventArgs e)
{
    var simu = new InputSimulator();
    simu.Keyboard.ModifiedKeyStroke(new[] { VirtualKeyCode.LWIN, VirtualKeyCode.CONTROL }, VirtualKeyCode.VK_O);
}

You will also need to add these using statements:您还需要添加这些 using 语句:

using WindowsInput;
using WindowsInput.Native;

Run your app and the button will display the keyboard and also hit it again and it will remove it.运行您的应用程序,该按钮将显示键盘并再次点击它并将其删除。

I am on Windows 10 and vs 2019.我在 Windows 10 和 vs 2019 上。

Set oShell = CreateObject("WScript.Shell")
oShell.AppActivate "Program Manager"
oShell.Run "tabtip.exe", 0, true
oShell.SendKeys "%{TAB}"

[HKEY_CURRENT_USER\SOFTWARE\Microsoft\TabletTip\1.7] "EnableDesktopModeAutoInvoke"=dword:00000001 [HKEY_CURRENT_USER\SOFTWARE\Microsoft\TabletTip\1.7] "EnableDesktopModeAutoInvoke"=dword:00000001

Use this method:使用此方法:

  1. Create osk.bat file and save it under your program folder ie.创建 osk.bat 文件并将其保存在您的程序文件夹下,即。 C:\My Software\osk.bat

  2. Type in this osk.bat the following cmd:在这个 osk.bat 中输入以下 cmd:

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

  3. Use Windows Script to run this bat file使用 Windows 脚本运行此 bat 文件

    oWSH = CREATEOBJECT("wscript.shell")

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

In Win10 Ver 1803, DesktopMode, there is no reliable way to Win10 Ver 1803,DesktopMode,没有可靠的方法
toggle the "Touch Keyboard" on|off [ ITipInvocation.Toggle() ];打开|关闭“触摸键盘”[ ITipInvocation.Toggle() ];
nor can you reliably discover if it's "up" ( on screen )你也不能可靠地发现它是否“向上”(在屏幕上)
[ IFrameworkInputPane.Location() ]; [ IFrameworkInputPane.Location() ]; both routines fail randomly .这两个例程都随机失败。

Instead, ensure that "TabTIP.EXE" and "....InputApp.EXE"相反,请确保“TabTIP.EXE”和“....InputApp.EXE”
only run when the keyboard is "up" ( on screen ).仅在键盘“向上”(在屏幕上)时运行。

To toggle the keyboard on and off ( from X.CPP in Jeff-Relf.Me/X.ZIP ):要打开和关闭键盘(来自 Jeff-Relf.Me/X.ZIP 中的 X.CPP):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Windows Vista / 7中以编程方式(TabTip.exe)控制文本输入面板 - How do I control the text input panel programmatically (TabTip.exe) in Windows Vista/7 更改EnableDesktopModeAutoInvoke注册表值并使TabTip.exe接受更改 - Change EnableDesktopModeAutoInvoke registry value and make TabTip.exe to accept change 在桌面下打开和关闭Windows 8触摸键盘tabtip - Open and close Windows 8 touch keyboard tabtip under desktop Windows 10周年更新中的Windows容器无法正常工作 - Windows containers on Windows 10 Anniversary Update are not working 确定Windows 10 Touch键盘是可见还是隐藏 - Determine if Windows 10 Touch Keyboard is Visible or Hidden Windows 8 Metro应用程序上的触摸键盘显示属性 - touch keyboard show property on windows 8 metro app 使用 powershell 脚本自动启用 Windows 10 触摸键盘和全键盘 - Automatically enable Windows 10 touch keyboard & full keyboard with powershell script 在输入焦点上打开 Windows 10 触摸键盘的数字版本 - Open numeric version of windows 10 touch keyboard on input focus Windows窗体-触摸文本框时显示Windows 8键盘 - windows form - show windows 8 keyboard when touch textbox Unity3D - 检测 Windows 10 周年(版本号) - Unity3D - Detect if Windows 10 Anniversary (version number)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM