子类记事本的编辑类(WINAPI)

时间:2013-05-08 21:36:31

标签: winapi callback subclass setwindowshookex

我在记事本的编辑类上设置了一个SetWindowsHookEx,但我不知道如何从这里继续。

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

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

我的SetWindowsHookEx看起来像这样:

SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll, npThreadId); 

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

它是否是正确的钩子类型?

我发信息吗?如果是,我该怎么做?

我的代码如下:

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.cpp

#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功能的文档 - 但我在那里找不到明确答案。

1 个答案:

答案 0 :(得分:2)

当挂钩线程调用WH_GETMESSAGEGetMessage()从其消息队列中检索消息时调用

PeekMessage(),但并非所有消息都通过消息队列,因此您可能需要也可以使用WH_CALLWNDPROC/RET挂钩,具体取决于您尝试拦截的消息类型。

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

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