| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Таймер без окна |
| Автор: Andrey44 15.2.2010, 12:17 |
| Вобщем вопрос. Есть класс, в нем надо делать что-то, через какое-то время. Можно делать SetTimer(0, ID_TIMER, TIMEOUT, (LPTIMERPROC)TimerProc); Но тогда функция TimerProc должна быть static, а мне надо иметь доступ к нестатическим членам класса. Как можно это обойти? Не ложить же статик-мембереом указатель на самого себя, или не объявлять глобальную переменную. |
| Автор: artsb 15.2.2010, 12:20 |
Сделать её другом класса? |
| Автор: Andrey44 15.2.2010, 12:32 |
| И что будет? TimerProc получит доступ к неявному указателю this? |
| Автор: artsb 15.2.2010, 12:46 |
Действительно, что-то я сморозил не то ИМХО простого выхода из этой ситуации нет. Если он вообще есть конечно... |
| Автор: GremlinProg 15.2.2010, 21:47 | ||||||
можно сделать так:
можно TimerProc сделать шаблоном, тогда вообще все просто:
|
| Автор: Dem_max 16.2.2010, 07:51 |
| не забывай что функция Таймера это CallBack функция, из которой нужно вернуть управление циклу сообщений. |
| Автор: Earnest 16.2.2010, 08:36 | ||
Ты точно знаешь, что это сработает? Дело в том, что MSDN пишет, что при hWnd == 0 ид-р таймера игнорируется.
Я тоже было хотела это предложить, да призадумалась над этой фразой. Как минимум, надо проверять (что ид-р будет приходить в call-back без искажений). |
| Автор: Dem_max 16.2.2010, 08:45 |
| Создавай таймер с помощью потока. |
| Автор: Earnest 16.2.2010, 08:47 |
Если выбирать между ни зачем больше не нужным потоком и статической переменной, я бы выбрала статическую переменную. Вот ей богу. По принципу Оккама. |
| Автор: Andrey44 16.2.2010, 08:52 |
| GremlinProg, сделал как ты написал, не работает.Все приходит, захожу в функцию обработчик таймера, но в this какой-то мусор. В MSDN написано что idEvent должен быть 0 если HWND == 0. |
| Автор: azesmcar 16.2.2010, 09:07 | ||||||||
Что-то вроде этого
создаем шаблонную функцию, которая будет вызываться таймером и вызывать соответствующую member функцию. Типы можно передать в compile-time, проблема с this, это решаем таким образом - создаем класс для регистрации объектов, пусть он может хранить по умолчанию 100 объектов.
использование
Пойдет? полный пример
Это навскидку, можно доработать. |
| Автор: GremlinProg 16.2.2010, 09:15 |
в районе полугода-года я пользовался таймером без окна в объектной модели, а отказался я от использования этого таймера по причине использования им очереди сообщений независимо от того, есть HWND или нет, что в моем случае означало его бесполезность, т.к. там нужно было следить за сменой состояния этой самой очереди, масло масляное вобщем с ним выходило т.е. независимо от первого параметра, сообщение поступит в обычную очередь и будет извлечено обычным способом, тут просто предоставляется возможность в цикле сообщений дополнить это сообщение желаемым дескриптором, что на самом деле реализуется крайне редко, т.е. в основном такой таймер, с hwnd=0 используется за пределами окон вот как раз эта очередь и дальнейшее дополнение сообщения WM_TIMER и требует какой-то внутренней идентификации "импульса" таймера, чтобы можно было дальше обработать сообщение обычным образом, через процедуру окна, а другого способа ввести эту идентификацию кроме как через nIDEvent нету можно конечно и проверить, полагаю, Andrey44 это сделать проще Добавлено через 10 минут и 49 секунд если приходит не 0, значит там точно не мусор, смотри за периодом жизни объекта, думаю в этом дело |
| Автор: maxim1000 16.2.2010, 09:28 |
| есть ещё вариант специально создать окно для обработки таймера начиная с Windows XP даже есть тип окна "message only window" если уж окна совсем не хочется, можно воспользоваться waitable timer, ожидание которого можно встроить в очередь сообщений, но тогда понадобится переменная, доступная коду работы с очередью, которая хранит соответствие индексов, таймеров и функторов |
| Автор: Earnest 16.2.2010, 19:51 |
Не прокатит: его нужно ждать функцией WaitForSingleObject (или Multiple) и, соответственно, стоять. Либо писать цикл - заглянул в таймер (с нулевым ожиданием), сделал что-то и т.д. Но это страшно неудобно. В общем, WaitableTimer - отличная штука для рабочего потока, но не для главного. |
| Автор: maxim1000 16.2.2010, 22:52 | ||
есть ещё один вариант: MsgWaitForMultipleObjects эта функция позволяет объединить ожидание сообщения и различных объектов синхронизации |
| Автор: Earnest 17.2.2010, 14:33 |
| Я же говорю, неудобно: это ожидание фактически подменяет главный цикл (или дублирует). А если это какой-то левый объект, которому просто нужно время от времени что-то сделать... |