C++ SendMessage(hwnd,RegisteredMsgHere,0,1)已收到,但未被其发送到的挂钩线程正确识别!

C++ SendMessage(hwnd,RegisteredMsgHere,0,1)已收到,但未被其发送到的挂钩线程正确识别!,c++,c,windows,winapi,C++,C,Windows,Winapi,我正试图将用户注册的消息发送到窗口过程,该过程收到一条消息,但它看不到我正在发送的特定注册消息 所以从一开始。。。我确保所有dll实例共享meessage #pragma data_seg (".shared") ... ... UINT WM_HOOKEX = 0; ... #pragma data_seg () #pragma comment(linker,"/SECTION:.shared,RWS") #pragma数据段(“共享”) ... ... UINT WM_HOOKEX=0

我正试图将用户注册的消息发送到窗口过程,该过程收到一条消息,但它看不到我正在发送的特定注册消息

所以从一开始。。。我确保所有dll实例共享meessage

#pragma data_seg (".shared") ... ... UINT WM_HOOKEX = 0; ... #pragma data_seg () #pragma comment(linker,"/SECTION:.shared,RWS") #pragma数据段(“共享”) ... ... UINT WM_HOOKEX=0; ... #pragma数据段() #pragma注释(链接器,“/节:。共享,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; } BOOL APICENT DllMain(手柄模块, 德沃德·乌尔打电话的理由, LPVOID lpReserved ) { if(ul\u调用的原因==DLL\u进程\u附加) { hDll=(HINSTANCE)hModule; //禁用线程库调用(hDll); if(WM_HOOKEX==NULL) WM_HOOKEX=::RegisterWindowMessage(_T(“WM_hookx_RK”); } 返回TRUE; } 稍后,使用我在应用程序中使用的导出dll函数(共享dll和消息),我将挂钩到所需窗口的过程,并将此消息发送给它

SendMessage( plist,WM_HOOKEX,0,1 ); SendMessage(plist,WM_-HOOKEX,0,1); 钩住的过程接收消息(我正在用dll调试检查它),但它看不到它是什么消息。Dll调试显示线程在其内存中注册了消息,但过程没有收到正确的消息参数

此外,我确信它正在接收此消息,而不是其他消息,因为这是指向我调用的过程的唯一消息,因此我排除了我的自定义mssg可能仍在队列中的可能性,那么为什么我想知道几天来为什么,为什么它不接收消息,因为它甚至应该调试显示它在内存中保存了自定义消息

这是接收(或实际上不接收)的过程

#定义pCW((CWPSTRUCT*)lParam) LRESULT-HookProc( int代码,//钩子代码 WPARAM WPARAM,//虚拟密钥代码 LPARAM LPARAM//击键消息信息 ) { 如果((pCW->message==WM_HOOKEX)和&pCW->lParam) { :unhookwindowshookx(g_hHook); if(g_b次级) goto END;//是否已子类化? //让我们增加DLL的引用计数(通过LoadLibrary), //因此,一旦吊钩被移除,它就不会被取消映射; TCHAR lib_名称[最大路径]; ::GetModuleFileName(hDll、库名称、最大路径); if(!::加载库(库名称)) 转到终点; //子类启动按钮 OldProc=(WNDPROC) ::SetWindowLong(g_hWnd,GWL_WNDPROC,(long)NewProc); 如果(OldProc==NULL)//失败? ::免费图书馆(hDll); 否则{//success->离开“HookInjEx.dll” ::MessageBeep(MB_OK);//映射到“explorer.exe” g_bSubclassed=真; } } else if(pCW->message==WM\u HOOKEX) { :unhookwindowshookx(g_hHook); //还原旧窗口过程失败?=>不要取消映射 //为什么?因为“explorer.exe”会调用 //“未映射”NewProc和crash!! 如果(!SetWindowLong(g_hWnd,GWL_WNDPROC,(long)OldProc)) 转到终点; ::免费图书馆(hDll); ::MessageBeep(MB_OK); g_bSubclassed=假; } 完: return::CallNextHookEx(g_hHook,code,wParam,lParam); } 我怀疑所有这一切都与我用我的应用程序调用的导出函数发送消息有关。如果我使用原始项目附带的示例应用程序中的函数执行此操作,它使用导入的函数,我认为是的,导出的函数可能是原因

此外,我无法测试导入的函数,因为它来自另一种语言

编辑:

因此,我也尝试按照这里的建议每次注册mssg,但没有什么不同,奇怪的是,如果我调用在内部钩住并发送mssg的函数,一切都正常,这是gui应用程序使用的函数的标题(在这种情况下,一切正常)

#如果!定义的注入 #定义注入前 #ifdef注入输出 #定义HOOKDLL\u API\u declspec(dllexport) #否则 #定义HOOKDLL\u API\u declspec(dllimport) #恩迪夫 外部接口API g_B子类; HOOKDLL_API int InjectDll(); HOOKDLL_API int unpdll(); #endif/!已定义(注入外部) #定义DIPSLIBAPI外部“C”uu declspec(dllexport) //外部功能原型 DIPSLIBAPI BOOL WINAPI setdipshake(BOOL hook_it,BOOL just_save_list,int lobb,int type); 这就是我认为gui应用程序使用injectdll函数作为导入函数的标题,也许这就是它工作的原因?如果我在没有此标题的情况下使用导出的函数,则mssg不会正确显示

编辑2:

以下是dll项目中的预处理器指令: _调试 WIN32 _窗户 _USRDLL
注入导出一个特别的问题是您应该调用::RegisterWindowMessage(_T(“WM_hookx_RK”);在每一个过程中,你都希望收到它。系统将在任何进程中返回相同的消息编号,消息在系统范围内注册。

一个特殊问题是,您应该调用::RegisterWindowMessage(_T(“WM_hookx_RK”);在每一个过程中,你都希望收到它。系统将在任何进程中返回相同的消息编号,消息在系统范围内注册。

我不完全清楚您描述的问题是什么。我猜这将对应于如果WM_HOOKEX在注入的dll中仍然为0时所得到的行为。假设这就是问题所在,您需要执行以下操作:

volatile UINT WM_HOOKEX = 0;

这确保编译器不会优化对WM_HOOKEX的引用,而是在每次使用它时从内存中读取它。

我不完全清楚您描述的问题是什么。我猜这会符合你的行为 #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);
volatile UINT WM_HOOKEX = 0;