РЕДАКТИРОВАТЬ: я забыл упомянуть, у меня нет исходного кода для DLL, которая создает окно, поэтому я не могу изменить функцию для возврата HWND.
Я создаю приложение Win32 и использую DLL, которая создает для меня окно с помощью одной из экспортируемых функций «void X ();» Я вызываю X () в моем WinMain ().
Это создает окно для меня. Я хочу получить HWND окна, которое было создано этой экспортированной библиотечной функцией, так как X () возвращает void, поэтому я могу использовать его для других вызовов API.
Может кто-нибудь подскажет проще всего получить HWND?
Я искал и отвечал на вопросы здесь, но я не могу как-то найти точное, подходящее решение. Я попытался EnumWIndows (), а затем получить идентификатор процесса, а затем сравнить с текущим идентификатором процесса потока. Но я думаю, что должен быть гораздо лучший, более эффективный и простой способ получить HWND.
В конце концов, я в WinMain процесса, который создал это окно в первую очередь.
Если мне нужно что-то объяснить, что я пропустил здесь, пожалуйста, дайте мне знать.
Я уверен, что это очень просто, и здесь что-то явно упущено. Сожалею.
Спасибо & С уважением!
Используйте инструмент, такой как Spy ++ или Winspector, чтобы увидеть все HWND
созданные вашим приложением, в частности их имена классов и заголовки окон. Затем вы можете скопировать эти значения в свой код и сделать один вызов FindWindow()
после того, как DLL создаст свое окно, например:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// ...
X();
HWND hWnd = FindWindow("ClassNameHere", "TitleHere");
// ...
return 0;
}
Самый простой способ сделать это — использовать функцию SetWindowsHookEx(WH_CBT, fun, NULL, GetCurrentThreadId())
, Тогда fun
Функция, определенный вами обратный вызов, будет вызываться при возникновении ряда событий. Тот, который вы хотите, это HCBT_CREATEWND
,
Что-то вроде этого (полностью не проверено):
HWND hDllHandle = NULL;
LRESULT CALLBACK X_CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_CREATEWND)
hDllHandle = (HWND)wParam;
return CallNextHookEx(NULL, nCode, wParam, lParam); //The first parameter is useless
}
HWND CallXAndGetHWND()
{
HHOOK hDllHook = SetWindowsHookEx(WH_CBT, X_CBTProc, NULL, GetCurrentThreadId());
X();
UnhookWindowsHookEx(hDllHook);
//hDllHandle is a global variable, so will be now you window!
return hDllHandle;
}
Обратите внимание, что эта функция не поддерживает потоки, но, скорее всего, вы будете вызывать ее только один раз в начале кода, поэтому это не должно иметь значения.
И будьте осторожны! Многие функции, даже функции Win32 API, создают скрытые окна. Этот код перехватит их все и вернет последний созданный. Изменение его для возврата любого другого или даже списка их, если необходимо, должно быть тривиальным.