1

アプリケーションがバックグラウンドで実行されている間に、キープレスを検出し、それに応じて特定のイベントを実行したいと考えています。たとえば、W を押すと、アプリケーションでこれを検出し、「W が押されました」とリストボックスに書き込み、実行中の他のプロセスに影響を与えないようにします。

私が見つけた次のコードは、上で述べたことのほとんどを実行します。唯一の問題は、キープレスを完全に傍受することです。たとえば、Google を開いて「W」と入力すると、その文字は Google 検索バーに表示されませんが、アプリケーションによってフックされます。

namespace WindowsFormsApplication1
{
   public partial class Form1 : Form
   {


     // DLL libraries used to manage hotkeys
     [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);

     const int MYACTION_HOTKEY_ID = 1;


     public Form1()
     {
         InitializeComponent();

         // Modifier keys codes: Alt = 1, Ctrl = 2, Shift = 4, Win = 8
         // Compute the addition of each combination of the keys you want to be pressed
         // ALT+CTRL = 1 + 2 = 3 , CTRL+SHIFT = 2 + 4 = 6...
         RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int)Keys.W);
     }


     protected override void WndProc(ref Message m)
     {
         if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID)
         {
             // My hotkey has been typed

             // Do what you want here
             // ...
             lstLog.Items.Add("W pressed");
         }
         base.WndProc(ref m);
     }
  }
}

つまり、要するに。元のコマンドを維持しながらキープレスをフックする方法を探しています。上記の例では、「W」が Google 検索バーに表示されます。

私はこの(おそらく小さな)問題の解決策を探していて、上記のような公開鍵とフックに関する多くの投稿を見つけましたが、私が望むように実際に機能するものはありませんでした. そこで、ここに初投稿することにしました。皆さんが私を助けてくれることを願っています。不明な点がある場合は、お知らせください。

どうも

-編集-

追加情報: League of Legends、WoW などのゲームをプレイしているときにこのプログラムを使用する予定です。サードパーティ製ソフトウェアの使用が禁止される可能性があるため、これらのゲームのプロセスと相互作用しないようにしたいと思います。これに関して私が知っておくべきことがあれば教えてください。私と私の将来は禁止されていないアカウントをよろしくお願いします。

4

1 に答える 1

0

RegisterHotKeyキーイベントを通過しないため使用できません。

WH_KEYBOARD_LLフックを使用する必要があります。

これは完全に機能するサンプルで、手早く汚れていますが機能します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Diagnostics;


namespace StackoverflowHooks
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);


        [StructLayout(LayoutKind.Sequential)]
        public struct KBDLLHOOKSTRUCT
        {
            public uint vkCode;
            public uint scanCode;
            public uint flags;
            public uint time;
            IntPtr dwExtraInfo;
        }


        IntPtr hHook;
        private delegate IntPtr HookProc(int nCode, IntPtr wp, IntPtr lp);
        HookProc lpfn;

        private IntPtr KeyboardHookProc(int code, IntPtr wParam, IntPtr lParam)
        {
            KBDLLHOOKSTRUCT data = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
            MessageBox.Show("Pressed key: " + (Keys)data.vkCode);

            return CallNextHookEx(hHook, code, wParam, lParam);
        }


        public Form1()
        {
            InitializeComponent();  
            SetHook();
        }

        private void SetHook()
        {
            int id_hook = 13; //WH_KEYBOARD_LL - HOOK
            lpfn = new HookProc(this.KeyboardHookProc);
            using (ProcessModule curModule = Process.GetCurrentProcess().MainModule)
            hHook = SetWindowsHookEx(id_hook, lpfn, GetModuleHandle(curModule.ModuleName), 0);
        }
    }
}
于 2013-10-22T16:59:16.473 に答える