SetWindowsHookEx,标识鼠标指向的窗口对话框

时间:2017-03-15 03:08:40

标签: c++ winapi hook setwindowshookex

这是我与setWindowsHookEx相关的另一个问题,我编写了一个小型应用程序来将dll挂钩到窗口calculator applicatio中。基本上,exe应用程序将dll注入calculator并监视计算器应用程序中发生的所有鼠标停止事件。目前,我可以禁用计算器上发生的所有鼠标按下事件。但是,我想根据鼠标指向的位置完成它。具体来说,当鼠标按钮单击特定菜单栏项目时。我试图通过使用GetWindowText来检索按钮指向的文本来完成此操作,但大多数时候它返回窗口文本而不是它指向的窗口项(menu item)。以下是我为此编写的代码。如何禁用菜单栏上的特定窗口元素。

调用SetWindowsHookEx的EXE代码

// program.exe.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include <string>
#include  <io.h>

using namespace std;

void Usage()
{
    printf("Usage: InjectDLL pid path-to-dll [-privilege]");
}


int _tmain(int argc, char* argv[])
{

    /*
    * Load library in which we'll be hooking our functions.
    */
    HMODULE dll = LoadLibrary(L"C:\\drivers\\dllinject.dll");
    if (dll == NULL) {
        printf("The DLL could not be found.\n");
        getchar();
        return -1;
    }

    /*
    * Get the address of the function inside the DLL.
    * _hookmethod@12 is used to hook into 32bit applications
    */
    //HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "_hookmethod@12");
    HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "hookmethod");
    if (addr == NULL) {
        printf("The function was not found.\n");
        getchar();
        return -1;
    }

    /*
    * Hook the function.
    */
    DWORD procID=0;

    HWND targetWnd = FindWindowA("CalcFrame", "Calculator");


    wchar_t msgBuf[1024] = L"";
    wchar_t msgBuf2[1024] = L"";
    wsprintf(msgBuf, L"the thread Id is :  %d , process id is  : %d ", threadID, procID);

    OutputDebugString(msgBuf);

    //
    //WH_KEYBOARD_LL 
    HHOOK handle = SetWindowsHookEx(WH_GETMESSAGE, addr, dll, threadID);
    //HHOOK handle = SetWindowsHookEx(WH_CALLWNDPROC, addr, dll, threadID);
    //HHOOK handle = SetWindowsHookEx(WH_MSGFILTER, addr, dll, threadID);
    DWORD x = GetLastError();
    wsprintf(msgBuf2, L"the last error is %d", x);
    OutputDebugString(msgBuf2);
    if (handle == NULL) {
        printf("The KEYBOARD could not be hooked.\n");
    }
    else{
        printf("Program successfully hooked.\nPress enter to unhook the function and stop the program.\n");
    }

    /*
    * Unhook the function.
    */

    getchar();
    UnhookWindowsHookEx(handle);

    return 0;
}

用于阻止点击菜单栏项目的dll。

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>

static HWND s_hWndButton;

INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {

    switch (Reason) {
    case DLL_PROCESS_ATTACH:
        OutputDebugString(L"DLL attach function called11.\n");
        break;
    case DLL_PROCESS_DETACH:
        OutputDebugString(L"DLL detach function called.\n");
        break;
    case DLL_THREAD_ATTACH:
        OutputDebugString(L"DLL thread attach function called.\n");
        break;
    case DLL_THREAD_DETACH:
        OutputDebugString(L"DLL thread detach function called.\n");
        break;
    }

    return TRUE;
}

extern "C" __declspec(dllexport) LRESULT  __stdcall hookmethod(int code, WPARAM wParam, LPARAM lParam) {

    TCHAR   msgBuftext[65536];
    TCHAR   msgBufhandle[65536];
    TCHAR   msgBufhandletext[65536];
    TCHAR   msgBufwintext[2048];
    if (code >= 0) {
        MSG* cp = (MSG*)lParam;
        int txtlen = GetWindowTextLengthW(cp->hwnd);
        GetWindowText(cp->hwnd, msgBufhandletext, txtlen);

        wsprintf(msgBufhandle, L"Handle %X", cp->hwnd);
        wsprintf(msgBufwintext, L"Window Text %s", msgBufhandletext);

        LPMSG msg = (LPMSG)lParam;

        if (msg->message == WM_LBUTTONDOWN) {
            OutputDebugString(msgBufwintext);

            msg->message = WM_NULL;

        }

    }

    return(CallNextHookEx(NULL, code, wParam, lParam));
}

1 个答案:

答案 0 :(得分:0)

对于那些感兴趣的人,我想发布我能够实现的答案。基本上,我没有收听WH_GETMESSAGE,而是将钩链更改为WH_MSGFILTER。原因是,它允许我在菜单项上移动鼠标时找到菜单项ID,当按钮启动事件发生时,我可以通过将消息更改为WM_NULL来检查菜单项ID并禁用鼠标单击。以下是工作代码示例。如果用户是navigat,它还可以阻止事件

dll代码

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <Winuser.h>
#include <Lmcons.h>
#include "nxlrunner.h"

WORD wMenuItemID;


INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {

    switch (Reason) {
    case DLL_PROCESS_ATTACH:
        OutputDebugString(L"DLL attach function called11.\n");
        break;
    case DLL_PROCESS_DETACH:
        OutputDebugString(L"DLL detach function called.\n");
        break;
    case DLL_THREAD_ATTACH:
        OutputDebugString(L"DLL thread attach function called.\n");
        break;
    case DLL_THREAD_DETACH:
        OutputDebugString(L"DLL thread detach function called.\n");
        break;
    }

    return TRUE;
}

extern "C" __declspec(dllexport) LRESULT  __stdcall meconnect(int code, WPARAM wParam, LPARAM lParam) {

    switch (code)
    {
        case MSGF_MENU: // message is for a menu
        {
            MSG* pMSG = (MSG*)lParam;

            switch (pMSG->message)
            {
                case WM_MENUSELECT:
                {

                    wMenuItemID = LOWORD(pMSG->wParam);
                    break;
                }
                case WM_LBUTTONDOWN:
                {
                    break;
                }

                case WM_LBUTTONUP:
                {
                    if (wMenuItemID == 10353){
                        wchar_t usernamew[UNLEN];
                        DWORD username_len = UNLEN + 1;
                        GetUserNameW(usernamew, &username_len);
                        MessageBoxW(NULL, usernamew, L"Title", MB_OK);
                        pMSG->message = WM_NULL;
                    }
                    break;
                }                   
                case WM_LBUTTONDBLCLK:
                {
                    if (wMenuItemID == 10353){
                        pMSG->message = WM_NULL;
                    }
                    break;
                }
                case WM_KEYDOWN:
                {
                    switch (pMSG->wParam)
                    {
                        case VK_RETURN:
                        {
                            if (wMenuItemID == 10353){
                                MessageBoxW(NULL, L"Message to user", L"Title.", MB_OK);
                                pMSG->message = WM_NULL;


                            }
                            break;
                        }
                    }

                    break;
                }
                case WM_KEYUP:
                {


                    switch (pMSG->wParam)
                    {
                    case VK_RETURN:
                    {
                        if (wMenuItemID == 10353){
                            MessageBoxW(NULL, L"Message to user", L"Title", MB_OK);
                            pMSG->message = WM_NULL;


                        }
                        break;
                    }
                    }
                    break;
                }

            }

            break;
        }

    }



    return false;
}

windows hooking

system message hooks

Call MSG Filter function

msg structure

sample code

keyboard codes

sample code from internet