zoukankan      html  css  js  c++  java
  • unity3d屏蔽Windows10输入法

    在win10上,如果安装了某些输入法(比如QQ输入法),会造成unity的键盘事件被输入法捕获而不能触发的情况。只有将输入法切换到英文状态下才能响应键盘事件。

    解决办法有,

    1:用户主动切换输入法,甚至卸载输入法

    2:程序在非输入状态下,屏蔽输入法

    由于方法1在全屏状态下,用户完全不知道是否在输入法劫持中,常常导致以为是程序的bug,所以这里采用方法2

    在unity中,官方并没有提供一个很好的解决方案(Input.imeCompositionMode无效)。所以只能借助win api。

    其中最为重要的API是设置输入法状态:

    [DllImport("imm32.dll")]
    private static extern bool ImmSetOpenStatus(IntPtr himc, bool b);

    其中himc为当前正在输入的窗口的输入法句柄,b为true表示开启,false表示关闭

    himc可以通过另外一个api函数获取

    [DllImport("imm32.dll")]
    private static extern IntPtr ImmGetContext(IntPtr hwnd);

    其中,hwnd为程序窗口的句柄

    该值的获取方式可以参考:http://blog.csdn.net/linkrules/article/details/50420797

    整个代码如下:

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    public class Win32Help
    {
        private delegate bool Wndenumproc(IntPtr hwnd, uint lParam);
    
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool EnumWindows(Wndenumproc lpEnumFunc, uint lParam);
    
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr GetParent(IntPtr hWnd);
        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);
    
        [DllImport("kernel32.dll")]
        private static extern void SetLastError(uint dwErrCode);
    
    
        /// <summary>
        /// 获取当前进程的窗口句柄
        /// </summary>
        /// <returns></returns>
        public static IntPtr GetProcessWnd()
        {
            var ptrWnd = IntPtr.Zero;
            var pid = (uint)Process.GetCurrentProcess().Id;  // 当前进程 ID  
    
            var bResult = EnumWindows(delegate (IntPtr hwnd, uint lParam)
            {
                uint id = 0;
    
                if (GetParent(hwnd) != IntPtr.Zero)
                    return true;
                GetWindowThreadProcessId(hwnd, ref id);
                if (id != lParam)
                    return true;
                ptrWnd = hwnd;   // 把句柄缓存起来  
                SetLastError(0);    // 设置无错误  
                return false;   // 返回 false 以终止枚举窗口  
            }, pid);
    
            return (!bResult && Marshal.GetLastWin32Error() == 0) ? ptrWnd : IntPtr.Zero;
        }
    
        [DllImport("imm32.dll")]
        private static extern IntPtr ImmGetContext(IntPtr hwnd);
        [DllImport("imm32.dll")]
        private static extern bool ImmGetOpenStatus(IntPtr himc);
        [DllImport("imm32.dll")]
        private static extern bool ImmSetOpenStatus(IntPtr himc, bool b);
    
        /// <summary>
        /// 设置输入法状态
        /// </summary>
        /// <param name="tf"></param>
        public static void SetImeEnable(bool tf)
        {
            var handle = GetProcessWnd();
            var hIme = ImmGetContext(handle);
            ImmSetOpenStatus(hIme, tf);
        }
    
        /// <summary>
        /// 获取输入法状态
        /// </summary>
        /// <returns></returns>
        public bool GetImeStatus()
        {
            var handle = GetProcessWnd();
            var hIme = ImmGetContext(handle);
            return ImmGetOpenStatus(hIme);
        }
    }

    然后在程序中可以使用Win32Help.SetImeEnable(false)的方法来屏蔽输入法,比如:

    using UnityEngine;
    
    public class InputTest : MonoBehaviour
    {
        // Use this for initialization
        protected void Start()
        {
            Win32Help.SetImeEnable(false);
        }
    
    
        // Update is called once per frame
        protected void Update()
        {
            if (Input.GetKey(KeyCode.A))
            {
                Debug.Log("AAAAAAAAAAAs");
            }
        }
    }

    注意:只对Windows系统有效,Win10测试可用,其他系统未经测试

    个人博客请访问:http://www.cnblogs.com/CodeGize/
  • 相关阅读:
    NX 调试批处理文件
    NXOpen 更改UI对话框宽度
    NXOpen 遍历体 移动图层
    NXOpen 设置工作图层 一键开关图层
    NXOpen Block UI弹出另一个对话框实例
    NXOpen 座标UI获取 (原点 矩阵变换)
    [StackExchange]Redis 的几种类型的操作(string,hash,lists,set,sorted set)
    IIS 并发连接 设置与测试
    [StackExchage]Redis 的连接与操作(跨机器)
    Redis 事务
  • 原文地址:https://www.cnblogs.com/CodeGize/p/5612067.html
Copyright © 2011-2022 走看看