1

我在记事本的 Edit 类上设置了 SetWindowsHookEx,但我不确定如何从这里继续。

我希望将 Edit 类子类化为我自己的过程,然后操作文本或将其保存到文件中,然后必须将其发回记事本控件/类。

有更简单的方法可以从记事本中获取文本,但我正在尝试学习 WINAPI 和子类化,所以这对我来说是学习它的好方法。

我的 SetWindowsHookEx 看起来像这样:

SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll, npThreadId); 

如何使用钩子类型:WH_GETMESSAGE从记事本中的 Edit 类中获取文本并将其传输到我的 GetMsgProc(I think) 函数?

它是正确的钩子类型吗?

我给它发消息吗?如果是,我该怎么做?

我的代码如下所示:

dllHeader.h:

#ifdef DLLAPI
#else
#define DLLAPI extern "C" __declspec(dllimport)
#endif
DLLAPI bool hookNotepad();

dll.cpp:

#include "stdafx.h"
#include <windows.h>
#define DLLAPI extern "C" __declspec(dllexport)
#include "dllHeader.h"

// Forward references
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);

// Global variables
HHOOK g_hHook = NULL;        // Hook for Notepad 'EDIT' class
HINSTANCE g_hInstDll = NULL; // DllMain entry (DLL_PROCESS_ATTACH)
HWND npHWND = NULL;          // Notepad handle
DWORD npThreadId = NULL;     // Notepad thread ID
HWND npeHWND = NULL;         // Notepad 'EDIT' class handle


BOOL APIENTRY DllMain(HMODULE hModule,  DWORD ul_reason_for_call,  LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        g_hInstDll = hModule;
        break;

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

bool hookNotepad ()
{
    npHWND = FindWindow(TEXT("Notepad"), NULL); // Finds Notepad

    if (npHWND) //Notepad found
    {
        npeHWND = FindWindowEx(npHWND, NULL, L"Edit", NULL); // Finds the 'EDIT' class in notepad
        npThreadId = GetWindowThreadProcessId(npeHWND, NULL); //Find ThreadID for Notepad 'EDIT' class
        g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll, npThreadId); //Set hook in Notepad 'EDIT' class

        if (g_hHook) //if the hook is a succes then...
        { 
            MessageBox(NULL,TEXT("Hook set in Notepad EDIT class!"), NULL, MB_OK); 
            // Now what? How to subclass the npeHWND (The 'EDIT' class of Notepad) to my own procedure? 
        }
        else
        {
            MessageBox(NULL,TEXT("SetWindowsHookEx error!"), NULL, MB_OK); //If the hook fails.
        }
    }
    return 0;
}

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) 
{
    if (nCode >= 0)
    {
        MessageBox(NULL,TEXT("This never get called. Why?"), NULL, MB_OK);
    }
    return(CallNextHookEx(g_hHook, nCode, wParam, lParam));
}

exe文件

#include <stdlib.h>
#include "stdafx.h"
#include <strsafe.h>

#include "C:\Users\Kristensen\Documents\Visual Studio 2012\Projects\dll\dll\dllHeader.h"

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) 
{

    hookNotepad();
    return 0;
}

我对如何从这里开始有点迷茫……有什么提示吗?链接?提示?

我已经阅读了 MSDN 上关于SetWindowsHookEx函数的文档——但我没有在那里找到明确的答案。

4

1 回答 1

2

WH_GETMESSAGE当钩子线程调用GetMessage()PeekMessage()从其消息队列中检索消息时调用,但并非所有消息都通过消息队列,因此您可能还必须使用WH_CALLWNDPROC/RET钩子,具体取决于您尝试拦截的消息类型。

您的全局变量需要存储在一块共享内存中,否则它们只能被安装挂钩的进程访问,因为在挂钩其他进程时会加载 DLL 的新副本。

您不能将HWND属于另一个进程的子类化。您必须将代码注入该进程,然后该代码可以根据需要在本地进行子类化。 SetWindowsHookEx()可用于将代码注入其他进程,但CreateRemoteThread()根据您的需要,可能会更好地使用它。

于 2013-05-09T02:26:17.060 回答