2013-05-08 55 views
1

我在記事本的編輯類上設置了SetWindowsHookEx,但我不知道如何從這裏繼續。子類化記事本的編輯類(WINAPI)

我希望將Edit類繼承到我自己的過程,然後操作文本或將它保存到文件中,然後它必須發回記事本控件/類。

有更簡單的方法來從記事本中獲取文本,但我正在嘗試學習WINAPI和子類化,所以這是我學習它的好方法。

我和SetWindowsHookEx看起來是這樣的:

SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll, npThreadId); 

如何使用掛鉤類型:WH_GETMESSAGE獲得從編輯類文本在記事本中,並將其轉移到我的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函數的文檔 - 但我沒有在那裏找到明確的答案。當掛鉤的線程調用GetMessage()PeekMessage()檢索從消息隊列中的消息,但並不是所有的消息通過消息隊列

回答

2

WH_GETMESSAGE被調用,所以你可能需要使用WH_CALLWNDPROC/RET鉤爲好,這取決於什麼樣的你試圖攔截的消息。

您的全局變量需要存儲在一個共享內存塊中,否則只有安裝鉤子的進程才能訪問它們,因爲掛鉤其他進程時會加載DLL的新副本。

您不能繼承其他進程擁有的HWND。您必須將代碼注入該進程,然後該代碼可以根據需要在本地進行子類化。 SetWindowsHookEx()可用於將代碼注入其他進程,但根據您的需要,CreateRemoteThread()可能更適合用於此目的。

+0

謝謝,雷米。 WH_GETMESSAGE現在更清晰。與全局變量的好處。再次感謝。 – 2013-05-10 05:49:55