C# Registerhotkey() 不会读取一些键码
C# Registerhotkey() won't read some keycodes
在尝试使用 Visual Studio Windows 允许您 select 您想要的热键的表单创建自动答题器应用程序时,我偶然发现了一个问题
当用户输入 ~ 或 / 等键时,热键将不起作用,但是,如果我输入 0xC0 (对于波浪号)或 0xDC(对于斜线)而不是 (int)[波浪号] 或 (int)'/' 它会起作用。
最重要的是,字母必须大写,但这没关系,因为我可以使用 ToUpper() 将其大写
允许用户 select 字符的部分很好,它 returns 字母作为字符串
这里是我实现 RegisterHotKey() 和 UnregisterHotKey() 以及设置表单事件的地方:
[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);
protected override void WndProc(ref Message m) {
if (m.Msg == 0x0312 && m.WParam.ToInt32() == 1)
{
toggleClicker(); //This turns my autoclicker off and on
}
base.WndProc(ref m);
}
public Form1(){
InitializeComponent();
/* Ignore this:
VersionText.Text = "Version " + version;
comboBox1.SelectedIndex = 0;
*/
RegisterHotKey(this.Handle, 1, 0x0002, (int)Keys.P); //This is the default and it works just fine
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
UnregisterHotKey(this.Handle, 1);
}
这是当用户select输入他们想要的密钥时的代码
private void button2_Click(object sender, EventArgs e)
{
/*Ignore this
if (isClickerRunning)
{
//Console.WriteLine("Stopping...");
clickerThread.Abort();
isClickerRunning = false;
}
*/
int Prefix = 0;
//Set Prefix to the value chosen in the combobox
if (comboBox1.SelectedIndex == 1) { Prefix = 0x0002; } //Ctrl
if (comboBox1.SelectedIndex == 2) { Prefix = 0x0004; } //Shift
if (comboBox1.SelectedIndex == 3) { Prefix = 0x0001; } //Alt
if (comboBox1.SelectedIndex == 4) { Prefix = 0x0002 + 0x0004; } //Ctrl + Shift
if (comboBox1.SelectedIndex == 5) { Prefix = 0x0002 + 0x0001; } //Ctrl + Alt
if (comboBox1.SelectedIndex == 6) { Prefix = 0x0002 + 0x0001 + 0x0004; } //Ctrl + Alt + Shift
bool Success1 = UnregisterHotKey(this.Handle, 1);
bool Success2 = RegisterHotKey(this.Handle, 1, prefix, (int)KeyCharacter); //KeyCharacter is the key that the user has selected
//Test if RegisterHotKey and UnregisterHotKey failed
if(Success1 == false || Success2 == false)
{
//Set the hotkey back to default if it failed
Success1 = UnregisterHotKey(this.Handle, 1);
Success2 = RegisterHotKey(this.Handle, 1, 0x0002, (int)Keys.P);
}
//Test if it failed again
if(Success1 == false || Success2 == false)
{
MessageBox.Show("FATAL ERROR!\nCould not register hotkey. Quiting...", "FATAL ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
程序启动时我有一个默认热键 CTL + P 设置
默认热键工作正常,但是当我在热键 selection 文本框中输入 / 之类的键并通过单击按钮进行设置时,它将停止默认热键工作但是当我按下我刚刚设置的热键时,它不起作用。但它适用于大写字母 A,例如
基本上我要问的是如何将 ~ 变成 0xC0 或 / 变成 0xDC
感谢任何帮助
您需要使用VkKeyScan
Win32 API函数来获取角色的虚拟键码。
在您的情况下,您将在调用 RegisterHotKey
.
之前使用 KeyCharacter
调用下面的 VirtualKeyCodeFromChar
函数
实际上使用VkKeyScanEx
功能更好,因为键盘布局不同,因此OEM键可能会因为布局不同而对同一字符产生不同的键码。但我会让您自行探索使用该功能。同时...
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ConsoleApp1
{
class Program
{
[DllImport("user32.dll")] static extern short VkKeyScan(char c);
static void Main(string[] args)
{
var s = "~|-.";
foreach(var c in s)
{
var key = VirtualKeyCodeFromChar(c);
Console.WriteLine($"{c}, {key}, 0x{key:X}\n");
}
Console.ReadKey();
}
static int VirtualKeyCodeFromChar(char c)
{
var composite = VkKeyScan(c);
byte keyCode = (byte)(composite & 255);
byte shiftState = (byte)((composite >> 8) & 255);
Keys key = (Keys)keyCode;
if ((shiftState & 1) != 0) key |= Keys.Shift;
if ((shiftState & 2) != 0) key |= Keys.Control;
if ((shiftState & 4) != 0) key |= Keys.Alt;
return (int)key;
}
}
}
在尝试使用 Visual Studio Windows 允许您 select 您想要的热键的表单创建自动答题器应用程序时,我偶然发现了一个问题
当用户输入 ~ 或 / 等键时,热键将不起作用,但是,如果我输入 0xC0 (对于波浪号)或 0xDC(对于斜线)而不是 (int)[波浪号] 或 (int)'/' 它会起作用。
最重要的是,字母必须大写,但这没关系,因为我可以使用 ToUpper() 将其大写
允许用户 select 字符的部分很好,它 returns 字母作为字符串
这里是我实现 RegisterHotKey() 和 UnregisterHotKey() 以及设置表单事件的地方:
[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);
protected override void WndProc(ref Message m) {
if (m.Msg == 0x0312 && m.WParam.ToInt32() == 1)
{
toggleClicker(); //This turns my autoclicker off and on
}
base.WndProc(ref m);
}
public Form1(){
InitializeComponent();
/* Ignore this:
VersionText.Text = "Version " + version;
comboBox1.SelectedIndex = 0;
*/
RegisterHotKey(this.Handle, 1, 0x0002, (int)Keys.P); //This is the default and it works just fine
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
UnregisterHotKey(this.Handle, 1);
}
这是当用户select输入他们想要的密钥时的代码
private void button2_Click(object sender, EventArgs e)
{
/*Ignore this
if (isClickerRunning)
{
//Console.WriteLine("Stopping...");
clickerThread.Abort();
isClickerRunning = false;
}
*/
int Prefix = 0;
//Set Prefix to the value chosen in the combobox
if (comboBox1.SelectedIndex == 1) { Prefix = 0x0002; } //Ctrl
if (comboBox1.SelectedIndex == 2) { Prefix = 0x0004; } //Shift
if (comboBox1.SelectedIndex == 3) { Prefix = 0x0001; } //Alt
if (comboBox1.SelectedIndex == 4) { Prefix = 0x0002 + 0x0004; } //Ctrl + Shift
if (comboBox1.SelectedIndex == 5) { Prefix = 0x0002 + 0x0001; } //Ctrl + Alt
if (comboBox1.SelectedIndex == 6) { Prefix = 0x0002 + 0x0001 + 0x0004; } //Ctrl + Alt + Shift
bool Success1 = UnregisterHotKey(this.Handle, 1);
bool Success2 = RegisterHotKey(this.Handle, 1, prefix, (int)KeyCharacter); //KeyCharacter is the key that the user has selected
//Test if RegisterHotKey and UnregisterHotKey failed
if(Success1 == false || Success2 == false)
{
//Set the hotkey back to default if it failed
Success1 = UnregisterHotKey(this.Handle, 1);
Success2 = RegisterHotKey(this.Handle, 1, 0x0002, (int)Keys.P);
}
//Test if it failed again
if(Success1 == false || Success2 == false)
{
MessageBox.Show("FATAL ERROR!\nCould not register hotkey. Quiting...", "FATAL ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
程序启动时我有一个默认热键 CTL + P 设置 默认热键工作正常,但是当我在热键 selection 文本框中输入 / 之类的键并通过单击按钮进行设置时,它将停止默认热键工作但是当我按下我刚刚设置的热键时,它不起作用。但它适用于大写字母 A,例如
基本上我要问的是如何将 ~ 变成 0xC0 或 / 变成 0xDC
感谢任何帮助
您需要使用VkKeyScan
Win32 API函数来获取角色的虚拟键码。
在您的情况下,您将在调用 RegisterHotKey
.
KeyCharacter
调用下面的 VirtualKeyCodeFromChar
函数
实际上使用VkKeyScanEx
功能更好,因为键盘布局不同,因此OEM键可能会因为布局不同而对同一字符产生不同的键码。但我会让您自行探索使用该功能。同时...
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ConsoleApp1
{
class Program
{
[DllImport("user32.dll")] static extern short VkKeyScan(char c);
static void Main(string[] args)
{
var s = "~|-.";
foreach(var c in s)
{
var key = VirtualKeyCodeFromChar(c);
Console.WriteLine($"{c}, {key}, 0x{key:X}\n");
}
Console.ReadKey();
}
static int VirtualKeyCodeFromChar(char c)
{
var composite = VkKeyScan(c);
byte keyCode = (byte)(composite & 255);
byte shiftState = (byte)((composite >> 8) & 255);
Keys key = (Keys)keyCode;
if ((shiftState & 1) != 0) key |= Keys.Shift;
if ((shiftState & 2) != 0) key |= Keys.Control;
if ((shiftState & 4) != 0) key |= Keys.Alt;
return (int)key;
}
}
}