У меня есть функция экспорта OpenUI () в DLL для представления пользовательского интерфейса, которая создает немодальное главное диалоговое окно, а также имеет немодальное дочернее диалоговое окно.
Я вызываю функцию экспорта OpenUI () из отдельной библиотеки DLL, которая является моим контроллером.
Как я могу выполнить дополнительный код после вызова функции, если цикл сообщений в OpenUI () не позволяет функции вернуться, если диалоговое окно не закрыто? Я не могу удалить цикл сообщений, потому что без него не будет работать табуляция.
Мне нужно, чтобы экспорт функции возвращался сразу после выполнения, поэтому я не могу использовать модальный диалог. Создание подпотока также не вариант, потому что это вызвало проблемы в моем приложении.
Любая помощь высоко ценится. Спасибо.
Псевдокод для моей dll контроллера
typedef int(*DLL_OPENUI)();
int func()
{
HINSTANCE hinst_dll = LoadLibrary(dll_path);
DLL_OPENUI DllOpenUI = (DLL_OPENUI)GetProcAddress(hinst_dll, "OpenUI");
int ret = DllOpenUI();
//...execute more code here
return ret;
}
Псевдокод для моей dll представления пользовательского интерфейса
__declspec(dllexport) OpenUI()
{
hwnd_main = CreateDialog(hinst, IDD_MAIN, MainDlgProc);
ShowWindow(hwnd_main, SW_SHOW);
MSG msg;
while ((GetMessage(&msg, NULL, 0, 0) > 0))
{
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
LRESULT CALLBACK MainDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
OnInitDialog();
break;
}
}
void OnInitDialog()
{
CreateDialog(hinst, IDD_NAV_PANE, hwnd_main, NavPaneProc);
CreateDialog(hinst, IDD_NAV_TABS, hwnd_main, NavTabsProc);
CreateDialog(hinst, IDD_TAB_1, hwnd_main, TabOneProc);
CreateDialog(hinst, IDD_TAB_2, hwnd_main, TabTwoProc);
CreateDialog(hinst, IDD_TAB_3, hwnd_main, TabThreeProc);
CreateDialog(hinst, IDD_DETAILS_PANE_BG, hwnd_main, BackgroundProc);
CreateDialog(hinst, IDD_DETAILS_PANE, hwnd_main, DetailsPaneProc);
//...execute more code below
}
Установите хук с SetWindowsHookEx
, вызовите с него IsDialogMessage
.
Большинство фреймворков, предлагающих немодальные диалоги, имеют своего рода вызов сообщения «PreHandle», который потребители должны вызывать из своего цикла сообщений.
@paddy Извини. Я отредактировал свой пост и добавил псевдокод
Экспорт функции должен возвращаться сразу после выполнения экспорта функции, поэтому я решил не включать цикл сообщений.
Вы спрашиваете о предлагаемом решении, а не о реальной проблеме, которую пытаетесь решить. Естественно, поток, владеющий окнами, должен отправлять сообщения. Если вы спросите способ отправки сообщений без отправки сообщений, вы не получите ответа. Первый шаг к решению - ознакомиться с анатомией приложения Windows. Программирование Windows®, пятое издание Петцольда научит вас.
@Inspectable, я понимаю. Я перефразировал свой вопрос, чтобы лучше понять проблему
У вас должен быть активный цикл сообщений, обойти это невозможно. Один из способов сделать это - иметь одну новую функцию, которая будет PeekMessage
и выполнять код цикла только один раз. PeekMessage
возвращает ненулевое значение, если при последующем вызове GetMessage
фактически будет получено сообщение, а не блокируется. ProcessOneMessage
может выглядеть примерно так:
BOOL ProcessOneMessage(HWND hwnd)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
return TRUE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return FALSE;
}
Итак, в вашем основном коде вы должны часто вызывать эту функцию (каждые 10 мс должно быть нормально). Что бы ни делал код, он должен вызывать функцию один раз в 10 мс. У вас будет живое окно, и вы одновременно запустите свой код. Но как только функция вернет TRUE
, окно будет закрыто, и вы не должны снова вызывать функцию. Для получения дополнительной информации ищите PeekMessage. Код взят по этой ссылке: https://jeffpar.github.io/kbarchive/kb/074/Q74042/
Пример кода говорит тысячу слов