C#プラグインシステムでホットキーを使いこなす

こんにちは親愛なるホーカー!



この記事では、ホットキーを使用して一部のアクションを高速化および簡素化するプログラムを作成した方法を示します。



エントリー



約1か月半前、ユーザーvvzvladが、ホットキーを押してさまざまなテキストを翻訳するプログラムのアイデアを促しました。 私はこのプログラムを非常に長い間使用していましたが、数日前にそれを改善するアイデアがありました。

異なるアクションに異なるホットキーを割り当てる機能を追加することにしました。 このために、プラグインシステムを使用しました。

その結果、HotKeyHelperプログラムが作成されます 。これは、 こちらからダウンロードできます



画像



プロジェクトファイルはこちらです。



カットの下に、プログラムのソースコードとその説明が表示されます。





プログラム





上記で書いたように、プラグインシステムを使用することにしました。



これを行うには、プラグインインターフェイスを記述する必要があります。



public delegate void PluginHandler(string text); /// <summary> ///     /// </summary> public interface IPlugin { /// <summary> ///   /// </summary> string Name { get; } /// <summary> ///        /// </summary> bool NeedSelectedText { get;} /// <summary> ///    /// </summary> /// <param name="parametres"> </param> /// <param name="text">  </param> void MainMethod(string parametres,string text); event PluginHandler ShowBaloonHandler; event PluginHandler ShowFormHandler; event PluginHandler PasteTextHandler; }
      
      







