如何在没有焦点的情况下将键数据发送到控制台窗口 [英] How to send keys data to a Console window without having focus

查看:51
本文介绍了如何在没有焦点的情况下将键数据发送到控制台窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试将数据发送到控制台窗口而没有重点.我从这里使用了一个简单的键盘钩:在控制台中没有焦点的情况下捕获键击

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

我已经修改了该页面上答案提供的代码,以显示已按下的键的unicode值;我的修改如下:

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);
}

控制台确实会写输入的内容,而与窗口焦点无关,这是预期的,但是问题是我不知道如何允许输入和处理数据,就像通常使用Console.ReadLine().

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.

推荐答案

您可以使用自己的标准输入流替换它,然后对其进行写入.为此,请使用新的流调用Console.SetIn.

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.

针对这些问题,有许多解决方案,从在控制台应用程序级别处理空值到创建自定义StreamReader(锁定该自定义StreamReader直到被写入一行为止)(默认情况下,Console使用SyncTextReader类型的流,但这是私有的).

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).

这篇关于如何在没有焦点的情况下将键数据发送到控制台窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