我正在开发一个控制台应用程序,其中我需要检测多个热键,例如 Ctrl+N、Ctrl+O 和 Ctrl+S。这是我用来识别这些热键的代码的一部分:
ConsoleKeyInfo input = Console.ReadKey(true);
if (input.Modifiers == ConsoleModifiers.Control)
{
if (input.Key == ConsoleKey.N)
{
// ...
}
else if (input.Key == ConsoleKey.O)
{
// ...
}
else if (input.Key == ConsoleKey.S)
{
//...
}
}
上面的代码对于 Ctrl+N 和 Ctrl+O 没有任何问题。但是,我无法让它为 Ctrl+S 工作。经过一些快速测试后,我发现按 Ctrl+S 甚至没有执行任何操作(意味着程序仍在等待用户输入某些内容)。
此问题仅在使用 Ctrl+S 时出现。对任何其他修饰符(例如
Shift)和键(N、O等)使用一些简单的
if
语句效果很好。
为什么会出现这种情况? Ctrl+S组合有什么特殊含义吗?有可能使这项工作成功吗?如果是的话,怎么办?
在 ThreeStarProgrammer57 的帮助下,我为自己的控制台应用程序提出了这个解决方案。
您需要使用 SetConsoleMode 并按照 oconnor0" 的建议传递
"
ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS
来配置控制台。
导入需要的内核函数:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
[Flags]
private enum ConsoleInputModes : uint
{
ENABLE_PROCESSED_INPUT = 0x0001,
ENABLE_LINE_INPUT = 0x0002,
ENABLE_ECHO_INPUT = 0x0004,
ENABLE_WINDOW_INPUT = 0x0008,
ENABLE_MOUSE_INPUT = 0x0010,
ENABLE_INSERT_MODE = 0x0020,
ENABLE_QUICK_EDIT_MODE = 0x0040,
ENABLE_EXTENDED_FLAGS = 0x0080,
ENABLE_AUTO_POSITION = 0x0100
}
[Flags]
private enum ConsoleOutputModes : uint
{
ENABLE_PROCESSED_OUTPUT = 0x0001,
ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002,
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004,
DISABLE_NEWLINE_AUTO_RETURN = 0x0008,
ENABLE_LVB_GRID_WORLDWIDE = 0x0010
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
static int STD_INPUT_HANDLE = -10;
并在您的程序中使用它们,如下所示:
// Add this section to your code:
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), (uint)(
ConsoleInputModes.ENABLE_WINDOW_INPUT |
ConsoleInputModes.ENABLE_MOUSE_INPUT |
ConsoleInputModes.ENABLE_EXTENDED_FLAGS
));
// ------------------------------
ConsoleKeyInfo input = Console.ReadKey(true);
if (input.Modifiers == ConsoleModifiers.Control)
{
if (input.Key == ConsoleKey.N)
{
// ...
}
else if (input.Key == ConsoleKey.O)
{
// ...
}
else if (input.Key == ConsoleKey.S)
{
//...
}
}
此解决方案不仅可以让您捕获 Ctrl+S 击键,还可以捕获 Ctrl+C!
我制作了一个控制台文本编辑器,在其中我必须检测 ctrl+s 才能保存文档。我的代码是这样的:
int d;
while(true){
if(_kbhit()){
d=_getch();
if(d==19){
// code for when ctrl+s is hit
}
// condition for other keys
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (msg.Msg == 256)
{
//if the user pressed control + s
if (keyData == (Keys.Control | Keys.S))
{
}
//if the user pressed control + o
else if (keyData == (Keys.Control | Keys.O))
{
}
//if the user pressed control + n
else if (keyData == (Keys.Control | Keys.N))
{
}
}
return base.ProcessCmdKey(ref msg, keyData);
}