Обрабатывать табуляцию с помощью DispatchMessage (), не блокируя поток через цикл сообщений?

У меня есть функция экспорта 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
}

Пример кода говорит тысячу слов

paddy 31.10.2018 02:31

Установите хук с SetWindowsHookEx, вызовите с него IsDialogMessage.

Igor Tandetnik 31.10.2018 05:00

Большинство фреймворков, предлагающих немодальные диалоги, имеют своего рода вызов сообщения «PreHandle», который потребители должны вызывать из своего цикла сообщений.

Chris Becke 31.10.2018 06:18

@paddy Извини. Я отредактировал свой пост и добавил псевдокод

Marss 31.10.2018 06:33

Экспорт функции должен возвращаться сразу после выполнения экспорта функции, поэтому я решил не включать цикл сообщений.

Marss 31.10.2018 09:05

Вы спрашиваете о предлагаемом решении, а не о реальной проблеме, которую пытаетесь решить. Естественно, поток, владеющий окнами, должен отправлять сообщения. Если вы спросите способ отправки сообщений без отправки сообщений, вы не получите ответа. Первый шаг к решению - ознакомиться с анатомией приложения Windows. Программирование Windows®, пятое издание Петцольда научит вас.

IInspectable 31.10.2018 11:28

@Inspectable, я понимаю. Я перефразировал свой вопрос, чтобы лучше понять проблему

Marss 05.11.2018 01:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
206
1

Ответы 1

У вас должен быть активный цикл сообщений, обойти это невозможно. Один из способов сделать это - иметь одну новую функцию, которая будет 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/

Другие вопросы по теме