2017年5月9日 星期二

Unity內使用桌面的虛擬鍵盤

虛擬鍵盤一般用在觸控螢幕上,也就是觸控電視和手機平板等,當需要讓使用者輸入的時候就很方便,因此在這記錄一下呼叫虛擬鍵盤的做法,之前在網路上找到並在專案中拿來使用的。

首先是創造一個C#的Script,裡面內容直接如下,可以直接複製貼上:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System;
  5. using System.Diagnostics;
  6. using System.Runtime.InteropServices;
  7.  
  8. public class VirtualKeyboardController : MonoBehaviour {
  9.  
  10.     void Start ()
  11.     {
  12.  
  13.     }
  14.  
  15.     void Update ()
  16.     {
  17.  
  18.     }
  19.  
  20.     public class VirtualKeyboard
  21.     {
  22.         [DllImport("user32")]
  23.         static extern IntPtr FindWindow(String sClassName, String sAppName);
  24.  
  25.         [DllImport("user32")]
  26.         static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
  27.  
  28.         private static Process _onScreenKeyboardProcess = null;
  29.  
  30.         //Show the touch keyboard (tabtip.exe).
  31.         public void ShowTouchKeyboard()
  32.         {
  33.             ExternalCall("C:\\Program Files\\Common Files\\Microsoft Shared\\ink\\tabtip.exe", null, false);
  34.             //ExternalCall("TABTIP", null, false);
  35.         }
  36.  
  37.         //Hide the touch keyboard (tabtip.exe).
  38.         public void HideTouchKeyboard()
  39.         {
  40.             uint WM_SYSCOMMAND = 274;
  41.             int SC_CLOSE = 61536;
  42.             IntPtr ptr = FindWindow("IPTip_Main_Window", null);
  43.             PostMessage(ptr, WM_SYSCOMMAND, SC_CLOSE, 0);
  44.         }
  45.  
  46.         //Show the on screen keyboard (osk.exe).
  47.         public void ShowOnScreenKeyboard()
  48.         {
  49.             //ExternalCall("C:\\Windows\\system32\\osk.exe", null, false);
  50.  
  51.             if (_onScreenKeyboardProcess == null || _onScreenKeyboardProcess.HasExited)
  52.                 _onScreenKeyboardProcess = ExternalCall("OSK", null, false);
  53.         }
  54.  
  55.         // Hide the on screen keyboard (osk.exe).
  56.         public void HideOnScreenKeyboard()
  57.         {
  58.             if (_onScreenKeyboardProcess != null && !_onScreenKeyboardProcess.HasExited)
  59.                 _onScreenKeyboardProcess.Kill();
  60.         }
  61.  
  62.         /// <summary>
  63.         /// Set size and location of the OSK.exe keyboard, via registry changes.  Messy, but only known method.
  64.         /// </summary>
  65.         /// <param name='rect'>
  66.         /// Rect.
  67.         /// </param>
  68.         public void RepositionOnScreenKeyboard(Rect rect)
  69.         {
  70.             ExternalCall("REG", @"ADD HKCU\Software\Microsoft\Osk /v WindowLeft /t REG_DWORD /d " + (int)rect.x + " /f", true);
  71.             ExternalCall("REG", @"ADD HKCU\Software\Microsoft\Osk /v WindowTop /t REG_DWORD /d " + (int)rect.y + " /f", true);
  72.             ExternalCall("REG", @"ADD HKCU\Software\Microsoft\Osk /v WindowWidth /t REG_DWORD /d " + (int)rect.width + " /f", true);
  73.             ExternalCall("REG", @"ADD HKCU\Software\Microsoft\Osk /v WindowHeight /t REG_DWORD /d " + (int)rect.height + " /f", true);
  74.         }
  75.  
  76.         private static Process ExternalCall(string filename, string arguments, bool hideWindow)
  77.         {
  78.             ProcessStartInfo startInfo = new ProcessStartInfo();
  79.             startInfo.FileName = filename;
  80.             startInfo.Arguments = arguments;
  81.  
  82.             // if just command, we do not want to see the console displayed
  83.             if (hideWindow)
  84.             {
  85.                 startInfo.RedirectStandardOutput = true;
  86.                 startInfo.RedirectStandardError = true;
  87.                 startInfo.UseShellExecute = false;
  88.                 startInfo.CreateNoWindow = true;
  89.             }
  90.  
  91.             Process process = new Process();
  92.             process.StartInfo = startInfo;
  93.             process.Start();
  94.  
  95.             return process;
  96.         }
  97.     }
  98. }
然後在其他地方來做呼叫或關閉,當然虛擬鍵盤呼叫出來後,也可以直接按鍵盤右上角的X來關閉:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class XXX : MonoBehaviour {
  6.  
  7.     void Start ()
  8.     {
  9.         VirtualKeyboardController.VirtualKeyboard keyboard = new VirtualKeyboardController.VirtualKeyboard();
  10.  
  11.         keyboard.ShowOnScreenKeyboard();
  12.  
  13.         keyboard.HideOnScreenKeyboard();
  14.     }
  15.  
  16.     void Update ()
  17.     {
  18.  
  19.     }
  20. }
這樣就可以呼叫和關閉螢幕虛擬鍵盤了,網路上有人說這招在Win 10後就沒辦法叫了,因為Microsoft不再放出虛擬鍵盤的控制權,我自己在Win 10使用是無礙啦......


沒有留言:

張貼留言