Windows Message in the Unity3D : WndProc
LRESULT CALLBACK SubWndProc( HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam); WNDPROC gOldWndProc = NULL; HWND gUnityWnd = NULL; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ __declspec(dllexport) bool __stdcall init(HWND hWnd) { gOldWndProc =(WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (LONG)SubWndProc); gUnityWnd =hWnd; if (gOldWndProc !=NULL) return true; return false; } __declspec(dllexport) void __stdcall release() { SetWindowLong(gUnityWnd, GWL_WNDPROC, (LONG)gOldWndProc); gOldWndProc =0; gUnityWnd =0; } #ifdef __cplusplus } #endif /* __cplusplus */ LRESULT CALLBACK SubWndProc( HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam) { switch(nMessage) { case WM_IME_SETCONTEXT: case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_COMPOSITION: case WM_IME_REQUEST: { //... } break; } return CallWindowProc(gOldWndProc, hWnd, nMessage, wParam, lParam); }
Unity 可以透過呼叫 DLL 提供的 init() 函數,讓 Windows 改為呼叫我們指定的函數 (SubWndProc) 來處理 Message,透過 release() 函數讓 Message 處理流程復原。底下是 Unity 部分的原始碼(DLL 檔名為 UnityIMEDLL.dll 且檔案放在 Assets/Plugins 目錄下)
using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; public class IMEInputBox : MonoBehaviour { //----------------------------------------------------------- [DllImport("UnityIMEDLL")] protected static extern bool init(IntPtr hWnd); [DllImport("UnityIMEDLL")] protected static extern void release(); [DllImport("user32")] protected static extern IntPtr GetActiveWindow(); //----------------------------------------------------------- // Use this for initialization void Start () { Debug.Log("init UnityIMEDLL."); try { init(GetActiveWindow()); } catch (Exception e) { Debug.Log(e.ToString()); } } void OnDisable() { Debug.Log("release UnityIMEDLL."); try { release(); } catch (Exception e) { Debug.Log(e.ToString()); } } }