diff --git a/src/Config.cs b/src/Config.cs new file mode 100755 index 0000000..4efd6fe --- /dev/null +++ b/src/Config.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using System.Xml.Serialization; +using static ProgramLauncherMod.KeyHandling; +using static ProgramLauncherMod.VirtualKeys; + +namespace ProgramLauncherMod +{ + public class Settings + { + public Settings() { } + + public Settings(ProgramMacro[] programMacros) + { + ProgramMacros = programMacros; + } + + public ProgramMacro[] ProgramMacros { get; /*private*/ set; } + + + public static readonly Settings Default = new Settings( + new ProgramMacro[] + { + new ProgramMacro(Mod.Tunnel.DefaultAlias, VKeys.APPS, new KeyModifierData[] { new KeyModifierData("", KeyModifiers.None, KeyboardFlags.None) }, "cmd.exe", "/k \"Welcome to the ProgramLauncher Mod!") + }); + + public static Settings Current = Default; + } + + public class KeyModifierData + { + public KeyModifierData() { } + + public KeyModifierData(string keyboardAlias, KeyModifiers keyModifiers, KeyFlags keyFlags) + { + KeyboardAlias = keyboardAlias; + KeyModifiers = keyModifiers; + } + + public string KeyboardAlias; + public KeyModifiers KeyModifiers; + KeyFlags KeyFlags; + } + + public class KeyData + { + public KeyData() { } + + public KeyData(string keyboardAlias, VKeys vKey) + { + KeyboardAlias = keyboardAlias; + VKey = vKey; + } + + public string KeyboardAlias; + public VKeys VKey; + } + + class Config + { + public static readonly string ConfigDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs"); + public static readonly string AppConfigDir = Path.Combine(ConfigDir, "Application"); + public static readonly string ModConfigDir = Path.Combine(ConfigDir, "Mods"); + public static readonly string ProgramLauncherModConfigDir = Path.Combine(ModConfigDir, "ProgramLauncherMod"); + public static readonly string ProgramLauncherModDefaultConfig = Path.Combine(ProgramLauncherModConfigDir, "ProgramLauncherMod.cfg"); + + public static bool Exists => File.Exists(ProgramLauncherModDefaultConfig); + + public static void Load() + { + + if (Exists) + { + Settings.Current = ReadConfig(); + } + else + { + Directory.CreateDirectory(ProgramLauncherModConfigDir); + SaveConfig(Settings.Current); + } + } + + public static Settings ReadConfig() + { + XmlSerializer xs = new XmlSerializer(typeof(Settings)); + + try + { + + using (TextReader tw = new StreamReader(ProgramLauncherModDefaultConfig)) + { + return (Settings)xs.Deserialize(tw); + } + } + catch (Exception ex) + { + new Thread(() => + { + MessageBox.Show($"Type: {ex.GetType()}\r\nMessage: {ex.Message}\r\n\r\nPlease check the config file for any invalid/misplaced characters and reload the mods before continuing!", + "ProgramLauncher Mod - Execution Error @ ReadConfig (ConfigDeserialize)"); + }).Start(); + } + return null; + } + + public static void SaveConfig(Settings settings, Stream saveStream) + { + XmlSerializer xs = new XmlSerializer(typeof(Settings)); + + xs.Serialize(saveStream, settings); + } + + public static void SaveConfig(Settings settings) + { + using (var f = File.Create(ProgramLauncherModDefaultConfig)) + { + SaveConfig(settings, f); + //return dc; + } + } + } + + public class ProgramMacro + { + public ProgramMacro() { } + // This code might not conform to the MacroBoard latest macro format standards, so it may not work with the latest build of MacroBoard + public ProgramMacro(string keyboardAlias, VKeys vKey, KeyModifierData[] keyModifiers, string programLocation, string programArguments) + { + KeyboardAlias = keyboardAlias; + VKey = vKey; + KeyModifiers = keyModifiers; + ProgramLocation = programLocation; + ProgramArguments = programArguments; + } + + public string KeyboardAlias; + public VKeys VKey; + public KeyModifierData[] KeyModifiers; + public string ProgramLocation; + public string ProgramArguments; + + } +} diff --git a/src/KeyHandling.cs b/src/KeyHandling.cs new file mode 100755 index 0000000..37b11da --- /dev/null +++ b/src/KeyHandling.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ProgramLauncherMod +{ + public class KeyHandling + { + [Flags] + public enum KeyModifiers + { + None = 0, + LShift = 1 << 0, + RShift = 1 << 1, + LControl = 1 << 2, + RControl = 1 << 3, + LAlt = 1 << 4, + RAlt = 1 << 5 + } + + [Flags] + public enum KeyFlags + { + None = 0, + Up = 1, + KeyE0 = 2, + KeyE1 = 4 + } + } +} diff --git a/src/KeyboardData.cs b/src/KeyboardData.cs new file mode 100755 index 0000000..2ab2667 --- /dev/null +++ b/src/KeyboardData.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ProgramLauncherMod +{ + public class KeyboardData + { + //Passed data from "RawInputKeyboardData" + + public readonly uint ExtraInformation; + public readonly int Flags; + public readonly int ScanCode; + public readonly int VirtualKey; + public readonly uint WindowMessage; + + //Custom made data + + //The string passed when the key is pressed to tell the mod what keyboard it was sent from. + public readonly string KeyboardAlias; + + //Determine if any key modifiers are presed. + public readonly int KeyModifiers; + + public KeyboardData(string keyboardAlias, int keyModifiers, uint extraInformation, int flags, int scanCode, int virtualKey, uint windowMessage) + { + KeyboardAlias = keyboardAlias; + KeyModifiers = keyModifiers; + ExtraInformation = extraInformation; + Flags = flags; + ScanCode = scanCode; + VirtualKey = virtualKey; + WindowMessage = windowMessage; + } + + [Flags] + public enum RawKeyboardFlags : ushort + { + None = 0, + Up = 1 << 0, + KeyE0 = 1 << 1, + KeyE1 = 1 << 2, + } + } +} diff --git a/src/Mod.cs b/src/Mod.cs new file mode 100755 index 0000000..5e40969 --- /dev/null +++ b/src/Mod.cs @@ -0,0 +1,73 @@ +using System; +using System.Diagnostics; +using static ProgramLauncherMod.KeyHandling; +using static ProgramLauncherMod.VirtualKeys; + +namespace ProgramLauncherMod +{ + public class Mod + { + public void Call(long wParam, long lParam, params dynamic[] args) + { + HandleKey(wParam, lParam, args); + } + + + private dynamic HostWindow; + + //Static may cause an exception. + public static dynamic Tunnel; + public void Init(dynamic tunnelInstance) + { + Tunnel = tunnelInstance; + HostWindow = Tunnel.HostWindow; + + Config.Load(); + } + + public void Reload() + { + Config.Load(); + } + + public void Closing() + { + Config.SaveConfig(Settings.Current); + } + + + // This code might not conform to the MacroBoard latest HandkeKey format standards, so it may not work with the latest build of MacroBoard + public void HandleKey(long wParam, long lParam, params dynamic[] args) + { + // Note: Working on new KeyModifiers, and adding KeyboardAliases + + //try + //{ + + KeyboardData keybdData = (KeyboardData)args[0]; + + + //Tunnel.WriteDebugLine("KeyModifiers (int): " + (int)keyModifiers + " - KeyModifiers Flags: - LShift: " + keyModifiers.HasFlag(KeyModifiers.LShift) + " RShift: " + keyModifiers.HasFlag(KeyModifiers.RShift) + " RControl: " + keyModifiers.HasFlag(KeyModifiers.RControl) + " LControl: " + keyModifiers.HasFlag(KeyModifiers.LControl) + " RAlt: " + keyModifiers.HasFlag(KeyModifiers.RAlt) + " LAlt: " + keyModifiers.HasFlag(KeyModifiers.LAlt)); + //} + //catch (Exception e) + //{ + // Tunnel.ShowMessageBox(e.Message, "ProgramLauncherMod - Error", 0, 64); + //} + + + + bool keyPressed = ((ulong)lParam & 0x80000000) == 0 ? true : false; + + if (!keyPressed) + return; + + foreach (var keyCommands in Settings.Current.ProgramMacros) + { + if (keyCommands.VKey == (VKeys)wParam && keyCommands.KeyModifiers == keybdData.KeyModifiers) + { + Process.Start(new ProcessStartInfo() { FileName = keyCommands.ProgramLocation, Arguments = keyCommands.ProgramArguments, UseShellExecute = true }); + } + } + } + } +} diff --git a/src/ProgramLauncherMod.csproj b/src/ProgramLauncherMod.csproj new file mode 100755 index 0000000..4232637 --- /dev/null +++ b/src/ProgramLauncherMod.csproj @@ -0,0 +1,13 @@ + + + + netcoreapp3.1 + + + + + C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Windows.Forms.dll + + + + diff --git a/src/ProgramLauncherMod.sln b/src/ProgramLauncherMod.sln new file mode 100755 index 0000000..df18eb5 --- /dev/null +++ b/src/ProgramLauncherMod.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31112.23 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProgramLauncherMod", "ProgramLauncherMod.csproj", "{24A4D8AB-4F88-41CE-9617-EC5FE4F35F01}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1AD5FBB0-1FB9-4F76-8397-8BC42E06C1C0}" + ProjectSection(SolutionItems) = preProject + Class1.cs = Class1.cs + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {24A4D8AB-4F88-41CE-9617-EC5FE4F35F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24A4D8AB-4F88-41CE-9617-EC5FE4F35F01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {24A4D8AB-4F88-41CE-9617-EC5FE4F35F01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {24A4D8AB-4F88-41CE-9617-EC5FE4F35F01}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {36B2EE33-5EA9-4856-858C-8E93546E42A8} + EndGlobalSection +EndGlobal diff --git a/src/VirtualKeys.cs b/src/VirtualKeys.cs new file mode 100755 index 0000000..8208176 --- /dev/null +++ b/src/VirtualKeys.cs @@ -0,0 +1,216 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace ProgramLauncherMod +{ + public class VirtualKeys + { + /// + /// Virtual Keys + /// + public enum VKeys + { + // Losely based on http://www.pinvoke.net/default.aspx/Enums/VK.html + + LBUTTON = 0x01, // Left mouse button + RBUTTON = 0x02, // Right mouse button + CANCEL = 0x03, // Control-break processing + MBUTTON = 0x04, // Middle mouse button (three-button mouse) + XBUTTON1 = 0x05, // Windows 2000/XP: X1 mouse button + XBUTTON2 = 0x06, // Windows 2000/XP: X2 mouse button + // 0x07 // Undefined + BACK = 0x08, // BACKSPACE key + TAB = 0x09, // TAB key + // 0x0A-0x0B, // Reserved + CLEAR = 0x0C, // CLEAR key + RETURN = 0x0D, // ENTER key + // 0x0E-0x0F, // Undefined + SHIFT = 0x10, // SHIFT key + CONTROL = 0x11, // CTRL key + MENU = 0x12, // ALT key + PAUSE = 0x13, // PAUSE key + CAPITAL = 0x14, // CAPS LOCK key + KANA = 0x15, // Input Method Editor (IME) Kana mode + HANGUL = 0x15, // IME Hangul mode + // 0x16, // Undefined + JUNJA = 0x17, // IME Junja mode + FINAL = 0x18, // IME final mode + HANJA = 0x19, // IME Hanja mode + KANJI = 0x19, // IME Kanji mode + // 0x1A, // Undefined + ESCAPE = 0x1B, // ESC key + CONVERT = 0x1C, // IME convert + NONCONVERT = 0x1D, // IME nonconvert + ACCEPT = 0x1E, // IME accept + MODECHANGE = 0x1F, // IME mode change request + SPACE = 0x20, // SPACEBAR + PRIOR = 0x21, // PAGE UP key + NEXT = 0x22, // PAGE DOWN key + END = 0x23, // END key + HOME = 0x24, // HOME key + LEFT = 0x25, // LEFT ARROW key + UP = 0x26, // UP ARROW key + RIGHT = 0x27, // RIGHT ARROW key + DOWN = 0x28, // DOWN ARROW key + SELECT = 0x29, // SELECT key + PRINT = 0x2A, // PRINT key + EXECUTE = 0x2B, // EXECUTE key + SNAPSHOT = 0x2C, // PRINT SCREEN key + INSERT = 0x2D, // INS key + DELETE = 0x2E, // DEL key + HELP = 0x2F, // HELP key + KEY_0 = 0x30, // 0 key + KEY_1 = 0x31, // 1 key + KEY_2 = 0x32, // 2 key + KEY_3 = 0x33, // 3 key + KEY_4 = 0x34, // 4 key + KEY_5 = 0x35, // 5 key + KEY_6 = 0x36, // 6 key + KEY_7 = 0x37, // 7 key + KEY_8 = 0x38, // 8 key + KEY_9 = 0x39, // 9 key + // 0x3A-0x40, // Undefined + KEY_A = 0x41, // A key + KEY_B = 0x42, // B key + KEY_C = 0x43, // C key + KEY_D = 0x44, // D key + KEY_E = 0x45, // E key + KEY_F = 0x46, // F key + KEY_G = 0x47, // G key + KEY_H = 0x48, // H key + KEY_I = 0x49, // I key + KEY_J = 0x4A, // J key + KEY_K = 0x4B, // K key + KEY_L = 0x4C, // L key + KEY_M = 0x4D, // M key + KEY_N = 0x4E, // N key + KEY_O = 0x4F, // O key + KEY_P = 0x50, // P key + KEY_Q = 0x51, // Q key + KEY_R = 0x52, // R key + KEY_S = 0x53, // S key + KEY_T = 0x54, // T key + KEY_U = 0x55, // U key + KEY_V = 0x56, // V key + KEY_W = 0x57, // W key + KEY_X = 0x58, // X key + KEY_Y = 0x59, // Y key + KEY_Z = 0x5A, // Z key + LWIN = 0x5B, // Left Windows key (Microsoft Natural keyboard) + RWIN = 0x5C, // Right Windows key (Natural keyboard) + APPS = 0x5D, // Applications key (Natural keyboard) + // 0x5E, // Reserved + SLEEP = 0x5F, // Computer Sleep key + NUMPAD0 = 0x60, // Numeric keypad 0 key + NUMPAD1 = 0x61, // Numeric keypad 1 key + NUMPAD2 = 0x62, // Numeric keypad 2 key + NUMPAD3 = 0x63, // Numeric keypad 3 key + NUMPAD4 = 0x64, // Numeric keypad 4 key + NUMPAD5 = 0x65, // Numeric keypad 5 key + NUMPAD6 = 0x66, // Numeric keypad 6 key + NUMPAD7 = 0x67, // Numeric keypad 7 key + NUMPAD8 = 0x68, // Numeric keypad 8 key + NUMPAD9 = 0x69, // Numeric keypad 9 key + MULTIPLY = 0x6A, // Multiply key + ADD = 0x6B, // Add key + SEPARATOR = 0x6C, // Separator key + SUBTRACT = 0x6D, // Subtract key + DECIMAL = 0x6E, // Decimal key + DIVIDE = 0x6F, // Divide key + F1 = 0x70, // F1 key + F2 = 0x71, // F2 key + F3 = 0x72, // F3 key + F4 = 0x73, // F4 key + F5 = 0x74, // F5 key + F6 = 0x75, // F6 key + F7 = 0x76, // F7 key + F8 = 0x77, // F8 key + F9 = 0x78, // F9 key + F10 = 0x79, // F10 key + F11 = 0x7A, // F11 key + F12 = 0x7B, // F12 key + F13 = 0x7C, // F13 key + F14 = 0x7D, // F14 key + F15 = 0x7E, // F15 key + F16 = 0x7F, // F16 key + F17 = 0x80, // F17 key + F18 = 0x81, // F18 key + F19 = 0x82, // F19 key + F20 = 0x83, // F20 key + F21 = 0x84, // F21 key + F22 = 0x85, // F22 key, (PPC only) Key used to lock device. + F23 = 0x86, // F23 key + F24 = 0x87, // F24 key + // 0x88-0X8F, // Unassigned + NUMLOCK = 0x90, // NUM LOCK key + SCROLL = 0x91, // SCROLL LOCK key + // 0x92-0x96, // OEM specific + // 0x97-0x9F, // Unassigned + LSHIFT = 0xA0, // Left SHIFT key + RSHIFT = 0xA1, // Right SHIFT key + LCONTROL = 0xA2, // Left CONTROL key + RCONTROL = 0xA3, // Right CONTROL key + LMENU = 0xA4, // Left MENU key + RMENU = 0xA5, // Right MENU key + BROWSER_BACK = 0xA6, // Windows 2000/XP: Browser Back key + BROWSER_FORWARD = 0xA7, // Windows 2000/XP: Browser Forward key + BROWSER_REFRESH = 0xA8, // Windows 2000/XP: Browser Refresh key + BROWSER_STOP = 0xA9, // Windows 2000/XP: Browser Stop key + BROWSER_SEARCH = 0xAA, // Windows 2000/XP: Browser Search key + BROWSER_FAVORITES = 0xAB, // Windows 2000/XP: Browser Favorites key + BROWSER_HOME = 0xAC, // Windows 2000/XP: Browser Start and Home key + VOLUME_MUTE = 0xAD, // Windows 2000/XP: Volume Mute key + VOLUME_DOWN = 0xAE, // Windows 2000/XP: Volume Down key + VOLUME_UP = 0xAF, // Windows 2000/XP: Volume Up key + MEDIA_NEXT_TRACK = 0xB0,// Windows 2000/XP: Next Track key + MEDIA_PREV_TRACK = 0xB1,// Windows 2000/XP: Previous Track key + MEDIA_STOP = 0xB2, // Windows 2000/XP: Stop Media key + MEDIA_PLAY_PAUSE = 0xB3,// Windows 2000/XP: Play/Pause Media key + LAUNCH_MAIL = 0xB4, // Windows 2000/XP: Start Mail key + LAUNCH_MEDIA_SELECT = 0xB5, // Windows 2000/XP: Select Media key + LAUNCH_APP1 = 0xB6, // Windows 2000/XP: Start Application 1 key + LAUNCH_APP2 = 0xB7, // Windows 2000/XP: Start Application 2 key + // 0xB8-0xB9, // Reserved + OEM_1 = 0xBA, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the ';:' key + OEM_PLUS = 0xBB, // Windows 2000/XP: For any country/region, the '+' key + OEM_COMMA = 0xBC, // Windows 2000/XP: For any country/region, the ',' key + OEM_MINUS = 0xBD, // Windows 2000/XP: For any country/region, the '-' key + OEM_PERIOD = 0xBE, // Windows 2000/XP: For any country/region, the '.' key + OEM_2 = 0xBF, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the '/?' key + OEM_3 = 0xC0, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the '`~' key + // 0xC1-0xD7, // Reserved + // 0xD8-0xDA, // Unassigned + OEM_4 = 0xDB, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the '[{' key + OEM_5 = 0xDC, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the '\|' key + OEM_6 = 0xDD, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the ']}' key + OEM_7 = 0xDE, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key + OEM_8 = 0xDF, // Used for miscellaneous characters; it can vary by keyboard. + // 0xE0, // Reserved + // 0xE1, // OEM specific + OEM_102 = 0xE2, // Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard + // 0xE3-E4, // OEM specific + PROCESSKEY = 0xE5, // Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key + // 0xE6, // OEM specific + PACKET = 0xE7, // Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP + // 0xE8, // Unassigned + // 0xE9-F5, // OEM specific + ATTN = 0xF6, // Attn key + CRSEL = 0xF7, // CrSel key + EXSEL = 0xF8, // ExSel key + EREOF = 0xF9, // Erase EOF key + PLAY = 0xFA, // Play key + ZOOM = 0xFB, // Zoom key + NONAME = 0xFC, // Reserved + PA1 = 0xFD, // PA1 key + OEM_CLEAR = 0xFE // Clear key + } + } +}