C# 在C中保持原始命令的同时挂起按键#
当我的应用程序在后台运行时,我想检测按键并相应地执行某些事件。例如,当我按下W时,我希望我的应用程序检测到这一点,在一个列表框中写下“W pressed”,并且不影响正在进行的任何其他进程 我找到的以下代码与我上面所说的基本相同。唯一的问题是它完全拦截了按键。例如,如果我打开google并键入“W”,该字母不会出现在google搜索栏中,但会被应用程序钩住C# 在C中保持原始命令的同时挂起按键#,c#,key,hook,keypress,C#,Key,Hook,Keypress,当我的应用程序在后台运行时,我想检测按键并相应地执行某些事件。例如,当我按下W时,我希望我的应用程序检测到这一点,在一个列表框中写下“W pressed”,并且不影响正在进行的任何其他进程 我找到的以下代码与我上面所说的基本相同。唯一的问题是它完全拦截了按键。例如,如果我打开google并键入“W”,该字母不会出现在google搜索栏中,但会被应用程序钩住 namespace WindowsFormsApplication1 { public partial class Form1 : F
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// DLL libraries used to manage hotkeys
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
const int MYACTION_HOTKEY_ID = 1;
public Form1()
{
InitializeComponent();
// Modifier keys codes: Alt = 1, Ctrl = 2, Shift = 4, Win = 8
// Compute the addition of each combination of the keys you want to be pressed
// ALT+CTRL = 1 + 2 = 3 , CTRL+SHIFT = 2 + 4 = 6...
RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int)Keys.W);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID)
{
// My hotkey has been typed
// Do what you want here
// ...
lstLog.Items.Add("W pressed");
}
base.WndProc(ref m);
}
}
}
简而言之。我正在寻找一种方法来钩住一个按键,同时仍然保持原来的命令。在我上面的例子中,“W”应该出现在谷歌搜索栏中
我一直在寻找解决这个(可能很小)问题的方法,并发现了很多问题
关于公钥和钩子的帖子与上面的一样,但是没有一个像我希望的那样工作。所以我决定在这里发表我的第一篇文章。希望你们能帮助我。如果有什么不清楚的地方,请告诉我
Thx
-编辑-
一些补充资料:
我确实计划在玩《传奇联盟》、《魔兽世界》等游戏时使用此程序。因此,由于可能禁止使用第三方软件,我希望它不会与这些游戏的任何进程交互。如果有什么我应该知道的,那么请告诉我。我和我的未来未被禁止的帐户提前感谢您。您不能使用
注册表项
,因为它不会传递密钥事件
您必须使用WH\u键盘LL
Hook
这是一个功能齐全的示例,快速且肮脏,但功能齐全:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace StackoverflowHooks
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
public struct KBDLLHOOKSTRUCT
{
public uint vkCode;
public uint scanCode;
public uint flags;
public uint time;
IntPtr dwExtraInfo;
}
IntPtr hHook;
private delegate IntPtr HookProc(int nCode, IntPtr wp, IntPtr lp);
HookProc lpfn;
private IntPtr KeyboardHookProc(int code, IntPtr wParam, IntPtr lParam)
{
KBDLLHOOKSTRUCT data = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
MessageBox.Show("Pressed key: " + (Keys)data.vkCode);
return CallNextHookEx(hHook, code, wParam, lParam);
}
public Form1()
{
InitializeComponent();
SetHook();
}
private void SetHook()
{
int id_hook = 13; //WH_KEYBOARD_LL - HOOK
lpfn = new HookProc(this.KeyboardHookProc);
using (ProcessModule curModule = Process.GetCurrentProcess().MainModule)
hHook = SetWindowsHookEx(id_hook, lpfn, GetModuleHandle(curModule.ModuleName), 0);
}
}
}
看一看界面这只是不恰当地使用RegisterHotKey(),它只对实现热键有用。截取像W这样的键入键需要编写一个WHU键盘挂钩。你不能在C#中编写这样的钩子,它需要一个可以注入每个进程的DLL。我应该补充一点,我计划在一些游戏中使用这个应用程序,如《传奇联盟》、《魔兽世界》等。我不知道插入DLL是什么意思,只是第一次用谷歌搜索它。但我想避免太复杂的东西,可能会与游戏互动,因为这可能会导致某种形式的禁令,因为使用第三方软件。