While trying to create an auto clicker application using a Visual Studio Windows Form that allows you to select the hotkey you want, I stumbled upon a problem
When a user inputs keys such as ~ or / the hotkey won't work, However, if I put in 0xC0 (for tilde) or 0xDC (for slash) instead of (int)[tilde] or (int)'/' it will work.
On top of that letters have to be capitalized, but thats ok because I can use ToUpper() to capitalize it
The part that allows the user to select a character is fine and it returns the letter as a string
Heres where I implement RegisterHotKey() and UnregisterHotKey() as well as setup the events for the form:
[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);
}
And this is the code for when the user has selected the key they wanted
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();
}
}
I have a default hotkey CTL + P setup when the program starts The default hotkey works fine but when I type in a key like / into the hotkey selection textbox and set it by clicking a button it will stop the default hotkey from working but when I press the hotkey I just set it won't work. But it works fine with capital A for example
Basically what I'm asking is how can I turn ~ into 0xC0 or / into 0xDC
Any help is appreciated
You will need to use the VkKeyScan
Win32 API function to get the virtual key code of the character.
In your case, then, you will call the VirtualKeyCodeFromChar
function below with your KeyCharacter
just before you call RegisterHotKey
.
It is actually better to use the VkKeyScanEx
function because keyboard layouts differ and so OEM keys may produce different key codes for the same character because of the different layout. But I'll leave you to explore using that function on your own. Meanwhile...
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;
}
}
}