Таймер

Тема в разделе "WASM.WIN32", создана пользователем Tarzan, 18 июл 2008.

  1. Tarzan

    Tarzan New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    8
    Возникла такая проблема:
    Я создаю обычное Win32 приложение, но окно хочу вызывать через класс с методами:
    1. CreateWindow, где будем регистрировать, создавать класс окна и запускать цикл с GetMessage
    2. static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM), функция обработки сообщений окна
    Таким образом из созданного нами приложения убиваем все кроме _tWinMain в которой пишем:
    CMyWindow w;
    w.CreateWindow(TEXT("Title"));
    Всё работает почти замечательно если не считать того что кроме всего прочего мне нужно запустить таймер. Добавляем if в CreateWindow :

    while (GetMessage(&msg, NULL, 0, 0))
    {
    if (msg.message == WM_TIMER)
    {
    MessageBox(NULL, TEXT("Title"), TEXT("message"), MB_OK);
    }
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    Если SetTimer вызвать перед этим циклом в if можно попасть только после того как закрывается окно, а если SetTimer вызвать в WM_CREATE, то приложение просто висит.
    Подскажите как правильно реализорвать то что я хочу: класс окна с таймером?
     
  2. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    А что если обрабатывать таймер в самой оконной процедуре? Или же просто проставить ему функцию-обработчик?
     
  3. mc black

    mc black Member

    Публикаций:
    0
    Регистрация:
    19 янв 2005
    Сообщения:
    213
    Адрес:
    Russia, N.Novgorod
    Ты не там обрабатывать пытаешься сообщения. Сообщения обрабатываются в WinMain. И что за код, какой язык программирования? Пиши в другой раз лучше в WASM.LANG.C
     
  4. Tarzan

    Tarzan New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    8
    C функцией обработчиком та же ситуация
    А в самой оконоой процедуре ето я так понимаю в WndProc? Если да то сообщения WM_TIMER она не получает, а если после WM_CREATE идет SetTimer и далее цикл c GetMessage, то он действительно обрабатывает там таймер, но тогда он из этого цикла не уходит в цикл GetMessage окна и окно просто висит.
     
  5. Tarzan

    Tarzan New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    8
    Хорошо тогда как мне реализовать таймер+окно без WinMain?
    С++
    ОК. Но в данном случае писал сюда потому, что именно проблема не в языке а в работе с WinAPI
     
  6. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Вот код. Рабочий. Непонятно, где там что висело...
    ;)
     
  7. Tarzan

    Tarzan New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    8
    Так проблема именно в том как спрятать работу в классе ( именно тогда всё и перестаёт работать), ведь судя по моим скромным знаниям ассемблера у тебя цикл с GetMessage находится именно там где и и должен (в WinMain), а я хочу перенести WinMain в класс и потом из настоящего WinMain запускать классовый (CreateWindow у меня)
     
  8. Tarzan

    Tarzan New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    8
    Изначально мой класс окна я хотел использовать в консольном приложении, но там была таже ситуация, что и сейчас. Прочитав вот это - "SetTimer() не должна использоваться в консольных приложениях, так как консольные приложения не поддерживают разделения потоков." просто перенес всё в созданное окнонное Win32 приложение и в место main теперь класс создается в _tWinMain.
    Так может ктото объяснит как именно работает таймер? Потому, что после вызова SetTimer я не нашел нового потока в моем процессе.
     
  9. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Хм, ну ладно, обычные таймеры не катят. А что если пользовать timeSetEvent/timeKillEvent из модуля WinMM? Там другой механизм отсчёта (вытесняющая многопоточность, если интересно). Может оно не будет подвешивать?
     
  10. Tarzan

    Tarzan New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    8
    Щас буду разбираться. Спасибо
     
  11. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Для таймера нет нового потока. По вызову SetTimer() - Windows записывает HWND окна во внутренний список и когда время течет внутенним образом в Windows - система посылает сообщения WM_TIMER.
     
  12. Tarzan

    Tarzan New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    8
    Вообщем я думал, что что-то не допонимаю в таймерах, а как оказалось проблема была в другом. Кстати кроме неправильной работы таймера, мое приложение со включённым окном грузило процессор примерно на 50%. Для избавления от этих 2-х проблем, как оказалось надо было добавить в обработчик сообщений окна:

    case WM_PAINT:
    hdc = BeginPaint(hwnd, &ps);
    EndPaint(hwnd, &ps);
    break;

    До этого, секция WM_PAINT у меня вообще отсутсвовала, но как оказалось именно без BeginPaint и EndPaint таймер не правильно работает и приложение со включённым окном грузит процессор на 50%.
    Судя по тому, что я прочитал в MSDN'е и всегда знал - сообщение WM_PAINT и не обязательно обрабатывать, если сам ничего в окне выводишь.
    Кто может объяснить почему именно нехватка BeginPaint и EndPaint в WM_PAINT так влияет на работу приложения - просьба отписаться
     
  13. zhindos

    zhindos New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    142
  14. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Ох, что-то странное у тебя происходит. Я размышляю... Можно посмотреть код? Конкретно нас интересуют связи между оконной процедурой [WndProc], функцией, в которой создаётся окно, функцией с циклом обработки сообщений и то, с какими параметрами вызывалась SetTimer. ). Короче говоря, хотелось бы получить код для воспроизведения ситуации с высокой загрузкой ЦП.
     
  15. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    С WM_PAINT-ом такая вот петрушка: если у тебя нет "case WM_PAINT:" вообще - тогда ничего не надо делать, потому что если какого-то обработчика нет, то должен быть вызов DefWindowProc() в "default" случае - в твоёй процедуре окна.. Если "case WM_PAINT:" есть - тогда надо обязательно пара BeginPaint()/EndPaint() или без пары, но опять вызов DefWindowProc():
    Код (Text):
    1. //
    2. // No handling! Bad code!
    3. //
    4. switch (message)
    5. {
    6.     case WM_PAINT:
    7.         break;
    8.  
    9.     default:
    10.         DefWindowProc (...);
    11. }
    12.  
    13. //
    14. // OK
    15. //
    16. switch (message)
    17. {
    18.     case WM_PAINT:
    19.         DefWindowProc (...);
    20.         break;
    21.  
    22.     default:
    23.         DefWindowProc (...);
    24. }
    25.  
    26. //
    27. // OK
    28. //
    29. switch (message)
    30. {
    31.     case WM_PAINT:
    32.         BeginPaint (...);
    33.         EndPaint (...);
    34.         break;
    35.  
    36.     default:
    37.         DefWindowProc (...);
    38. }
    Дело в том, что WM_PAINT изымается из очереди сообщений окна функцией EndPaint() и если такого вызова нет, то сообщение стоит в очереди навсегда и происходит замкнутый цикл - т.е. постоянный вызов твоей оконной процедуры.
     
  16. Tarzan

    Tarzan New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2008
    Сообщения:
    8
    Спасибо теперь всё стало на свои места
     
  17. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Ну и так, на всякий случай: таймер не работал, потому что сообщения WM_TIMER имеют наименьший приоритет и доходят до оконной процедуры только после того, как из очереди сообщений будут изъяты другие сообщения (в том числе и WM_PAINT).
     
  18. zet

    zet New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2007
    Сообщения:
    121
    Может лучше использовать message-only window? (2k/XP)