そして、プラグインをロードするためのメソッドを書きます:



  private void LoadPlugins() { //    string sPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); ; //       .dll foreach (string f in System.IO.Directory.GetFiles(sPath, "*.dll")) { System.Reflection.Assembly a = System.Reflection.Assembly.LoadFile(f); try { foreach (Type t in a.GetTypes()) { foreach (Type i in t.GetInterfaces()) { //     IPlugin if (i.Equals(Type.GetType("HotKeyHelper.IPlugin"))) { //          IPlugin p = (IPlugin)Activator.CreateInstance(t); p.ShowBaloonHandler += ShowBaloon; p.ShowFormHandler += ShowForm; p.PasteTextHandler += PasteText; comboBox1.Items.Add(p.Name); Plugins.Add(p); break; } } } } catch (Exception) { continue; } } }
      
      







また、WinApiメソッドを呼び出す必要があります。そのために、それらをインポートします。



  [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); [DllImport("User32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); [DllImport("user32.dll", SetLastError = true)] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
      
      







そして、いくつかのプラグインの機能を実行するために必要な2つのメソッドを書きます



  /// <summary> ///   Ctrl+C /// </summary> void CtrlCEmul() { keybd_event(0x11, 0, 0, 0); keybd_event((byte)'C', 0, 0, 0); keybd_event((byte)'C', 0, 0x2, 0); keybd_event(0x11, 0, 0x2, 0); } /// <summary> ///   Ctrl+V /// </summary> void CtrlVEmul() { keybd_event(0x11, 0, 0, 0); keybd_event((byte)'V', 0, 0, 0); keybd_event((byte)'V', 0, 0x2, 0); keybd_event(0x11, 0, 0x2, 0); }
      
      







また、カスタムホットキーを保存するためのクラスを作成します。

 public class HotKey { /// <summary> ///   /// </summary> public string Plugin { get; set; } /// <summary> ///     /// </summary> public string Parametres { get; set; } /// <summary> ///   /// </summary> public string Key { get; set; } /// <summary> ///   /// </summary> public uint KeyCode { get; set; } /// <summary> ///   /// </summary> public string Modificators { get; set; } /// <summary> ///   /// </summary> public uint ModificatorsCode { get; set; } /// <summary> ///   /// </summary> /// <param name="path">   </param> /// <returns> </returns> public static List<HotKey> LoadHotKeys(string path) { List<HotKey> hotKeys = new List<HotKey>(); if (File.Exists(path)) foreach (string line in File.ReadAllLines(path)) { string[] parametres = line.Split(new string[] { "<!>" }, StringSplitOptions.None); hotKeys.Add(new HotKey() { Plugin = parametres[0], Parametres = parametres[1], Key = parametres[2], KeyCode = UInt32.Parse(parametres[3]), Modificators = parametres[4], ModificatorsCode = UInt32.Parse(parametres[5]) }); } return hotKeys; } /// <summary> ///   /// </summary> /// <param name="hotKeys"> </param> /// <param name="path">   </param> public static void SaveHotKeys(List<HotKey> hotKeys, string path) { List<string> parametres = new List<string>(); foreach (HotKey hotKey in hotKeys) { parametres.Add(String.Format("{0}<!>{1}<!>{2}<!>{3}<!>{4}<!>{5}", new object[]{hotKey.Plugin,hotKey.Parametres,hotKey.Key,hotKey.KeyCode, hotKey.Modificators,hotKey.ModificatorsCode})); } File.WriteAllLines(path, parametres); } }
      
      







プラグインをロードした後、カスタムホットキーをダウンロードしてサブスクライブできます。



  HotKeys = HotKey.LoadHotKeys("HotKeys.txt"); //       for (int i = 0; i < HotKeys.Count; i++) { if (!RegisterHotKey(this.Handle, i, HotKeys[i].ModificatorsCode, HotKeys[i].KeyCode)) { notifyIcon1.BalloonTipText = String.Format(" {0} {1}  ", HotKeys[i].Modificators, HotKeys[i].Key); notifyIcon1.ShowBalloonTip(10000); } }
      
      







ホットキーにサインアップすると、WM_HOTKEYメッセージがウィンドウに送信されます。 ユーザーが必要な組み合わせをクリックしたタイミングを確認するには、メソッドを書き換える必要があります。

  protected override void WndProc(ref Message m) { //  WM_HOTKEY if (m.Msg == 0x0312) { //       int id = (int)m.WParam; IPlugin plugin = Plugins.SingleOrDefault(pl => pl.Name == HotKeys[id].Plugin); if (plugin == null) { notifyIcon1.Text = "   "; notifyIcon1.ShowBalloonTip(10000); return; } string text = ""; if(plugin.NeedSelectedText) { //  Ctrl+C CtrlCEmul(); //,       Thread.Sleep(150); //..       ,      for (int i = 0; i < 10; i++) { try { //    text = Clipboard.GetText(); break; } catch (ExternalException) { } Thread.Sleep(100); } } //   try { plugin.MainMethod(HotKeys[id].Parametres,text); } catch (Exception ex) { notifyIcon1.Text = "    "+ex.Message; notifyIcon1.ShowBalloonTip(10000); } return; } base.WndProc(ref m); }
      
      







ホットキーを作成するためのより便利なインターフェイスを追加するだけです。 これでは、面白いことは何もないと思いますが、押した組み合わせを記録するシステムをどのように作成したかを示します。

これを行うには、KeyDownおよびKeyUpフォームのイベントをサブスクライブする必要があります。



  private void button1_Click(object sender, EventArgs e) { if (button1.Enabled) { button1.Enabled = false; isRecord = true; } } //     private void Form1_KeyDown(object sender, KeyEventArgs e) { //     "" if (isRecord) { //    modKeys = e.Modifiers; key = e.KeyCode; //     if (e.Alt) modifiers = 1; if (e.Control) modifiers = 2; if (e.Shift) modifiers = 4; if (e.Alt && e.Control) modifiers = 3; if (e.Alt && e.Shift) modifiers = 5; if (e.Control && e.Shift) modifiers = 6; if (e.Alt && e.Control && e.Shift) modifiers = 7; label1.Text = modKeys.ToString(); label2.Text = key.ToString(); } } //    private void Form1_KeyUp(object sender, KeyEventArgs e) { if (isRecord) { //    DialogResult result = MessageBox.Show(String.Format(" : {0} {1}",label1.Text,label2.Text), "", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) isRecord = false; } }
      
      







まあ、それだけです。 プログラムの準備ができました。 使用を開始するためのプラグインを作成するだけです。



プラグイン



プログラムでプラグインを使用するには、IPluginからメインクラスを継承する必要があります。

これを行うには、プログラムへのリンクを追加する必要があります。 これで、簡単なプラグインの実装を作成できます。 たとえば、選択したテキストをpastebin.comに投稿するプラグインを作成しました。
  public class PastebinSender : IPlugin { public string Name { get { return "PastebinSender"; } } public bool NeedSelectedText { get { return true; } } public event PluginHandler ShowBaloonHandler; public event PluginHandler ShowFormHandler; public event PluginHandler PasteTextHandler; /// <summary> ///   /// </summary> /// <param name="parametres">   "     :  :  "</param> /// <param name="text">  </param> public void MainMethod(string parametres, string text) { string[] param = parametres.Split(':'); bool useMessage = param[0] == "1"; string format = param[1]; string expire = param[2]; using (HttpRequest request = new HttpRequest()) { MultipartDataCollection reqParams = new MultipartDataCollection(); //   - request.UserAgent = HttpHelper.RandomChromeUserAgent(); string cont = request.Get("http://pastebin.com").ToText(); string postKey = cont.Substring("post_key\" value=\"", "\""); reqParams.AddData("post_key", postKey); reqParams.AddData("submit_hidden", "submit_hidden"); reqParams.AddData("paste_code", text); reqParams.AddData("paste_format", format); reqParams.AddData("paste_expire_date", expire); reqParams.AddData("paste_private", "1"); reqParams.AddData("paste_name", ""); //     string link = request.Post("http://pastebin.com/post.php", reqParams).Address.AbsoluteUri; if (useMessage) { ShowFormHandler(link); } else { ShowBaloonHandler(link); } } } }
      
      







これらのHTTP要求用プラグインでは、 xNetを使用しました



選択したテキストを翻訳するためのプラグインも作成しました。

  public class GoogleTranslator : IPlugin { public string Name { get { return "GoogleTranslator"; } } public bool NeedSelectedText { get { return true; } } public event PluginHandler ShowBaloonHandler; public event PluginHandler ShowFormHandler; public event PluginHandler PasteTextHandler; /// <summary> ///   /// </summary> /// <param name="parametres">   "   :     "</param> /// <param name="text">  </param> public void MainMethod(string parametres, string text) { //   string[] param = parametres.Split(':'); string ToLang = param[0]; bool useMessage = param[1] == "1"; //     ::,       string[] message = text.Split(new string[] { "::" }, StringSplitOptions.None); if (message.Length != 2) { //     if (isRussian(text)) { //     string translate = GetTranslate(text, ToLang); PasteTextHandler(translate); } //      else { //    string translate = GetTranslate(text, "ru"); //     if (useMessage) { ShowFormHandler(translate); } else { ShowBaloonHandler(translate); } } } //    ::,       else { string mess = message[1]; string toLang = message[0]; //     string translate = GetTranslate(mess, toLang); PasteTextHandler(translate); } } private string GetTranslate(string message, string toLang) { //      - using (HttpRequest request = new HttpRequest()) { StringDictionary reqParams = new StringDictionary(); //   - request.UserAgent = HttpHelper.RandomChromeUserAgent(); reqParams["tl"] = toLang; reqParams["sl"] = "auto"; reqParams["client"] = "x"; string translate = ""; ShowBaloonHandler("..."); reqParams["text"] = message; //    string s = request.Get( "http://translate.google.ru/translate_a/t", reqParams).ToText(); //      string[] ts = s.Substrings("trans\":\"", "\","); foreach (string t in ts) { string tr = t; if (tr.Contains('\"')) { tr = tr.Replace("\\", ""); } //  if (translate != "") { translate = translate + " " + tr; } else { translate = tr; } } return translate; } } bool isRussian(string text) { foreach (char c in text) { if ((c >= '' && c <= '')) return true; } return false; } }
      
      







プラグインを作成してコンパイルしたら、プログラムと共に1つのフォルダーに配置する必要があります。次回起動するときに、このプラグインの実行を特定のホットキーに「バインド」できます。



All Articles