синхронизированный MessageBox в консольном приложении - PullRequest
0 голосов
/ 21 июля 2011

Я использую функцию MessageBox в консольном приложении Win32.
Приложение не использует MFC, даже цикл обработки событий.
Мне нужно сделать обертку MessageBoxTimed (), которая выходит из
(и диалоговое окно исчезает) через N секунд, если пользователь не нажал ни одной кнопки.

Есть ли более или менее простой способ сделать это?

Ответы [ 4 ]

2 голосов
/ 22 июля 2011

См. в этой статье в MSDN для примера одной реализации.Мы используем это в некоторых наших проектах, и это прекрасно работает.

2 голосов
/ 21 июля 2011

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

Если время таймера истекло, используйте API FindWindow(), чтобы найти дескриптор окна сообщения, а затем смоделируйте нажатие кнопки OK или, что более подходящее, нажатие кнопки ESC.

РЕДАКТИРОВАТЬ: На самом деле, не так уж плохо. Это не полностью проверено, может потребоваться дополнительная очистка, но этого достаточно для начала работы.

  #include <Windows.h>

  class TimedMB
  {
  public:
     TimedMB() : timeout_(0), caption_(0)
     {
        interrupt_ = CreateEvent(NULL, FALSE, FALSE, NULL);
     }

     ~TimedMB()
     {
        CloseHandle(interrupt_);
     }

     static DWORD WINAPI timer(LPVOID param)
     {
        TimedMB* mb = reinterpret_cast<TimedMB*>(param);

        if(WAIT_TIMEOUT == WaitForSingleObject(mb->interrupt_, mb->timeout_))
        {
           HWND message_box = FindWindow(NULL, mb->caption_);

           if(::IsWindow(message_box))
           {
              PostMessage(message_box, WM_COMMAND, IDCANCEL, 0);
           }
        }

        return 0;
     }

     void DisplayMessageBox(const char* msg, const char* caption, DWORD timeout)
     {
        timeout_ = timeout;
        caption_ = caption;

        CreateThread(NULL, 0, &TimedMB::timer, this, 0, NULL);
        ::MessageBox(NULL, msg, caption, MB_OKCANCEL);
        ::SetEvent(interrupt_);
     }

  private:
     HANDLE      interrupt_;
     DWORD       timeout_;
     const char* caption_;
  };

  int main()
  {
     TimedMB mb;
     mb.DisplayMessageBox("Hello There!", "My Message Box", 5000);
  }
0 голосов
/ 22 июля 2011

Не делай этого.Модальные диалоги должны быть закрыты при вмешательстве пользователя.Отклонение от этого шаблона просто запутанно и нестандартно.Если вы хотите, чтобы окна сообщений закрывались, используйте всплывающее окно.

0 голосов
/ 21 июля 2011

Если вам нужно отменить его автоматически, я бы вообще не стал использовать MessageBox.Вместо этого я просто собрал бы диалог, который закрывается сам по истечении указанного периода времени.Если память служит, вы можете сделать это довольно легко, установив время при отображении диалогового окна псевдо-сообщения.Когда время истекает или пользователь нажимает «ОК» (или «Закрыть» и т. Д.), Вы закрываете окно и отменяете таймер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...