C# 检测击键并发送到后台 Windows
C# Detect Keystrokes and Send to Background Windows
我今天花了六个小时四处寻找方法来完成我想要完成的任务。然而,运气不佳,我尝试过的每一种方法都没有奏效。
所以我正在开发的程序是一个用于视频游戏的多框应用程序。本质上,我想在后台运行我创建的应用程序 运行。用户将检查复选框以说明他们想要捕获哪些键,因此并非每个键都被捕获。然后,当他们玩主游戏时,应用程序会在后台将选中的密钥发送到游戏 运行。
我已经尝试过全局热键,但是从来没有一个以上的键可以工作。我也尝试过连接键,但出于某种原因,无法实现该功能。我也涉足了 sendmessage,但运气不佳。
只是想知道是否还有其他人对此有一些想法。举一个做同样事情的另一个程序的例子是 HotKeyNet、KeyClone 和 ISboxer。我知道还有更多,但这让您了解我正在尝试对我的应用程序做什么。
我的建议是 "mapped memory"(在操作系统概念中:共享内存)
第一个进程创建(可能是您的检查状态程序)创建映射内存并将值写入其中。
所有其他游戏进程从第一个进程创建的内存映射中读取值。
这是一个很好的例子,说明如何做。
https://msdn.microsoft.com/en-us/library/dd267552(v=vs.110).aspx
好的,在对发送击键和读取击键的不同方法进行了大量研究之后。我终于能够将不同类型的编码拼接在一起,以提供我正在寻找的结果。
我正在 post 寻找答案,所以任何正在寻找此问题答案的人都可以找到答案。
我将这段代码拼接在一起的两个参考如下:
http://www.codeproject.com/Articles/19004/A-Simple-C-Global-Low-Level-Keyboard-Hook
Send combination of keystrokes to background window
我使用全局低级挂钩和 post消息将击键发送到后台应用程序。
所以首先你需要按照第一个
link,让起始代码正常工作。
从link下载工作源代码,并使用
globalKeyboardHook.cs 在您的申请中。
然后在参考文献中放置以下内容:
using System.Runtime.InteropServices; //Grabs for your DLLs
using Utilities; //Grabs from the file you added to your application.
- 现在您需要将以下代码放入 class:
globalKeyboardHook gkh = new globalKeyboardHook();
[DllImport("user32.dll")] //Used for sending keystrokes to new window.
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Ansi)] //Used to find the window to send keystrokes to.
public static extern IntPtr FindWindow(string className, string windowName);
- 现在开始敲击你想要被抓住的这个我
找到最好的 Form1_Loaded:
gkh.HookedKeys.Add(Keys.A);//This collects the A Key.
gkh.HookedKeys.Add(Keys.B);//This collects the B Key.
gkh.HookedKeys.Add(Keys.C);//This collects the C Key.
gkh.KeyDown += new KeyEventHandler(gkh_KeyDown); //Event for pressing the key down.
gkh.KeyUp += new KeyEventHandler(gkh_KeyUp); //Event for the release of key.
- 之后你会想要继续并放置在以下位置
您的代码也是:
void gkh_KeyUp(object sender, KeyEventArgs e) //What happens on key release.
{
lstLog.Items.Add("Up\t" + e.KeyCode.ToString());
e.Handled = false; //Setting this to true will cause the global hotkeys to block all outgoing keystrokes.
}
void gkh_KeyDown(object sender, KeyEventArgs e) //What happens on key press.
{
lstLog.Items.Add("Down\t" + e.KeyCode.ToString());
e.Handled = false;
}
- 一旦到位,只需将这一点放在 gkh_KeyDown 中即可
让您的击键发送到您选择的另一个 window:
const uint WM_KEYDOWN = 0x100;
IntPtr hWnd = FindWindow(null, "Example1"); //Find window Example1 for application.
switch (e.KeyCode)
{
case Keys.A: //Makes it so it only sends that key when it's pressed and no other keys.
if(chkA.Checked == true)
{
PostMessage(hWnd, WM_KEYDOWN, (IntPtr)(Keys.A), IntPtr.Zero); //Sends to key A to new window assigned hWnd which equals Example1.
}
break;
}
}
我提供的代码已经过设置,因此人们可以使用复选框来告诉程序他们想要将哪些密钥发送到第二个应用程序。
如果您对此 post 有任何疑问,请告诉我,我会尽力引导您完成整个过程。希望这对以后的人有所帮助。
我今天花了六个小时四处寻找方法来完成我想要完成的任务。然而,运气不佳,我尝试过的每一种方法都没有奏效。
所以我正在开发的程序是一个用于视频游戏的多框应用程序。本质上,我想在后台运行我创建的应用程序 运行。用户将检查复选框以说明他们想要捕获哪些键,因此并非每个键都被捕获。然后,当他们玩主游戏时,应用程序会在后台将选中的密钥发送到游戏 运行。
我已经尝试过全局热键,但是从来没有一个以上的键可以工作。我也尝试过连接键,但出于某种原因,无法实现该功能。我也涉足了 sendmessage,但运气不佳。
只是想知道是否还有其他人对此有一些想法。举一个做同样事情的另一个程序的例子是 HotKeyNet、KeyClone 和 ISboxer。我知道还有更多,但这让您了解我正在尝试对我的应用程序做什么。
我的建议是 "mapped memory"(在操作系统概念中:共享内存)
第一个进程创建(可能是您的检查状态程序)创建映射内存并将值写入其中。
所有其他游戏进程从第一个进程创建的内存映射中读取值。
这是一个很好的例子,说明如何做。
https://msdn.microsoft.com/en-us/library/dd267552(v=vs.110).aspx
好的,在对发送击键和读取击键的不同方法进行了大量研究之后。我终于能够将不同类型的编码拼接在一起,以提供我正在寻找的结果。
我正在 post 寻找答案,所以任何正在寻找此问题答案的人都可以找到答案。
我将这段代码拼接在一起的两个参考如下: http://www.codeproject.com/Articles/19004/A-Simple-C-Global-Low-Level-Keyboard-Hook
Send combination of keystrokes to background window
我使用全局低级挂钩和 post消息将击键发送到后台应用程序。
所以首先你需要按照第一个 link,让起始代码正常工作。
从link下载工作源代码,并使用 globalKeyboardHook.cs 在您的申请中。
然后在参考文献中放置以下内容:
using System.Runtime.InteropServices; //Grabs for your DLLs
using Utilities; //Grabs from the file you added to your application.
- 现在您需要将以下代码放入 class:
globalKeyboardHook gkh = new globalKeyboardHook();
[DllImport("user32.dll")] //Used for sending keystrokes to new window.
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Ansi)] //Used to find the window to send keystrokes to.
public static extern IntPtr FindWindow(string className, string windowName);
- 现在开始敲击你想要被抓住的这个我 找到最好的 Form1_Loaded:
gkh.HookedKeys.Add(Keys.A);//This collects the A Key.
gkh.HookedKeys.Add(Keys.B);//This collects the B Key.
gkh.HookedKeys.Add(Keys.C);//This collects the C Key.
gkh.KeyDown += new KeyEventHandler(gkh_KeyDown); //Event for pressing the key down.
gkh.KeyUp += new KeyEventHandler(gkh_KeyUp); //Event for the release of key.
- 之后你会想要继续并放置在以下位置 您的代码也是:
void gkh_KeyUp(object sender, KeyEventArgs e) //What happens on key release.
{
lstLog.Items.Add("Up\t" + e.KeyCode.ToString());
e.Handled = false; //Setting this to true will cause the global hotkeys to block all outgoing keystrokes.
}
void gkh_KeyDown(object sender, KeyEventArgs e) //What happens on key press.
{
lstLog.Items.Add("Down\t" + e.KeyCode.ToString());
e.Handled = false;
}
- 一旦到位,只需将这一点放在 gkh_KeyDown 中即可 让您的击键发送到您选择的另一个 window:
const uint WM_KEYDOWN = 0x100;
IntPtr hWnd = FindWindow(null, "Example1"); //Find window Example1 for application.
switch (e.KeyCode)
{
case Keys.A: //Makes it so it only sends that key when it's pressed and no other keys.
if(chkA.Checked == true)
{
PostMessage(hWnd, WM_KEYDOWN, (IntPtr)(Keys.A), IntPtr.Zero); //Sends to key A to new window assigned hWnd which equals Example1.
}
break;
}
}
我提供的代码已经过设置,因此人们可以使用复选框来告诉程序他们想要将哪些密钥发送到第二个应用程序。
如果您对此 post 有任何疑问,请告诉我,我会尽力引导您完成整个过程。希望这对以后的人有所帮助。