When using parentHWND option, keyboard input doesn't work

I’ve been testing the new parentHWND command line option that appeared in 4.5.5p1 using the reference example provided in the documentation page, but when I tried to use Input.GetKey it never triggered. Input.GetMouseButton works correctly, but I couldn’t get keyboard input to work. I’ve tested it in Windows 8.1 x64 and Windows 7 x64.
I know is a very recent feature, but it looked great and I’d love to use it.
Any advice?

I have the same problem, mouse input works fine, but no keyboard input at all.
Did you find a solution or workaround for this?
Any official statement about this? Is it a bug, or missing something from the initialization on opener side?

I think you need to send WM_ACTIVATE

1 Like

Adding to Dave answer, here’s the updated Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.Windows.Forms.VisualStyles;

namespace Container
{
    public partial class Form1 : Form
    {
        [DllImport("User32.dll")]
        static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);

        internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
        [DllImport("user32.dll")]
        internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);

        [DllImport("user32.dll")]
        static extern int SendMessage(IntPtr hWnd, int msg, int wParam, uint lParam);

        private Process process;
        private IntPtr unityHWND = IntPtr.Zero;

        private const int WM_ACTIVATE = 0x0006;
        private const int WA_ACTIVE = 1;

        public Form1()
        {
            InitializeComponent();

            try
            {
                process = new Process();
                process.StartInfo.FileName = "Child.exe";
                process.StartInfo.Arguments = "-parentHWND " + panel1.Handle.ToInt32() + " " + Environment.CommandLine;
                process.StartInfo.UseShellExecute = true;
                process.StartInfo.CreateNoWindow = true;

                process.Start();

                process.WaitForInputIdle();
                // Doesn't work for some reason ?!
                //unityHWND = process.MainWindowHandle;
                EnumChildWindows(panel1.Handle, WindowEnum, IntPtr.Zero);

                unityHWNDLabel.Text = "Unity HWND: 0x" + unityHWND.ToString("X8");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ".\nCheck if Container.exe is placed next to Child.exe.");
            }

        }
        private int WindowEnum(IntPtr hwnd, IntPtr lparam)
        {
            unityHWND = hwnd;
            SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, 0);
            return 0;
        }

        private void panel1_Resize(object sender, EventArgs e)
        {
            MoveWindow(unityHWND, 0, 0, panel1.Width, panel1.Height, true);
            SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, 0);
        }

        // Close Unity application
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                process.CloseMainWindow();

                Thread.Sleep(1000);
                while (process.HasExited == false)
                    process.Kill();
            }
            catch (Exception)
            {
               
            }
        }
    }
}
5 Likes

Can you plz guide me how to pass data to the embedded Unity Exe from the Host WPF Application ?

use Interprocess communication

I had similar issue, this was caused by the line

unityHWND = process.MainWindowHandle;

I dont know why I uncommented it. Removed the line, works well.

Still looking for a solution for this with the new input system. If anyone have one.

See https://discussions.unity.com/t/807093