SetWindowsHookEx()
を使用してプログラムでグローバルマウスホットキーを作成しようとしています。これまでのところ私はここで見たような1つの記事のようにそれらを作成しようとしましたが、私は実際にこの方法を知っていません。 問題は現在、_globalMouseHookCallbackが何であるかを正確に知ることができません。wpfでグローバルマウスホットキーを正しく作成する方法
これは私がこれまでに書かれたものです:
class GlobalHotkey
{
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, HookProc callback, IntPtr hInstance, uint threadId);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
internal delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private IntPtr _hGlobalMouseHook;
MainWindow _m;
private const int WH_KEYBOARD_LL = 13;
private const int WH_MOUSE_LL = 14;
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_LBUTTONUP = 0x0202;
private const int WM_RBUTTONDOWN = 0x0204;
private const int WM_RBUTTONUP = 0x0205;
private static IntPtr hook = IntPtr.Zero;
public GlobalHotkey(MainWindow m)
{
_m = m;
}
public void SetUpHook()
{
_m.rtbLog.AppendText("Setting up global Hotkey \n");
_globalMouseHookCallback = LowLevelMouseProc;
_hGlobalMouseHook = SetWindowsHookEx(WH_MOUSE_LL, _globalMouseHookCallback, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
if (_hGlobalMouseHook == IntPtr.Zero)
{
_m.rtbLog.AppendText("Unable to set up global mouse hook\n");
}
}
public void ClearHook()
{
_m.rtbLog.AppendText("Deleting global mouse hook\n");
if (_hGlobalMouseHook != IntPtr.Zero)
{
if (!UnhookWindowsHookEx(_hGlobalMouseHook))
{
_m.rtbLog.AppendText("Unable to delete global mouse hook\n");
}
_hGlobalMouseHook = IntPtr.Zero;
}
}
public int LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
var wmMouse = wParam;
if (wmMouse == (IntPtr)WM_LBUTTONDOWN)
{
_m.rtbLog.AppendText("Right Mouse down");
}
if (wmMouse == (IntPtr)WM_LBUTTONUP)
{
_m.rtbLog.AppendText("Left Mouse up");
}
if (wmMouse == (IntPtr)WM_RBUTTONDOWN)
{
_m.rtbLog.AppendText("Right Mouse down");
}
if (wmMouse == (IntPtr)WM_RBUTTONUP)
{
_m.rtbLog.AppendText("Right Mouse up");
}
}
return CallNextHookEx(_hGlobalMouseHook, nCode, wParam, lParam);
}
}
このグローバルホットキーのものはかなり難しいです私のようなnewbsのためにそれを簡単に説明するチュートリアルのようにあります:P?
EDIT 私はコビーダックスの例を自分のコードに適用しようとしました。
これは私のホットキークラスです:
class GlobalHotkey
{
MainWindow _m;
private static readonly object sSyncObj = new object();
private static readonly HashSet<Key> sDownKeys = new HashSet<Key>();
private static readonly Dictionary<Key, Action> sPressActions = new Dictionary<Key, Action>();
private static readonly Dictionary<Key, Action> sReleaseActions = new Dictionary<Key, Action>();
public GlobalHotkey(MainWindow m)
{
_m = m;
}
public static void ProcessKeyDown(KeyEventArgs args)
{
var key = args.Key;
var action = default(Action);
lock (sSyncObj)
{
if (!sDownKeys.Contains(key))
{
sDownKeys.Add(key);
if (sPressActions.TryGetValue(key, out action))
{
args.Handled = true;
}
}
}
action.Invoke();
}
public static void ProcessKeyUp(KeyEventArgs args)
{
var key = args.Key;
var action = default(Action);
lock (sSyncObj)
{
if (sDownKeys.Remove(key))
{
if (sReleaseActions.TryGetValue(key, out action))
{
args.Handled = true;
}
}
}
action.Invoke();
}
public static void AttachPressAction(Key key, Action action)
{
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
lock (sSyncObj)
{
sPressActions.Add(key, action);
}
}
public static bool DetachPressAction(Key key)
{
lock (sSyncObj)
{
return sPressActions.Remove(key);
}
}
public static void AttachReleaseAction(Key key, Action action)
{
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
lock (sSyncObj)
{
sReleaseActions.Add(key, action);
}
}
public static bool DetachReleaseAction(Key key)
{
lock (sSyncObj)
{
return sReleaseActions.Remove(key);
}
}
}
そして私は自分の行動
public void MyTestAction()
{
rtbLog.AppendText("The B key was pressed");
}
myAction = new Action(MyTestAction);
を作成した。しかし、私はPreviewKeyUp-とダウンイベントに私のEventHandlerを追加するとすぐに、それは私に言って、エラーを与えましたProcessKeyUp-とDownのパラメータは、PreviewKeyUp-とDownと同じではありません。
PreviewKeyDown += GlobalHotkey.ProcessKeyDown;
PreviewKeyUp += GlobalHotkey.ProcessKeyUp;
これは、アプリケーションにフォーカスがない場合でも発生するキーボードイベントとマウスイベントを捕まえたいという意味ですか? –
はい正確には – Celmos
私の更新された回答を見てください。問題は明らかに送信側パラメータを省いたことです。大部分のWindows GUIイベントは、 '(オブジェクト送信者、EventArgs args) '形式です。 –