【Unity 填坑记】 Vuplex WebView 输入框无法拉起 Windows 触摸键盘

前言

大家好,我是Mark。 许久未碰 Unity,最近遇到个实际需求:要在触摸屏 Windows 设备上调用系统触摸键盘。翻了不少资料,发现大多方案都是拉起旧版 “屏幕键盘”,样式偏老旧,和新版 Windows 的设计风格格格不入。为了适配现代 UI 审美,我专门研究了新版触摸键盘的调用逻辑,整理出一套完整可落地的解决方案,分享给有同样需求的开发者~

一、最终效果

动画.gif

二、解决方案

  1. 使用 COM 接口拉起Windows触摸键盘
using System;  
using System.Diagnostics;  
using System.Runtime.InteropServices;  
using UnityEngine;  
using Debug = UnityEngine.Debug;  
  
// ==================== COM接口定义(用于调用Windows触摸键盘) ====================[ComImport]  
[Guid("37c994e7-432b-4834-a2f7-dce1f13b834b")]  
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]  
interface ITipInvocation  
{  
    void Toggle(IntPtr hwnd);  
}  
  
[ComImport]  
[Guid("4ce576fa-83dc-4F88-951c-9d0782b4e376")]  
class TipInvocation { }

public class WinTouchKeyboard : MonoBehaviour  
{  
    /// <summary>  
    /// 打开Windows触摸键盘(通过COM接口)  
    /// </summary>  
    public void ShowKeyboard()  
    {        
	    try  
        {  
            ITipInvocation tip = new TipInvocation() as ITipInvocation;  
            // 传入当前Unity进程的主窗口句柄  
            tip.Toggle(Process.GetCurrentProcess().MainWindowHandle);  
            Debug.Log("已尝试打开触摸键盘");  
        }        
        catch (Exception e)  
        {            
	        Debug.LogError($"打开触摸键盘失败:{e.Message}");  
        }    
    }      
    /// <summary>  
    /// 关闭Windows触摸键盘(COM接口的Toggle方法可切换状态)  
    /// </summary>  
    public void HideKeyboard()  
    {        
	    try  
        {  
            ITipInvocation tip = new TipInvocation() as ITipInvocation;  
            tip.Toggle(Process.GetCurrentProcess().MainWindowHandle);  
            Debug.Log("已尝试关闭触摸键盘");  
        }        
        catch (Exception e)  
        {            
	        Debug.LogError($"关闭触摸键盘失败:{e.Message}");  
        }    
    }
}
  1. 接收WebView FocusedInputFieldChanged 回调事件
using UnityEngine;  
using Vuplex.WebView;  
using System;  
  
  
public class CanvasWebViewMessageReceiver : MonoBehaviour  
{  
    // 1. 拖拽场景中的 CanvasWebViewPrefab 到此处  
    public CanvasWebViewPrefab canvasWebViewPrefab;  
    private WinTouchKeyboard winTouchKeyboard;
      
    private void Start()  
    {        
	    // 安全检查  
        if (canvasWebViewPrefab == null)  
        {            
            return;  
        }  
        winTouchKeyboard = FindObjectOfType<WinTouchKeyboard>();  
        // 2. 监听 WebView 初始化完成事件  
        canvasWebViewPrefab.Initialized += OnWebViewInitialized;  
    }
      
    /// <summary>  
    /// WebView 初始化完成后调用  
    /// </summary>  
    private void OnWebViewInitialized(object sender, EventArgs e)  
    {        
	    Debug.Log("WebView 初始化完成,开始监听 FocusedInputFieldChanged 消息...");  
        canvasWebViewPrefab.WebView.FocusedInputFieldChanged += (sender, eventArgs) => 
        {  
            if (eventArgs.Type == FocusedInputFieldType.Text)  
            {                
	            winTouchKeyboard.ShowKeyboard();
	            // 获得焦点时启用输入法的合成模式,如果不启用导致网页输入框无法输入中文
                Input.imeCompositionMode = IMECompositionMode.On;  
                Debug.Log("IME enabled On: " + Input.imeIsSelected);  
            }            
            else  
            {  
                winTouchKeyboard.HideKeyboard();
                // 焦点丢失,关闭输入法合成模式,输入法直接输出单个字符(无法输入中文等需要组合的文字)
                Input.imeCompositionMode = IMECompositionMode.Off;  
                Debug.Log("IME enabled Off: " + Input.imeIsSelected);  
            }        
        };        
    }  
  
}

三、结束

好了,今天就写到这吧~

对你有帮助的话可以点赞、关注、收藏,有问题评论区见哈~

原创不易,若转载请注明出处,感谢大家~

Logo © 2025 Mark All Rights Reserved. 陕ICP备2025083152号