0

I am making a customizable on-screen keyboard with Unity, but am having trouble figuring out how to get the keyboard to send the keys to whatever window is behind it.

I have tried using a slightly edited version of Louisbob's code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

[SerializeField]
class SendMessages
{
    [DllImport("user32.dll")]
    public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    public static void sendKeystroke()
    {
        const uint WM_KEYDOWN = 0x0100;
        const uint WM_KEYUP = 0x0101;

        IntPtr hWnd;
        string processName = "Notepad";
        Process[] processList = Process.GetProcesses();

        foreach (Process P in processList)
        {
            if (P.ProcessName.Equals(processName))
            {
                IntPtr edit = P.MainWindowHandle;
                PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.B), IntPtr.Zero);
            }
        }
    }

}

public class B_Button : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

        if(Input.GetMouseButtonDown(0))
        {
            SendMessages.sendKeystroke();
        }
    }

}

This code does not return any errors but when I run/build the project and click, no 'B' appears in Notepad. Am I doing something wrong or does the PostMessage function not work with Unity? If it does not work, what else can I do to get this program to work?

Update

I figured out that getting the handle on the window is one or the only problem. I did

Process[] n = Process.GetProcessesByName("Notepad");
        foreach (Process p in n)
        {
            hWnd = p.MainWindowHandle;
            UnityEngine.Debug.Log(hWnd);
        }

on multiple programs, that were running, and it returned 0 for both mainwindowhandles. I am not sure what is causing this since the applications are running and not hidden, so any advice would be appreciated.

Kile Maze
  • 73
  • 1
  • 11
  • 1
    Unity is not meant for "always on top" style applications where it has to pass input around, be transparent, etc. – Draco18s no longer trusts SE Jun 25 '19 at 02:09
  • Make sure the message is sent – shingo Jun 25 '19 at 03:51
  • did you try to debug step by step? Does `processList` have the entry(entries) you expect or is it maybe empty? Is `P.ProcessName.Equals(processName)` ever true? Maybe a `P.ProcessName.Contains(processName)` would be enough? Is `edit` set to a correct vaue? – derHugo Jun 25 '19 at 11:06
  • @derHugo I posted an update. Thanks for the advice. I just thought it must be the postmessage fcn. causing the issue. – Kile Maze Jun 26 '19 at 00:56

0 Answers0