0

マウスの左ボタンを押したまま、マウスの左ボタンを1回クリックするアプリを実行しています(したがって、基本的にクリックを続ける必要はありません)。マウスイベントにフックしてlbダウン/アップイベントをリッスンする小さなテストアプリを作成しました。ただし、アプリはデスクトップ上の任意の場所でのマウスクリックをリッスンします。特定のプロセスだけをリッスンさせる方法はありますか?

これが私がマウスクリックをリッスンするために使用しているテストアプリです:

class Program
{
        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
        private static LowLevelMouseProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;
        private static bool _leftButtonDown;

        public static void Main()
        {
            _hookID = SetHook(_proc);
            Application.Run();
            UnhookWindowsHookEx(_hookID);
        }

        private static IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        private static IntPtr HookCallback(
            int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 &&
                MouseMessages.WM_LBUTTONUP == (MouseMessages)wParam)
            {
                _leftButtonDown = false;
                Console.WriteLine(_leftButtonDown);
            }

            if (nCode >= 0 &&
                MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
            {
                _leftButtonDown = true;
                Console.WriteLine(_leftButtonDown);
                StartTest();
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private static void StartTest()
        {
            Task.Factory.StartNew(() =>
                {
                    while (_leftButtonDown)
                    {
                        Console.WriteLine("SENDING");
                    }
                });
        }

        private const int WH_MOUSE_LL = 14;

        private enum MouseMessages
        {
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x0202
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

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

        [DllImport("User32.dll")]
        public static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] input, int structSize);

        [StructLayout(LayoutKind.Sequential)]
        public struct MOUSEINPUT
        {
            public int dx;
            public int dy;
            public uint mouseData;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct KEYBDINPUT
        {
            public ushort wVk;
            public ushort wScan;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct HARDWAREINPUT
        {
            uint uMsg;
            ushort wParamL;
            ushort wParamH;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct INPUT
        {
            [FieldOffset(0)]
            public int type;
            [FieldOffset(4)] //*
            public MOUSEINPUT mi;
            [FieldOffset(4)] //*
            public KEYBDINPUT ki;
            [FieldOffset(4)] //*
            public HARDWAREINPUT hi;
        }
    }
4

1 に答える 1

1

引数の4番目SetWindowsHookEx()の引数をdwThreadId選択的に使用できます。監視したいプロセスのGUIスレッドのスレッドIDを渡す必要があります。GetWindowThreadProcessId()たとえば、プロセスが所有するウィンドウの1つのハンドルがある場合は、値を取得します。それが独自のプロセスである場合は、を使用してくださいGetCurrentThreadId()。Winformsアプリの場合はIMessageFilter、フックではなく優先します。

于 2012-10-05T17:18:01.980 に答える