我在记事本的编辑类上设置了一个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功能的文档 - 但我在那里找不到明确答案。
答案 0 :(得分:2)
WH_GETMESSAGE
或GetMessage()
从其消息队列中检索消息时调用 PeekMessage()
,但并非所有消息都通过消息队列,因此您可能需要也可以使用WH_CALLWNDPROC/RET
挂钩,具体取决于您尝试拦截的消息类型。
您的全局变量需要存储在共享内存块中,否则它们只能由安装钩子的进程访问,因为在挂钩其他进程时会加载DLL的新副本。
您不能继承另一个进程所拥有的HWND
。您必须将代码注入该进程,然后该代码可以根据需要在本地进行子类化。 SetWindowsHookEx()
可用于将代码注入其他进程,但根据您的需要,CreateRemoteThread()
可能更适合使用。