我一直在尝试将数据发送到控制台窗口而没有焦点。我从这里使用了一个简单的键盘钩:Capture keystroke without focus in console
我修改了该页面上答案提供的代码,以显示已按下的键的unicode值;我的修改如下:
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);
简而言之,我想做的是允许用户将数据输入到控制台而不管窗口焦点。
答案 0 :(得分:0)
您可以用自己的标准输入流替换标准输入流,然后写入。为此,请使用新流调用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类型的流,但它是私有的)。