Как получать события таймера в CWinApp с MFC? - PullRequest
1 голос
/ 17 октября 2008

В MFC я пытаюсь установить таймер нулевого обработчика (т.е. без окон). Но я не могу обработать событие WM_TIMER в CWinApp MESSAGE_MAP. Это возможно? Если да, то как?

Ответы [ 3 ]

13 голосов
/ 18 октября 2008

Как сообщает MSDN, есть два режима работы для SetTimer(): один, который связывает таймер с окном, и другой, который связывает таймер с очередью сообщений потока. Когда у вас есть окно, вы можете использовать первое; в противном случае вы должны использовать последнее. И CWinApp не окно.

Перехват сообщений таймера в очереди потоков

UINT_PTR uTimerId = SetTimer(NULL, 0, 2000, NULL);
TRACE(_T("Timer created - ID=%x\n"), uTimerId);

Это создаст новый таймер, включаемый каждые две секунды, связанный только с очередью сообщений текущего потока. Вы не можете указать идентификатор таймера, когда не связываете его с окном, поэтому сохраните идентификатор, возвращенный в классе, или что-то в этом роде - у вас будет трудное время, чтобы позже убить таймер, если забыть . Затем вы можете обработать это в CWinApp::PreTranslateMessage() переопределении:

BOOL CMyFunkyApp::PreTranslateMessage(MSG* pMsg)
{
   if (pMsg->message == WM_TIMER)
   {
      TRACE(_T("Timer fired - ID=%x\n"), pMsg->wParam);
   }

   return CWinApp::PreTranslateMessage(pMsg);
}

Обратите внимание, что подключение к циклу сообщений потока, как это, является только способом для обработки таймера, настроенного таким образом - как мы уже обсуждали, окна нет, и хотя MFC предоставляет средство отображения сообщений для CWinApp Вы не можете использовать макросы ON_WM_*(), потому что ... ну, потому что это не окно . Однако есть и другой, слегка менее грязный способ: обратные вызовы.

Обработка сообщений таймера с обратным вызовом

void CALLBACK TimerCallback(HWND, UINT, UINT_PTR id, DWORD dwTime)
{
   TRACE(_T("Timer fired - ID=%x\n"), id);
}

//...

UINT_PTR uTimerId = SetTimer(NULL, 0, 2000, &TimerCallback);
TRACE(_T("Timer created - ID=%x\n"), uTimerId);

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

Итак, поехали. Два способа использования таймеров от CWinApp.

2 голосов
/ 18 октября 2008

Проверьте это сообщение Раймонд Чен. Есть несколько интересных самородков для того, над чем вы работаете, и это может уберечь вас от неприятностей.

Почему ваш поток тратит все свое время на обработку бессмысленных таймеров потоков

2 голосов
/ 17 октября 2008

Я сделал это, сделав невидимое окно и установив на нем таймер.

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