zoukankan      html  css  js  c++  java
  • c# 弹出虚拟键盘关闭虚拟键盘(适用win10、win7)

    using System;
    using System.Diagnostics;
    using System.Management;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Threading;
    
    namespace test
    {
        /// <summary>
        ///     虚拟键盘管理类
        /// </summary>
        public class VirtualKeyboardHelper
        {
            private const uint WS_VISIBLE = 0x10000000;
            private const int GWL_STYLE = -16;
            private const int WM_SYSCOMMAND = 0x0112;
            private const uint SC_CLOSE = 0xF060;
            private const int WS_DISABLED = 0x08000000;
            private const int DWMWA_CLOAKED = 14;
    
            private const string ApplicationFrameHostClassName = "ApplicationFrameWindow";
            private const string CoreWindowClassName = "Windows.UI.Core.CoreWindow";
    
            private const string TextInputApplicationCaption = "Microsoft Text Input Application";
    
    
            /// <summary>
            ///     win10 虚拟键盘路径
            /// </summary>
            private const string Win10TabTipPath = @"C:Program FilesCommon Filesmicrosoft sharedinkTabTip.exe";
    
            /// <summary>
            ///     win7 虚拟键盘路径
            /// </summary>
            private const string Win7OskPath = @"C:WINDOWSsystem32osk.exe";
    
            /// <summary>
            ///     虚拟键盘 窗口名称
            /// </summary>
            private const string TabTipWindowClassName = "IPTIP_Main_Window";
    
            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
            [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
            private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass,
                string lpszWindow);
    
    
            [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
            private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    
            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            private static extern bool PostMessage(IntPtr hWnd, int msg, uint wParam, uint lParam);
    
    
            [DllImport("kernel32.dll", SetLastError = true)]
            private static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
    
            [DllImport("kernel32.dll", SetLastError = true)]
            private static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);
    
    
            [DllImport("user32.dll", EntryPoint = "GetDesktopWindow", SetLastError = false)]
            private static extern IntPtr GetDesktopWindow();
    
            [DllImport("dwmapi.dll", EntryPoint = "DwmGetWindowAttribute")]
            private static extern int DwmGetWindowAttribute(IntPtr intPtr, int dwAttribute, out int pvAttribute,
                uint cbAttribute);
    
    
    
            /// <summary>
            /// 判断键盘是否连接
            /// </summary>
            /// <returns></returns>
            public static bool IsKeyboardAttached()
            {
                try
                {
                    ManagementObjectSearcher searcher =
                        new ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_Keyboard");
    
                    int devCount = 0;
    
                    foreach (ManagementObject obj in searcher.Get())
                    {
                        if (obj["Status"].ToString().Contains("OK")) // if device is ready
                        {
                            //surface测试时发现,HID设备,不是键盘,比较特殊
                            if (!obj["Description"].ToString().Contains("HID Keyboard Device"))
                            {
                                devCount++;
                            }
                        }
                    }
    
                    return devCount > 0;
                }
                catch (Exception)
                {
                    return false;
                }
            }
    
            /// <summary>
            ///     打开虚拟键盘,目前支持win7 64位,win10 64位,exe编译为x86。
            /// </summary>
            public static void ShowVirtualKeyboard()
            {
                //+------------------------------------------------------------------------------+
                //|                    |   PlatformID    |   Major version   |   Minor version   |
                //+------------------------------------------------------------------------------+
                //| Windows 95         |  Win32Windows   |         4         |          0        |
                //| Windows 98         |  Win32Windows   |         4         |         10        |
                //| Windows Me         |  Win32Windows   |         4         |         90        |
                //| Windows NT 4.0     |  Win32NT        |         4         |          0        |
                //| Windows 2000       |  Win32NT        |         5         |          0        |
                //| Windows XP         |  Win32NT        |         5         |          1        |
                //| Windows 2003       |  Win32NT        |         5         |          2        |
                //| Windows Vista      |  Win32NT        |         6         |          0        |
                //| Windows 2008       |  Win32NT        |         6         |          0        |
                //| Windows 7          |  Win32NT        |         6         |          1        |
                //| Windows 2008 R2    |  Win32NT        |         6         |          1        |
                //| Windows 8          |  Win32NT        |         6         |          2        |
                //| Windows 8.1        |  Win32NT        |         6         |          3        |
                //+------------------------------------------------------------------------------+
                //| Windows 10         |  Win32NT        |        10         |          0        |
    
                try
                {
                    var isWin7 = Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1;
                    var isWin8OrWin10 =
                        Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 2;
                    var isWin10 = Environment.OSVersion.Version.Major == 10 && Environment.OSVersion.Version.Minor == 0;
                    if (isWin7)
                    {
                        //win7
                        ShowWin7VirtualKeyboard();
                    }
                    else if (isWin8OrWin10 || isWin10)
                    {
                        //win10 
                        ShowWin10VirtualKeyboard();
                    }
                }
                catch (Exception)
                {
                    // ignored
                }
            }
            /// <summary>
            /// 关闭虚拟键盘
            /// </summary>
            public void CloseVirtualKeyboard()
            {
                var touchhWnd = FindWindow("IPTip_Main_Window", null);
                if (touchhWnd == IntPtr.Zero)
                {
                    return;
                }
    
                PostMessage(touchhWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
            }
            private static void ShowWin7VirtualKeyboard()
            {
                if (!Environment.Is64BitProcess && Environment.Is64BitOperatingSystem)
                {
                    //32位程序 运行在64位系统上,打开32位程序,需要禁用文件重定向
                    var ptr = new IntPtr();
                    var isWow64FsRedirectionDisabled = Wow64DisableWow64FsRedirection(ref ptr);
    
                    Process.Start(Win7OskPath);
    
                    if (isWow64FsRedirectionDisabled)
                    {
                        Wow64RevertWow64FsRedirection(ptr);
                    }
                }
                else if (Environment.Is64BitProcess && Environment.Is64BitOperatingSystem)
                {
                    Process.Start(Win7OskPath);
                }
            }
    
            private static void ShowWin10VirtualKeyboard()
            {
                if (!IsTabTipProcessPresent())
                {
                    Process.Start(Win10TabTipPath);
                    while (!IsValidHandle(FindWindow("IPTIP_Main_Window", "")))
                    {
                        Thread.Sleep(100);
                    }
                }
    
                //判断可见性
                if (!IsWin10OnScreenKeyboardVisible())
                {
                    ShowByCom();
                }
            }
    
            private static bool IsWin10OnScreenKeyboardVisible()
            {
                var handle = FindWindow(TabTipWindowClassName, "");
                if (!IsValidHandle(handle))
                {
                    return false;
                }
    
                var isVisible = IsWindowVisibleByHandle(handle);
                if (isVisible.HasValue)
                {
                    return isVisible.Value;
                }
    
                // hard way
                var textInputHandle = FindTextInputWindow();
                return IsValidHandle(textInputHandle);
            }
    
            private static IntPtr FindTextInputWindow()
            {
                var lastProbed = IntPtr.Zero;
                do
                {
                    lastProbed = FindWindowEx(IntPtr.Zero, lastProbed, ApplicationFrameHostClassName, null);
                    if (IsValidHandle(lastProbed))
                    {
                        var textInput = FindWindowEx(lastProbed, IntPtr.Zero, CoreWindowClassName,
                            TextInputApplicationCaption);
                        return textInput;
                    }
                } while (IsValidHandle(lastProbed));
    
                return IntPtr.Zero;
            }
    
    
    
            private static bool? IsWindowVisibleByHandle(IntPtr handle)
            {
                var style = GetWindowLong(handle, GWL_STYLE);
                //Console.WriteLine( "Style {0:X8}", style );
    
                // if is disabled - not visible
                if ((style & WS_DISABLED) != 0)
                {
                    return false;
                }
    
                // if has visible style - visible :)
                if ((style & WS_VISIBLE) != 0)
                {
                    return true;
                }
    
                // DWM Window can be cloaked
                // see https://social.msdn.microsoft.com/Forums/vstudio/en-US/f8341376-6015-4796-8273-31e0be91da62/difference-between-actually-visible-and-not-visiblewhich-are-there-but-we-cant-see-windows-of?forum=vcgeneral
                if (DwmGetWindowAttribute(handle, DWMWA_CLOAKED, out var cloaked, 4) == 0)
                {
                    if (cloaked != 0)
                    {
                        return false;
                    }
                }
    
                // undefined
                return null;
            }
    
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            private static bool IsValidHandle(IntPtr handle)
            {
                // if (?:) will be eliminated by jit
                return IntPtr.Size == 4
                    ? handle.ToInt32() > 0
                    : handle.ToInt64() > 0;
            }
    
            private static bool IsTabTipProcessPresent()
            {
                var handle = FindWindow(TabTipWindowClassName, "");
                return IntPtr.Size == 4
                    ? handle.ToInt32() > 0
                    : handle.ToInt64() > 0;
            }
    
            private static void ShowByCom()
            {
                ITipInvocation instance = null;
                try
                {
                    instance = (ITipInvocation)Activator.CreateInstance(ComTypes.TipInvocationType);
                    instance.Toggle(GetDesktopWindow());
                }
                finally
                {
                    if (!ReferenceEquals(instance, null))
                    {
                        Marshal.ReleaseComObject(instance);
                    }
                }
            }
        }
    
        [ComImport]
        [Guid("37c994e7-432b-4834-a2f7-dce1f13b834b")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface ITipInvocation
        {
            void Toggle(IntPtr hwnd);
        }
    
        internal static class ComTypes
        {
            internal static readonly Guid ImmersiveShellBrokerGuid;
            internal static readonly Type ImmersiveShellBrokerType;
    
            internal static readonly Guid TipInvocationGuid;
            internal static readonly Type TipInvocationType;
    
            static ComTypes()
            {
                TipInvocationGuid = Guid.Parse("4ce576fa-83dc-4F88-951c-9d0782b4e376");
                TipInvocationType = Type.GetTypeFromCLSID(TipInvocationGuid);
    
                ImmersiveShellBrokerGuid = new Guid("228826af-02e1-4226-a9e0-99a855e455a6");
                ImmersiveShellBrokerType = Type.GetTypeFromCLSID(ImmersiveShellBrokerGuid);
            }
        }
    }
  • 相关阅读:
    Zookeeper(1)---初识
    golang的一些零散笔记
    ELK使用过程中遇到的一些问题
    ECharts系列:玩转ECharts之常用图(折线、柱状、饼状、散点、关系、树)
    MySQL系列:Docker安装 MySQL提示错误:Access denied for user'root'@'localhost' (using password:yes)
    HTML+CSS系列:登录界面实现
    Apollo系列(二):ASP.NET Core 3.1使用分布式配置中心Apollo
    Apollo系列(一):分布式配置中心Apollo安装(Linux、Docker)
    为你的应用加上skywalking(链路监控)
    工作中,你是如何开始搭建一套容器云环境的呢?
  • 原文地址:https://www.cnblogs.com/congqiandehoulai/p/12725782.html
Copyright © 2011-2022 走看看