[英]configurable hotkeys for button presses c#
我正在寻找一种方法,以便使用我的程序的用户可以自己更改热键,使其不绑定到D,F12,K,F,A等。我有点希望ppl可以通过文本框或通过设置文件。 现在被困在它上面几周了,我只是找不到实现它的方法,这是我第一个正在开发的程序。
public void gHook_KeyDown(object sender, KeyEventArgs e) { switch (e.KeyCode) { case Keys.D: // stuff Salvagebtn.PerformClick(); break; case Keys.F12: // stuff pausebtn.PerformClick(); break; case Keys.K: //stuff Geardropbtn.PerformClick(); break; case Keys.F: //stuff Gamblebtn.PerformClick(); break; case Keys.A: //stuff LeftClickSpambtn.PerformClick(); break; case Keys.H: // stuff openGRbtn.PerformClick(); break; case Keys.B: //stuff gemupbtn.PerformClick(); break; } }
在广告期间,我花了几分钟。 因此,我写了以下内容:
编辑:用全局键盘处理程序包装的代码。 您还需要添加对PresentationCore和WindowsBase的引用。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Windows.Input;
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll")]
static extern int MapVirtualKey(uint uCode, uint uMapType);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100,
WM_KEYUP = 0x0101,
S_WM_KEYDOWN = 0x0104,
S_WM_KEYUP = 0x0105;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private static Form1 hookForm;
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
static bool bShortcutPressed;
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (hookForm.Handle != GetForegroundWindow())
{
if (nCode >= 0 && ((wParam == (IntPtr)WM_KEYDOWN) || (wParam == (IntPtr)S_WM_KEYDOWN)))
{
int vkCode = Marshal.ReadInt32(lParam);
bool bCtrl = (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl));
bool bAlt = (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt));
bool bShift = (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift));
Keys hookKey = (Keys)vkCode;
hookKey = (bCtrl) ? ((Keys.Control | hookKey)) : hookKey;
hookKey = (bAlt) ? ((Keys.Alt | hookKey)) : hookKey;
hookKey = (bShift) ? ((Keys.Shift | hookKey)) : hookKey;
Debug.Print($"hookKey {hookKey} {bCtrl} {bAlt} {bShift}");
if (!bShortcutPressed && dicTest.ContainsValue(hookKey))
{
hookForm.OnKeyDown(new System.Windows.Forms.KeyEventArgs(hookKey));
bShortcutPressed = true; Debug.Print($"{bShortcutPressed}");
}
}
if (nCode >= 0 && (((wParam == (IntPtr)WM_KEYUP) || (wParam == (IntPtr)S_WM_KEYUP)))) { bShortcutPressed = false; Debug.Print($"{bShortcutPressed}"); }
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
static Dictionary<string, Keys> dicTest = new Dictionary<string, Keys>();
public void AddHotKey(Action function, Keys key, bool ctrl = false, bool shift = false, bool alt = false)
{
KeyDown += delegate (object sender, System.Windows.Forms.KeyEventArgs e) { if (IsHotkey(e, key, ctrl, shift, alt)) { function(); } };
}
public bool IsHotkey(System.Windows.Forms.KeyEventArgs eventData, Keys key, bool ctrl = false, bool shift = false, bool alt = false) =>
eventData.KeyCode == key && eventData.Control == ctrl && eventData.Shift == shift && eventData.Alt == alt;
public Form1() => InitializeComponent();
private void Form1_Load(object sender, EventArgs e)
{
_hookID = SetHook(_proc);
hookForm = this;
KeyPreview = true;
String[] names = Enum.GetNames(typeof(Keys));
foreach (string key in names) { comboBox1.Items.Add(key); }
comboBox1.SelectedItem = comboBox1.Items[0];
KeyDown += Form1_KeyDown;
}
private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
Debug.Print($"Form1_KeyDown : {e.KeyData}");
}
protected override void OnFormClosing(FormClosingEventArgs e) => UnhookWindowsHookEx(_hookID);
private void button1_Click(object sender, EventArgs e)
{
Keys hookKey = (Keys)Enum.Parse(typeof(Keys), comboBox1.Text);
hookKey = (checkBox1.Checked) ? ((Keys.Control | hookKey)) : hookKey;
hookKey = (checkBox2.Checked) ? ((Keys.Alt | hookKey)) : hookKey;
hookKey = (checkBox3.Checked) ? ((Keys.Shift | hookKey)) : hookKey;
if (!dicTest.ContainsValue(hookKey))
{
Debug.Print($"Going to add : {hookKey} : to our Shortcut Dictionary<>");
dicTest.Add("test", hookKey);
AddHotKey(() => { button2.PerformClick(); }, (Keys)new KeysConverter().ConvertFrom(comboBox1.Text), checkBox1.Checked, checkBox3.Checked, checkBox2.Checked);
//checkBox1.Enabled = checkBox2.Enabled = checkBox3.Enabled = comboBox1.Enabled = button1.Enabled = false;
label2.Text = "Go ahead and tryout your Shortcut now ...";
}
else { label2.Text = "Shortcut key is already stored in our Dictionary<> ..."; }
}
private void button2_Click(object sender, EventArgs e) { Debug.Print($"Button2 was clicked"); }
}
}
您将看到:
试用所需的快捷方式:
仅举例说明,有很多方法可以做事情。
易于将它们写到文件或其他内容中。 如果要...我将把AddHotKey Action参数更改为包含函数名称的字符串,然后使用其他方法,可以让它调用该函数。
确实,我将合并一个词典,如下面所讨论的。
您可以采用多种不同的方式来处理此问题。 就个人而言,我会选择使用“ Dictionary
,将“键码”作为“键”,并将“委托/动作”作为值。 然后在按键上,您只需在与该按键代码关联的字典中调用该函数即可。 类似于以下内容:
Dictionary<KeyCode, System.Action> keyDict = new Dictionary<KeyCode, System.Action>();
// populate it however you wish. Whether it's user entry or from a file or something.
keyDict.Add(KeyCode.D, SomeFunction);
如果要更改字典中的委托,请执行以下操作:
keyDict[KeyCode.D] = SomeOtherFunction;
然后在事件处理程序中:
public void gHook_KeyDown(object sender, KeyEventArgs e)
{
keyDict[e.KeyCode].Invoke();
}
public void SomeFunction()
{
Console.WriteLine("called some function");
}
(如果需要,此问题可能会更详细: 在C#中使用动态键创建字典 )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.