c# - 如何修复 C# 控制台应用程序中的错误 KeyEventHandler?
问题描述
我有一个问题,在我的winform应用程序中执行这段代码时,它运行正常,但是在控制台上运行时却收到错误消息,似乎KeyEventHandler只在winform中使用,是的,可以在控制台应用程序中替换什么。这是我的钩子函数:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace Websevice_Core_Console
{
class Y2KeyboardHook
{
#region Win32 API Functions and Constants
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
KeyboardHookDelegate lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private const int WM_KEYUP = 0x101;
#endregion
private KeyboardHookDelegate _hookProc;
private IntPtr _hookHandle = IntPtr.Zero;
public delegate IntPtr KeyboardHookDelegate(int nCode, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
public struct KeyboardHookStruct
{
public int VirtualKeyCode;
public int ScanCode;
public int Flags;
public int Time;
public int ExtraInfo;
}
#region Keyboard Events
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
#endregion
// destructor
~Y2KeyboardHook()
{
Uninstall();
}
public void Install()
{
_hookProc = KeyboardHookProc;
_hookHandle = SetupHook(_hookProc);
if (_hookHandle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
private IntPtr SetupHook(KeyboardHookDelegate hookProc)
{
IntPtr hInstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
}
private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
KeyboardHookStruct kbStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
if (wParam == (IntPtr)WM_KEYDOWN)
{
if (KeyDown != null)
KeyDown(null, new KeyEventArgs((Keys)kbStruct.VirtualKeyCode));
}
else if (wParam == (IntPtr)WM_KEYUP)
{
if (KeyUp != null)
KeyUp(null, new KeyEventArgs((Keys)kbStruct.VirtualKeyCode));
}
}
return CallNextHookEx(_hookHandle, nCode, wParam, lParam);
}
public void Uninstall()
{
UnhookWindowsHookEx(_hookHandle);
}
}
}
这是我的使用方法:
_y2KeyboardHook.KeyDown += (sender, e) =>// ghi nhan thong tin tu ban phim
{
if (e.KeyCode.ToString() != "")
{
Console.WriteLine("Hello "+KeyCode);
}
}
我在 2 行收到一条错误消息
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
谁能帮帮我,非常感谢!
解决方案
鉴于您发布的代码和模糊的“我收到一条错误消息”(这不是一个实际问题,也不是一个有用的问题陈述……总是要具体),您似乎没有引用System.Windows.Forms.dll
. 另一方面,如果您没有引用 Winforms 程序集,则不清楚为什么您在使用的地方也没有收到错误KeyEventArgs
,因为这是在同一个程序集中定义的。
也就是说,假设您使用的错误KeyEventHandler
只是没有定义,您可以定义相同的类型供您自己使用:
public delegate void KeyEventHandler(object sender, KeyEventArgs e);
即,只需从文档中复制委托类型声明。
现在,说了这么多,如果您没有引用 Winforms 程序集,并且您也收到与预期KeyEventArgs
一样类型的错误消息,正如预期的那样,您可能需要考虑不复制这种方法的 Winforms 实现,并且只需使用您自己的事件处理程序声明您自己的事件参数类型。您返回的唯一内容是虚拟键代码,因此您不妨为此定义自己的类型:
class KeyboardHookEventArgs : EventArgs
{
public int VirtualKeyCode { get; }
public KeyboardHookEventArgs(int virtualKeyCode)
{
VirtualKeyCode = virtualKeyCode;
}
}
…然后是事件:
public event EventHandler<KeyboardHookEventArgs> KeyDown;
public event EventHandler<KeyboardHookEventArgs> KeyUp;
new KeyboardHookEventArgs(kbStruct.VirtualKeyCode)
相反,您在哪里创建 args 对象。
请注意,您的事件引发实现不是线程安全的。在 C# 中使用空条件运算符会更安全,也更惯用,例如:
if (wParam == (IntPtr)WM_KEYDOWN)
{
KeyDown?.Invoke(this, new KeyboardHookEventArgs(kbStruct.VirtualKeyCode));
}
您还应该为 传递一个正确的值sender
,即this
如上所示。如果您希望事件没有发件人,那么它(和班级的其他人)应该只是static
.
推荐阅读
- java - Java Map.containsValue 在列表中的第 15000 个项目之后不起作用
- sql - 如何为每个员工总结 6 个月范围内 5 年的数据?
- c# - 自动触发 ChecklistBox 项的 BackColor
- apache-flink - 使用 MiniCluster 测试 flink 作业以使用处理时间触发计时器
- c++ - 未声明的标识符,在定义宏以加载 vulkan 函数指针时
- python - GSM SSL 握手 ssl.py
- python - “表有 X 列,但提供了 Y 值”错误
- mysql - 在反应 javaScript 中删除 MySQL 表中的正确条目
- jquery - jquery droppable/html5 api - 如何使元素可拖放和可拖动
- plugins - DjangoCMS 在多个自定义插件中填充模型的数据