internal static void Initialize(Game game) { if (Initialized) { return; } Initialized = true; Type t_TextInputExt = typeof(Keyboard).Assembly.GetType("Microsoft.Xna.Framework.Input.TextInputEXT"); EventInfo e_TextInput = t_TextInputExt?.GetEvent("TextInput"); if (e_TextInput != null) { // FNA offers Microsoft.Xna.Framework.Input.TextInputEXT, // public static event Action<char> TextInput; e_TextInput.AddEventHandler(null, new Action <char>(ReceiveTextInput).CastDelegate(e_TextInput.EventHandlerType)); // SDL2 offers SDL_GetClipboardText and SDL_SetClipboardText Type t_SDL2 = typeof(Keyboard).Assembly.GetType("SDL2.SDL"); _GetClipboardText = t_SDL2.GetMethod("SDL_GetClipboardText").CreateDelegate(typeof(Func <string>)) as Func <string>; Func <string, int> setClipboardText = t_SDL2.GetMethod("SDL_SetClipboardText").CreateDelegate(typeof(Func <string, int>)) as Func <string, int>; _SetClipboardText = value => setClipboardText(value); } else { // XNA requires WinForms message hooks. FormsHook = new XNAFormsHook(game.Window.Handle, (ref Message msg) => { if (msg.Msg != 0x0102) { return; } ReceiveTextInput((char)msg.WParam); }); // WinForms offers Clipboard.GetText and SetText Type t_Clipboard = Assembly.Load("System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").GetType("System.Windows.Forms.Clipboard"); Func <string> getClipboardText = t_Clipboard.GetMethod("GetText", new Type[] { }).CreateDelegate(typeof(Func <string>)) as Func <string>; _GetClipboardText = () => STAThreadHelper.Get(getClipboardText).GetResult(); Action <string> setClipboardText = t_Clipboard.GetMethod("SetText", new Type[] { typeof(string) }).CreateDelegate(typeof(Action <string>)) as Action <string>; _SetClipboardText = (value) => STAThreadHelper.Get(() => { try { setClipboardText(string.IsNullOrEmpty(value) ? "\0" : value); } catch (ExternalException e) { Logger.Log(LogLevel.Warn, "TextInputs", "Failed to set the clipboard"); Logger.LogDetailed(e); } return(value); }).GetResult(); } }
public STAThreadHelper(Game game) : base(game) { Instance = this; UpdateOrder = -500000; WaitTokenSource = new CancellationTokenSource(); Worker = new Thread(WorkerLoop) { Name = "Everest STAThread Worker", IsBackground = true }; Worker.SetApartmentState(ApartmentState.STA); Worker.Start(); }