문제

화면에 그리기 위해 제 3 자 앱을 연결하려고합니다. 화면에 그리기가 쉽고 도움이 필요하지 않지만 사용에 문제가있는 것 같습니다. SetWindowsHookEx 다루다 WH_GETMESSAGE. 마지막 두 매개 변수에 대해 무엇을 전달 해야하는지 알 수 없습니다.

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;

namespace WindowDrawer
{
    public partial class Form1 : Form
    {
        private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
        static IntPtr hHook;
        IntPtr windowHandle;
        uint processHandle;

        HookProc PaintHookProcedure;     

        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        static extern System.IntPtr FindWindowByCaption(int ZeroOnly, string lpWindowName);

        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowsHookEx", SetLastError = true)]
        static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        // When you don't want the ProcessId, use this overload and pass IntPtr.Zero for the second parameter
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        [System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet =System.Runtime.InteropServices.CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        { 
            PaintHookProcedure = new HookProc(PaintHookProc);
            windowHandle = FindWindowByCaption(0, "Untitled - Notepad");
            uint threadID = GetWindowThreadProcessId(windowHandle, out processHandle);
            IntPtr hMod = System.Runtime.InteropServices.Marshal.GetHINSTANCE(typeof(Form1).Module);

            // HERE IS THE PROBLEM.  WHAT THE HECK DO I PASS INTO THE LAST 2 PARAMS?  I get a null pointer
            hHook = SetWindowsHookEx(WH_GETMESSAGE, PaintHookProcedure, hMod, threadID);
        }

        public int PaintHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
           // Do some painting here.
            return CallNextHookEx(hHook, nCode, wParam, lParam); 
        }

        private const int WM_PAINT = 15;
        private const int WH_GETMESSAGE = 3;
    }
}
도움이 되었습니까?

해결책

setwindowshookex 따라서 마지막 두 매개 변수를 세부 사항 :

  • hMod

LPFN 매개 변수가 가리키는 후크 절차를 포함하는 DLL에 대한 [in]. dwthreadid 매개 변수가 현재 프로세스에 의해 생성 된 스레드를 지정하고 후크 프로 시저가 현재 프로세스와 관련된 코드 내에있는 경우 hmod 매개 변수를 null로 설정해야합니다.

  • dwThreadId

in]은 후크 절차가 연관 될 스레드의 식별자를 지정합니다. 이 매개 변수가 0 인 경우 후크 절차는 호출 스레드와 동일한 데스크탑에서 실행되는 모든 기존 스레드와 관련됩니다.

필요한 방식으로 .NET DLL을 사용할 수는 없지만 확실히 시도 할 수 있습니다.

붙잡다 hMod ~을 통해 Marshal.gethinstance (typeof (form1). 모듈) 그리고 dwThreadId ~을 통해 프로세스. 스레드. 또는 설정하십시오 dwThreadId 글로벌 훅을 원한다면 0에서 0까지 (즉, 모두를위한 후크 GetMessage() 현재 데스크탑에서 호출) 그러나 성능 처벌을 조심하십시오.

다른 팁

다음은 이것이 작동하지 않는다는 것을 암시합니다.

.

에서 "Visual C# .net에서 Windows 후크를 설정하는 방법"

나는 당신이 p/호출해야한다고 생각합니다 GetModuleHandle 그리고 세 번째 매개 변수에 대해 반환하는 핸들을 사용합니다. SetWindowsHookEx. 나는 또한 믿는다 0 제 3 자 애플리케이션에서 특정 스레드를 연결하고 싶지 않기 때문에 네 번째 매개 변수에 맞습니다.

이것이 당신에게 효과가 없다면 SetWindowsHookEx MSDN에서 올바른 방향을 가리킬 수 있습니다.

모르겠지만 API가 "다른 프로세스에 DLL을 주입"하는 것처럼 원하는 매개 변수 값을 사용하는 경우 관리되지 않은 DLL을 작성하는 경우에만 효과가있을 수 있습니다. 그것을 부를 수 있습니다.

나는 이것이 오래된 질문이라는 것을 알고 있지만 여전히 유용한 사람이 있기를 바라고 있습니다. 나는 당신이 섞이고 있다고 생각합니다 int 그리고 IntPtr

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

이 작업은 13 ...

 private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(13, proc,
                GetModuleHandle(curModule.ModuleName), 0);
            }
        }
  internal enum HookType : uint {
    WH_JOURNALRECORD = 0,
    WH_JOURNALPLAYBACK = 1,
    WH_KEYBOARD = 2,
    WH_GETMESSAGE = 3,
    WH_CALLWNDPROC = 4,
    WH_CBT = 5,
    WH_SYSMSGFILTER = 6,
    WH_MOUSE = 7,
    WH_HARDWARE = 8,
    WH_DEBUG = 9,
    WH_SHELL = 10,
    WH_FOREGROUNDIDLE = 11,
    WH_CALLWNDPROCRET = 12,
    WH_KEYBOARD_LL = 13,
    WH_MOUSE_LL = 14
  }

.NET 프레임 워크에서는 글로벌 후크가 지원되지 않습니다

wh_keyboard_ll 저급 후크 및 wh_mouse_ll 저급 후크를 제외하고 Microsoft .NET Framework에서 글로벌 후크를 구현할 수 없습니다.

글로벌 후크를 설치하려면 후크에는 유효하고 일관된 기능을 호출 해야하는 다른 프로세스에 자체적으로 DLL 내보내기가 있어야합니다. 이 동작에는 DLL 내보내기가 필요합니다.

.NET 프레임 워크는 DLL 내보내기를 지원하지 않습니다. 관리되는 코드는 함수 포인터에 대한 일관된 값의 개념이 없습니다. 이러한 기능 포인터는 동적으로 구축 된 프록시이기 때문입니다.

후크를 설치 한 스레드에서 낮은 수준의 후크 절차가 호출됩니다. 낮은 수준의 후크는 후크 절차를 DLL에서 구현할 필요가 없습니다.

또한보십시오:탐정 -WPF 스파이 유틸리티

또는 내 wpf => wf => win32 ll_keyboard 후크 프록시 w/ gestures

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top