我有一个问题,当在我的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实现,并使用您自己的事件处理函数声明您自己的事件args类型。您唯一要返回的是虚拟密钥代码,因此您也可以为此定义自己的类型:
class KeyboardHookEventArgs : EventArgs
{
public int VirtualKeyCode { get; }
public KeyboardHookEventArgs(int virtualKeyCode)
{
VirtualKeyCode = virtualKeyCode;
}
}
…然后发生的事件:
public event EventHandler<KeyboardHookEventArgs> KeyDown;
public event EventHandler<KeyboardHookEventArgs> KeyUp;
在类似的地方创建args对象new KeyboardHookEventArgs(kbStruct.VirtualKeyCode)
。
请注意,您的事件引发实现不是线程安全的。使用空条件运算符在C#中更安全,更惯用,例如:
if (wParam == (IntPtr)WM_KEYDOWN)
{
KeyDown?.Invoke(this, new KeyboardHookEventArgs(kbStruct.VirtualKeyCode));
}
您还应该为传递正确的值sender
,即this
如上所述。如果您希望该事件没有发送者,则该事件(以及该类的其余部分)应该为static
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句