![](/img/trans.png)
[英]How to get HWND in ATL DLL (for SendMessage or PostMessage)
[英]SendMessage(hwnd, registeredmssghere, 0, 1) received but not correctly recognized by hooked thread its sent to!
我正在嘗試將用戶注冊的消息發送到窗口過程,該過程收到一條消息,但無法看到我正在發送的特定注冊消息。
因此,從一開始...我確保所有dll實例共享消息。
#pragma data_seg (".shared") ... ... UINT WM_HOOKEX = 0; ... #pragma data_seg () #pragma comment(linker,"/SECTION:.shared,RWS")
在dllmain中,我確保其僅注冊一次
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { if( ul_reason_for_call == DLL_PROCESS_ATTACH ) { hDll = (HINSTANCE) hModule; //DisableThreadLibraryCalls( hDll ); if( WM_HOOKEX==NULL ) WM_HOOKEX = ::RegisterWindowMessage( _T("WM_HOOKEX_RK") ); } return TRUE; }
后來我在我的應用程序中使用了導出的dll函數(共享dll和消息),我將鈎接到所需窗口的過程並將此消息發送給
SendMessage( plist,WM_HOOKEX,0,1 );
掛鈎的過程接收到該消息(因為我正在用dll調試對其進行檢查),但無法看到它是什么消息。 DLL調試顯示盡管線程在其內存中注冊了消息,但是過程未接收到正確的消息參數。
另外,我確定它正在接收此消息,而不是其他消息,因為這是指向我調用的過程的唯一消息,因此我忽略了我的自定義mssg可能仍在隊列中的可能性,那么為什么我想知道為什么幾天來,為什么它沒有收到消息,因為即使調試也應該表明它在內存中保存了自定義消息!
這是接收它的過程(或實際上沒有)
#define pCW ((CWPSTRUCT*)lParam) LRESULT HookProc ( int code, // hook code WPARAM wParam, // virtual-key code LPARAM lParam // keystroke-message information ) { if( (pCW->message == WM_HOOKEX) && pCW->lParam ) { ::UnhookWindowsHookEx( g_hHook ); if( g_bSubclassed ) goto END; // already subclassed? // Let's increase the reference count of the DLL (via LoadLibrary), // so it's NOT unmapped once the hook is removed; TCHAR lib_name[MAX_PATH]; ::GetModuleFileName( hDll, lib_name, MAX_PATH ); if( !::LoadLibrary( lib_name ) ) goto END; // Subclass START button OldProc = (WNDPROC) ::SetWindowLong( g_hWnd, GWL_WNDPROC, (long)NewProc ); if( OldProc==NULL ) // failed? ::FreeLibrary( hDll ); else { // success -> leave "HookInjEx.dll" ::MessageBeep(MB_OK); // mapped into "explorer.exe" g_bSubclassed = true; } } else if( pCW->message == WM_HOOKEX ) { ::UnhookWindowsHookEx( g_hHook ); // Failed to restore old window procedure? => Don't unmap the // DLL either. Why? Because then "explorer.exe" would call our // "unmapped" NewProc and crash!! if( !SetWindowLong( g_hWnd, GWL_WNDPROC, (long)OldProc ) ) goto END; ::FreeLibrary( hDll ); ::MessageBeep(MB_OK); g_bSubclassed = false; } END: return ::CallNextHookEx(g_hHook, code, wParam, lParam); }
我懷疑所有這些都與我發送帶有導出功能的消息有關,我從應用程序中調用了該消息。 如果我使用原始項目隨附的示例應用程序中的功能執行此操作,則我認為它使用了導入功能,因此也許是導出功能的原因。
我也無法測試從另一種語言導入的功能。
編輯:
所以我也嘗試按照每次有人在這里建議的方式注冊mssg,但沒有區別,這里很奇怪的是,如果我調用內部掛鈎並發送mssg的函數,一切都可以正常工作,這是gui的函數頭應用程序使用(在這種情況下,一切正常)
#if !defined INJECT_EX__H #define INJECT_EX__H #ifdef INJECT_EX_EXPORTS #define HOOKDLL_API __declspec(dllexport) #else #define HOOKDLL_API __declspec(dllimport) #endif extern int HOOKDLL_API g_bSubclassed; HOOKDLL_API int InjectDll(); HOOKDLL_API int UnmapDll(); #endif // !defined(INJECT_EX__H) #define DIPSLIBAPI extern "C" __declspec(dllexport) // External function prototypes DIPSLIBAPI BOOL WINAPI SetDIPSHook(BOOL hook_it, BOOL just_save_list, int lobby, int type);
因此,這是我相信gui應用程序將injectdll函數用作導入函數的標頭,也許這就是為什么它起作用的原因? 如果我使用導出的函數而沒有此標頭,則看不到mssg。
編輯2:
這是dll項目中的預處理程序指令:_DEBUG WIN32 _WINDOWS _USRDLL INJECT_EX_EXPORTS
對於您要描述的問題,我還不太清楚。 我猜想如果WM_HOOKEX在注入的dll中仍然為0,它將與您得到的行為相對應。 假設這是問題所在,則需要執行以下操作:
volatile UINT WM_HOOKEX = 0;
這樣可以確保編譯器不會優化對WM_HOOKEX的引用,而是在每次使用它時從內存中讀取它。
一個特殊的問題是您應該調用:: RegisterWindowMessage(_T(“ WM_HOOKEX_RK”));。 在每個過程中,您都希望收到它。 系統將在任何進程中返回相同的消息號,該消息已在系統范圍內注冊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.