我已将 DLL 注入到程序中,以在应用程序主窗口上实现聊天 UI。我想我可以获取应用程序主窗口句柄,然后获取它的 DC,然后在上面绘制。该窗口有一个可预测的标题,这意味着我可以使用它FindWindow
来获取句柄。唯一的问题是,DLL 是在进程启动时注入的。那时,该窗口尚未创建。这意味着FindWindow
什么也没找到!
对此有什么解决方案?我可以在 DLL 中创建一个线程并休眠一段时间,直到我知道创建了窗口吗?这似乎很不稳定,所以我宁愿不这样做。
我试图做的是SetWindowsHookEx
在 DLL 中使用来挂钩全局 WndProc。我可以扫描这些消息,直到从我的窗口中找到一条消息(这意味着它已被创建)。然后我可以保存句柄并继续我的程序。我不太担心当时有多个同名的窗口。唯一的问题是我的钩子永远不会被调用。
我像这样创建钩子:
m_hWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)WndProc, m_hModule, 0);
if(!m_hWndProcHook)
{
oss << "Failed to set wndproc hook. Error code: " << GetLastError();
Log(oss.str().c_str());
return false;
}
它返回一个有效的钩子。WndProc 如下所示:
LRESULT CALLBACK CChatLibrary::WndProc(int code, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* pData;
ostringstream oss;
char wndName[256];
gChatLib->Log("WNDPROC");
if(code < 0)
return CallNextHookEx(gChatLib->GetWndProcHookHandle(), code, wParam, lParam);
else
{
//Get the data for the wndproc
pData = (CWPSTRUCT*)lParam;
//Log the message
GetWindowText(pData->hwnd, wndName, 256);
oss << "Message from window \"" << wndName << "\"";
gChatLib->Log(oss.str().c_str());
return CallNextHookEx(gChatLib->GetWndProcHookHandle(), code, wParam, lParam);
}
}
但是没有“WNDPROC”消息记录到我的日志文件中......早些时候,我有一个MessageBox
而不是日志来查看它是否有效,结果证明这是一个糟糕的主意。所有程序都冻结了,因为它们在等待我单击“确定”,而我不得不进行硬重置...当我重新打开计算机并MessageBox
用日志命令替换时,它不起作用。不过,我知道我的日志有效,因为它在其他任何地方都有效。我对发生的事情感到非常困惑。
是否有其他获取主窗口的方法(最好是在创建时)?还是我的钩子方法很好,但只是执行错误?感谢您的任何反馈。