Диалоговое окно

Тема в разделе "WASM.WIN32", создана пользователем SadKo, 23 июн 2023.

  1. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Всем привет!

    Что-то я не совсем понимаю, как с помощью WinAPI создать своё окно, которое висело бы над другим окном как диалоговое. То есть, не давало сделать какие-либо действия с блокированным окном, пока само не закроется, и не уходило бы на второй план. А то у меня получается. что окошко About может уползти куда-то под основное окно приложения.
     
  2. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.995
    Самое примитивное - EnableWindow(,False) на основное окно при показе дочернего и обратно при его скрывании.
     
  3. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    457
    Там смысл в том, что главный цикл приложения while GetMessage / DispatchMessage в сущности своей одинаково относится ко всем окнам просто передавая в их обработчики сообщений соответствующие сообщения. При этом создаётся иллюзия их параллельной работы (хотя всё может крутится в одном потоке) если сообщения обрабатываются быстро и визуально не блокируют друг друга (не впадают в слишком долгую работу в потоке).
    Так вот когда мы делаем код который имитирует блокирующую работу с диалогом (DialogBox), т.е. код застывает в точке вызова DialogBox как будто бы это какой нибудь ReadLine из однопоточного приложения в DOS, то на самом деле в функции DialogBox просто начинает крутится абсолютно такой же цикл while GetMessage / DispatchMessage просто он не выходит оттуда пока диалог не закроется. При этом в цикле вызывается IsDialogMessage которая фильтрует сообщения для модального диалогового окна. Хотя ряд сообщений всё-таки доставляется остальным окнам (типа перерисовки) даже после этой фильтрации, но уже не переключения и тому подобное - фокус в приложении таким образом оказывается захвачен диалоговым окном. В WinAPI очень важно понимать такие нюансы и писать обработку сообщений таким образом чтобы она оставалась совместимой с такими штуками - т.е. если рассчитывать, что message loop устроен всегда по одному шаблону, то диалоговые окна будут работать и в, допустим, оконном OpenGL-приложении. Если же "поломать" основной message loop в таком приложении ориентируясь на интуитивные представления об OpenGL-приложении, то диалоговые окна начнут вызывать заморозку или порчу картинки и т.п.
     
  4. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    У меня основная проблема в том, что Event Loop не моего приложения. Т.е. я встраиваю плагин в другое приложение.
    Когда другое приложение показывает окно моего плагина, есть возможность создавать дочерние диалоговые окна, например About:
    [​IMG]
    Так вот этот About имеет свойство уходить под основное окно, если щёлкнуть на заголовок окна, окружающего моё.
    Соответственно, хочется понять, как удерживать окно поверх своего основного и не давать что-то в нём менять, пока оно не закроется.
    --- Сообщение объединено, 23 июн 2023 ---
    Как написал f13nd, EnableWindow может помочь отключить события мыши/клавиатуры на основном окне. Но вопрос удержания другого окна поверх него пока остаётся открытым.
     
  5. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    В общем, вроде как помогла комбинация из EnableWindow + обработка вот такого сообщения:

    Код (Text):
    1.  
    2.                     case WM_WINDOWPOSCHANGING:
    3.                     {
    4.                         if ((hTransientFor == NULL) || (hTransientFor == HWND_TOP))
    5.                             break;
    6.  
    7.                         HWND hPrev          = GetTopWindow(GetDesktopWindow());
    8.                         while (hPrev != NULL)
    9.                         {
    10.                             HWND hCurr              = GetWindow(hPrev, GW_HWNDNEXT);
    11.  
    12.                             // We are already at the top?
    13.                             if (hCurr == hWindow)
    14.                                 break;
    15.                             if (hCurr == hTransientFor)
    16.                             {
    17.                                 WINDOWPOS *p            = reinterpret_cast<WINDOWPOS *>(lParam);
    18.                                 p->hwndInsertAfter      = hPrev;
    19.                                 p->flags               &= ~SWP_NOZORDER;
    20.                                 break;
    21.                             }
    22.  
    23.                             // Update pointer
    24.                             hPrev                  = hCurr;
    25.                         }
    26.  
    27.                         break;
    28.                     }
    29.  
    В этом сообщении мы контролируем, чтобы положение диалогового окна было не ниже окна, над которым мы его показываем (hTransientFor).
     
  6. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    875
    Так нужно модальное окно показать? Создаешь нужное окно, родителем которого указываешь disabled окно (EnableWindow (FALSE)).
     
  7. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    457
    А они точно диалоговые? Диалог в WinAPI это конкретные обязательства. Как создаются и показываются? По идее вообще без каких либо телодвижений должно было всё работать. Если они действительно диалоговые.
     
  8. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Я не уверен, что они "настоящие" диалоговые окна. Но, в целом, мой трюк сработал.
     
  9. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    457
    Можно два фактора выделить:
    а) если не было вызова DialogBox, то нет
    а) если не было бита в стиле окна Чего-то-там-MODAL, то может и диалог, но не модальный
     
  10. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    189
    Так всего-же есть 3 типа диалоговых окон:
    1. Немодальное (по умолчанию, не требуется флаг при создании);
    2. Модальное внутри своего процесса (флаг DS_MODALFRAME);
    3. Системно-модальное. Перекрывает все окна на раб.столе, даже если окно неактивно - видимо это и есть ваш вариант. Создаётся просто добавлением флага DS_SYSMODAL.
     
  11. mantissa

    mantissa Мембер Команда форума

    Публикаций:
    0
    Регистрация:
    9 сен 2022
    Сообщения:
    155
    https://blog.adeltax.com/window-z-order-in-windows-10/
     
    Mikl___ нравится это.