1

グローバルキーボードメッセージをキャプチャする必要があるため、WH_KEYBOARD_LLでSetWindowsHookEx()を使用します。ただし、アプリケーションにフォーカスがある場合にのみ機能し、コールバックをグローバルにトリガーしません。ほぼ同じコードがmouse_LL(別の構造など)でうまく機能します。助けてください!

public const int WH_KEYBOARD_LL = 13;
public const int VK_INSERT = 0x2D;
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
HookProc KeyboardHookProcedure;

[DllImport("user32.dll", CharSet = CharSet.Auto,
   CallingConvention = CallingConvention.StdCall)]
  public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
  IntPtr hInstance, int threadId);

[DllImport("user32.dll", CharSet = CharSet.Auto,
   CallingConvention = CallingConvention.StdCall)]
  public static extern bool UnhookWindowsHookEx(int idHook);

[DllImport("user32.dll", CharSet = CharSet.Auto,
   CallingConvention = CallingConvention.StdCall)]
  public static extern int CallNextHookEx(int idHook, int nCode,
  IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  private static extern IntPtr GetModuleHandle(string lpModuleName);

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

private void SetHookKeyboard()
  {
     if (kHook == 0)
     {
        KeyboardHookLL();

        //If the SetWindowsHookEx function fails.
        if (kHook == 0)
        {
           MessageBox.Show("SetWindowsHookEx Failed");
           return;
        }
        button1.Text = "UnHook Windows Hook";
     }
     else
     {
        bool ret = UnhookWindowsHookEx(kHook);
        //If the UnhookWindowsHookEx function fails.
        if (ret == false)
        {
           MessageBox.Show("UnhookWindowsHookEx Failed");
           return;
        }
        kHook = 0;
        this.Text = "Keyboard Hook";
     }
  }

private void KeyboardHookLL()
  {
     KeyboardHookProcedure = new HookProc(MainForm.KeyboardHookProc);
     kHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure,   GetModuleHandle("user32"), 0);
  }

public static int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
  {
     KBDLLHOOKSTRUCT MyKeyboardHookStruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
     if (nCode < 0)
     {
        return CallNextHookEx(hHook, nCode, wParam, lParam);
     }
     else
     {
        Form tempForm = Form.ActiveForm;
        tempForm.Text = MyKeyboardHookStruct.vkCode.ToString();
        if (MyKeyboardHookStruct.vkCode == VK_INSERT)
        {
           MainForm.botAlive = false;
           MessageBox.Show(MainForm.botAlive.ToString());
        }
        return CallNextHookEx(hHook, nCode, wParam, lParam);
     }
  }
4

2 に答える 2

1

クレジットはここでジョンに行きます:

ハンドルがある場合のintとIntPtr?

私はこれが古い投稿であることを知っています、そして私は少し逸脱します、しかし私は元のコードにちょっと不吉な欠点があることに気づきました。

  [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
  public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

より好ましくは:

  [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
   static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);

他の署名にも同様の変更を加える必要があります。Microsoft自体には、戻り型としてintを使用してSetwindowsHookExを表示するリソースがありますが(https://support.microsoft.com/en-us/kb/318804)、「IntPtr」を他の型に簡単に置き換えることはできません。この場合、「int」は32ビットOSでのみ「IntPtr」と同等です。64ビットプラットフォームでは、「IntPtr」は64ビットですが、「int」は32ビットのままであり、ワームの缶全体を開きます。'int'を使用する場合の最悪の側面の1つは、SetWindowsHookExの戻り値がそれに収まらない場合、おそらくintハンドルが壊れてしまうことです(まれですが、考えられないことではありません)。

これは、アプリケーションの存続期間がフックを解除/破棄するポイントを超えて延長された場合(フック解除呼び出しが最初から機能するわけではありません...)、マウスやキーボードが完全にフリーズする可能性があることを意味しますホストプロセスが強制終了されるまで。ほとんどの人は、その時点でマシンを再起動して、アプリを完全に破棄します。この「キーボード/マウスのフリーズ」はすべて、破棄されていないフックがホストアプリケーションのメッセージポンプに到達する必要があるために発生します。これは、それが属していたコンポーネントが破棄中にバストしたため、明らかに発生しません-wooohoo!

TL; DR:使用しているp / invokeメソッドのシグネチャ、特にIntPtrsに注意してください。

于 2016-03-23T20:43:55.103 に答える
0

問題は「デバッグ」機能にありました。

Form tempForm = Form.ActiveForm;
于 2013-03-29T07:56:47.847 に答える