WM_TIMER внезапно останавливается в элементе управления ActiveX ATL

У меня изначально был элемент управления ActiveX, который зарегистрировал таймер Windows (с SetTimer()), который срабатывает каждые несколько секунд. До сих пор это работало нормально. Теперь, чтобы реализовать полноэкранный режим, я добавил в свой элемент управления дочернее окно, которое должно отображать содержимое, а сам элемент управления управляет всеми элементами ActiveX.

Проблема, с которой я столкнулся при таком подходе, заключается в том, что мой WM_TIMER внезапно перестает запускаться через некоторое время. Я проследил это до UIDeactivate() вызывается на моем контроле, но я не знаю, почему этот метод вызывается (я думаю, что это связано с потерей фокуса), когда он не был вызван раньше.

Я также хотел бы знать, почему мои события WM_TIMER внезапно прекращаются, в то время как все остальное, кажется, работает нормально. И что это может делать с отображением содержимого в дочернем окне вместо самого элемента управления ActiveX?

0

Решение

Таймеры останавливается по причине. Который может быть:

  1. Вы останавливаете таймер KillTimer вызов
  2. Ваше окно воссоздано и таймер не включен
  3. Ваш контроль без окон, и у вас на самом деле нет HWND справиться
  4. Есть конфликт в идентификаторах таймера, есть что-то еще (например, внутреннее подклассное окно), чтобы использовать тот же идентификатор, он устанавливает, убивает таймер, и вы больше не видите WM_TIMER сообщения, которые вы включили ранее
  5. Поток окна занят (заморожен) некоторой деятельностью, которая не включает отправку сообщений, поэтому сам таймер существует, исправен и жив, просто не отправлено сообщений

Что нужно сделать — без дополнительной информации по данному вопросу на руках:

  1. Проверьте потоки вашего окна и ваши вызовы Set / KillTimer, чтобы убедиться, что все они имеют смысл вместе
  2. Используйте инструмент Spy ++ для проверки сообщений, опубликованных для вашего окна и / или в интересующей ветке, чтобы выяснить, действительно иметь WM_TIMERотсутствует, или они просто не доходят до вашего кода; также вы можете увидеть другие интересные сообщения вокруг
2

Другие решения

Вот выдержка из реализации ATL CComControlBase (Я полагаю, что ваш контроль наследует от этого). Проверьте часть, отмеченную <<<<<<<<<<<:

inline HRESULT CComControlBase::IOleInPlaceObject_InPlaceDeactivate(void)
{
if (!m_bInPlaceActive)
return S_OK;

if(m_bUIActive) {
CComPtr<IOleInPlaceObject> pIPO;
ControlQueryInterface(__uuidof(IOleInPlaceObject), (void**)&pIPO);
ATLENSURE(pIPO != NULL);
pIPO->UIDeactivate();
}

m_bInPlaceActive = FALSE;

// if we have a window, tell it to go away.
//
if (m_hWndCD)
{
ATLTRACE(atlTraceControls,2,_T("Destroying Window\n"));
if (::IsWindow(m_hWndCD))
DestroyWindow(m_hWndCD);  <<<<<<<<<<<<<<<<<<<<<<<<<<<
m_hWndCD = NULL;
}

if (m_spInPlaceSite)
m_spInPlaceSite->OnInPlaceDeactivate();

return S_OK;
}

При деактивации окно управления разрушается. Поэтому он больше не может обрабатывать WM_TIMER.

0

По вопросам рекламы [email protected]