SetWindowsHookEx()函数的第四个参数到底是什么意思呢?查看了许多资料都把它解释成线程ID.请问这个ID只能是本程序线程ID呢还是允许设置成其他程序的线程ID?现在我能够对本身的程序设置鼠标钩子,使鼠标失效,也能够通过编写动态连接库,设置ID为0,安装一个全局的钩子,屏蔽所有程序的鼠标消息。
    请问大家能否对专门一个程序安装钩子?根据我的理解,我用IceSword查出了其他程序的线程ID,设置为第四个参数,可一点效果都没有。就拿记事本程序做实验,我查出它是单线程的。不论我把第四个参数设置成它的进程ID还是线程ID都不起作用。(都采用了dll,程序没有问题,全局钩子都可以实现,仅仅改变了ID)
    思考了原因我有以下疑问:
    1.难道SetWindowsHookEx()函数只能为本身安装钩子或者安装全局钩子?不能为其他单个程序安装钩子?
    2.我知道进程ID是系统唯一的,但是线程ID是在某一个进程内唯一,还是在整个操作系统内唯一?
    3.说了那么多废话,前面大家可以不理,只要求实现一个事情:打开记事本窗口,通过编写一个钩子屏蔽记事本的键盘或鼠标消息,要求只能屏蔽记事本范围内的,不允许写全局钩子屏蔽所有程序的。也就是说,只有记事本接收不到鼠标和键盘消息,其他的程序不受影响.无论大家是自己写还是转贴,贴源代码也好,说思想也好,经测试能实现的100分送出。

解决方案 »

  1.   

    1.为其他单个程序安装钩子,设置第三个参数hMod为需要设置的应用程序的实例句柄,dwThreadId设为空
    2.进程线程id都是系统唯一的
    3。SetWindowsHookEx(WH_KEYBOARD|WH_MOUSE,lpfn,hMod,NULL)
            hmod为记事本程序的实例句柄
      

  2.   

    1、不能。
    2、系统唯一。
    3、可以这样试试:Hook全局键盘和鼠标事件,键盘函数中判断当前活动窗口,鼠标函数根据鼠标位置判断窗口,然后再GetWindowThreadProcessId获得窗口所属进程ID,判断出是记事本时直接返回非0值。
      

  3.   


    你测试成功了?
    hMod 
    Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process. 
    hMod是动态链接库实例的句柄,不是要挂钩的程序实例句柄。
      

  4.   

    1 全局的钩子可以用GetModuleFileName判断当前进程是不是你要钩的进程
    2 操作系统内唯一
    3 见1
      

  5.   


    hmod为记事本模块的实例句柄,即记事本可执行文件模块句柄
      

  6.   

    SetWindowsHookEx()貌似可以为某个程序安装钩子啊,我都是这么干的
    hMod为你要插入的Dll的句柄,dwThreadId为目标线程的Id(一般是目标进程的主线程)
    dwThreadId一般使用GetWindowThreadProcessId的返回值
      

  7.   

    HINSTANCE表示的是该模块在进程内的开始地址,不能用它来识别进程,我所见过的EXE模块的HINSTANCE都是0x400000。
      

  8.   

    用GetWindowThreadProcessId得到该窗口的线程的id,其他第三方软件查的可能不准。
    你可以先FindWindowEx到记事本的句柄。
      

  9.   

    WH_MOUSE不能针对其它进程的某个线程,但是WH_GETMESSAGE可以
    Hook.h
    #ifdef HOOK_EXPORTS
    #define HOOK_API __declspec(dllexport)
    #else
    #define HOOK_API __declspec(dllimport)
    #endif#define WM_HOOK WM_USER + 1HOOK_API BOOL SetHook(HWND hWindow, DWORD dwThreadId);
    HOOK_API BOOL UnHook();Hook.cpp
    #include "stdafx.h"
    #include "Hook.h"#pragma data_seg("HookShared")
    HHOOK hHook = NULL;
    HWND hWnd = NULL;
    #pragma data_seg()
    #pragma comment(linker, "/SECTION:HookShared,RWS")HINSTANCE hMod;BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
     )
    {
    hMod = (HINSTANCE)hModule;
        switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    break;
        }
        return TRUE;
    }LRESULT WINAPI HookProc(int code, WPARAM wParam, LPARAM lParam)
    {
    PMSG pMsg = (PMSG)lParam;
    if (pMsg->message == WM_MOUSEMOVE)
    SendMessage(hWnd, WM_HOOK, pMsg->wParam, pMsg->lParam);
    return CallNextHookEx(hHook, code, wParam, lParam);
    }HOOK_API BOOL SetHook(HWND hWindow, DWORD dwThreadId)
    {
    hWnd = hWindow;
    hHook = SetWindowsHookEx(WH_GETMESSAGE, HookProc, hMod, dwThreadId);
    return hHook != NULL;
    }HOOK_API BOOL UnHook()
    {
    hWnd = NULL;
    return UnhookWindowsHookEx(hHook);
    }
      

  10.   

    HostDlg.h
    class CHostDlg : public CDialog
    {
    // Construction
    public:
    CHostDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data
    //{{AFX_DATA(CHostDlg)
    enum { IDD = IDD_HOST_DIALOG };
    CEdit m_EdtWnd;
    //}}AFX_DATA // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CHostDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
    //}}AFX_VIRTUAL// Implementation
    protected:
    HICON m_hIcon; // Generated message map functions
    //{{AFX_MSG(CHostDlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg void OnBtnStart();
    afx_msg void OnBtnStop();
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    //}}AFX_MSG
    afx_msg LRESULT OnHookMsg(WPARAM wParam, LPARAM lParam);
    DECLARE_MESSAGE_MAP()
    };HostDlg.cpp
    void CHostDlg::OnBtnStart() 
    {
    // TODO: Add your control notification handler code here
    this->SetCapture();
    m_EdtWnd.SetWindowText(_T("单击任意窗体"));
    }void CHostDlg::OnLButtonUp(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    ::ReleaseCapture();
    POINT pt;
    ::GetCursorPos(&pt);
    HWND hWnd = ::WindowFromPoint(pt);
    TCHAR szCaption[128];
    ::GetWindowText(hWnd, szCaption, 127);
    DWORD dwThreadId = ::GetWindowThreadProcessId(hWnd, NULL);
    if (dwThreadId != 0)
    {
    if (SetHook(this->m_hWnd, dwThreadId))
    StrCat(szCaption, _T("-钩挂成功"));
    else
    StrCat(szCaption, _T("-钩挂失败"));
    m_EdtWnd.SetWindowText(szCaption);
    }
    CDialog::OnLButtonUp(nFlags, point);
    }LRESULT CHostDlg::OnHookMsg(WPARAM wParam, LPARAM lParam)
    {
    POINT pt;
    TCHAR szInfo[128];
    ::GetCursorPos(&pt);
    wsprintf(szInfo, "鼠标位置:X:%d Y:%d", pt.x, pt.y);
    m_EdtWnd.SetWindowText(szInfo);
    return 0;
    }void CHostDlg::OnBtnStop() 
    {
    // TODO: Add your control notification handler code here
    UnHook();
    m_EdtWnd.SetWindowText(NULL);
    }
    那些MFC自动生成的我就没贴了
    m_EdtWnd是个文本框、BtnStart和BtnStop是两个按钮,没其它东西了,资源文件就不贴了
      

  11.   

    记得加上ON_MESSAGE(WM_HOOK, OnHookMsg)这句消息映射,这个忘贴了
      

  12.   


    钻石级的就是牛叉啊,GetModuleFlieName判断一下果然搞定。