How to send keys data to a Console window without having focus

笑着哭i 提交于 2021-02-05 12:04:43

问题


I've been trying to send data to a console window without it having focus. I've used a simple Keyboard Hook from here: Capture keystroke without focus in console

I've modified the code provided from the answer on that page to display the unicode values of keys that have been pressed; my modifications are as follows:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        var vkCode = Marshal.ReadInt32(lParam);

        var key = (Keys) vkCode;

        if (key == Keys.LShiftKey || key == Keys.RShiftKey)
            shift = true;

        if (key == Keys.RMenu)
            altgr = true;

        if (key == Keys.Return || key == Keys.Enter)
        {
            Console.WriteLine();
            input = "";
        }else if (key == Keys.Back)
        {
            if (input.Length > 0)
            {
                input = input.Substring(0, input.Length - 1);
                Console.Write("\b \b");
            }
        }
        else
        {
            input += GetCharsFromKeys(key);

            Console.Write(GetCharsFromKeys(key));
        }
    }

    if (nCode >= 0 && wParam == (IntPtr) WM_KEYUP)
    {
        var vkCode = Marshal.ReadInt32(lParam);

        var key = (Keys)vkCode;

        if (key == Keys.LShiftKey || key == Keys.RShiftKey)
            shift = false;

        if (key == Keys.RMenu)
            altgr = false;
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

The console does write what is being typed regardless of window focus, which is what is intended, however the issue is I have no idea how to allow the input and processing of data, like you would normally do using Console.ReadLine().

I am using the following code to put the program in a message loop for the hook to work:

_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);

In a nutshell, what I want to do is allow users to input data to the console regardless of window focus.


回答1:


You can replace the standard input stream with your own and then write to it. To do that call Console.SetIn with your new stream.

Here is a very little example:

    static void Main(string[] args)
    {

        MemoryStream ms = new MemoryStream();
        StreamReader sr = new StreamReader(ms);
        StreamWriter sw = new StreamWriter(ms);
        Console.SetIn(sr);


        sw.WriteLine("Hi all!");
        ms.Seek(0, SeekOrigin.Begin);
        string line = Console.ReadLine();

        Console.WriteLine(line);

    }

Only problem here is you must control the stream's position and if the Console reaches the end of the stream it will continue returning a null value.

There are many solutions for those problems, from handling the null values at the console app level to creating a custom StreamReader which locks until a line has been written (Console uses by default a stream of type SyncTextReader, but it's private).



来源:https://stackoverflow.com/questions/24411887/how-to-send-keys-data-to-a-console-window-without-having-focus

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!