C# 如何在没有焦点的情况下将密钥数据发送到控制台窗口
我一直在尝试将数据发送到控制台窗口,但它没有焦点。我在这里使用了一个简单的键盘挂钩: 我修改了该页面答案中提供的代码,以显示已按下键的unicode值;我的修改如下:C# 如何在没有焦点的情况下将密钥数据发送到控制台窗口,c#,input,console,focus,C#,Input,Console,Focus,我一直在尝试将数据发送到控制台窗口,但它没有焦点。我在这里使用了一个简单的键盘挂钩: 我修改了该页面答案中提供的代码,以显示已按下键的unicode值;我的修改如下: private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) { var vkCode
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()所做的那样
我使用以下代码将程序放入消息循环中,以便钩子工作:
_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);
简而言之,我想做的是允许用户向控制台输入数据,而不考虑窗口焦点。您可以用自己的输入流替换标准输入流,然后写入。为此,请使用新流调用Console.SetIn 下面是一个很小的例子:
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);
}
这里唯一的问题是您必须控制流的位置,如果控制台到达流的末尾,它将继续返回空值
对于这些问题,有很多解决方案,从在控制台应用程序级别处理空值到创建自定义StreamReader(控制台默认使用SyncTextReader类型的流,但它是私有的),StreamReader会一直锁定到写入行为止。控制台应用程序是由您的进程启动的吗?如果是,则您可以在ProcessStartInfo中设置RedirectStandardInput,获取StandardInput流并将字符写入其中。@Gusman控制台应用程序是由用户启动的,而不是由另一个进程启动的。好的,控制台应用程序是您的控制台应用程序,我以为它是第三个应用程序。让我写一个回复。你知道我将如何把这个应用到上面提到的代码中吗?当程序到达Application.Run()时;它不允许我运行任何进一步的代码,因为它已进入消息循环。是的,在创建您自己的流类型并将其设置为Console.SetIn而不是Console.Write(Line)之后,再执行您的stream.Write(Line)