Re[11]: Есть Timer без окна!
От: igorl Россия  
Дата: 16.10.02 15:30
Оценка:
Здравствуйте Constructor, Вы писали:

C>Но вот с решением этого вопроса... Какая-то фигня... Решил одну проблему — получил другую.

Тут во время просмотра ветки возникла интересная (но, возможно бредовая ) мысль (сам не проверял).
Нужно каким-то образом передавать указатель на объект класса (н-р, this) в функцию. Для этого можно попробовать использовать параметр nIDEvent. Тут могут возникнуть две проблемы:
1. Если захочется создать несколько таймеров, работающих с одним классом (указатель одинаков, а должен быть разным, но — см. п. 2)
2. В MSDN сказано, что если hWnd == NULL, то параметр nIDEvent игнорируется. Поэтому возможно его и можно использовать и даже задавать одинаковым для любого таймера (однако возможно, что игнорирование также заключается и в том, что он не передается в обработчик — надо проверять). Если же нельзя, то тогда плохо, т.к. тогда придется действительно пользоваться глобальными переменными или еще что-то придумывать.
Re[12]: Есть Timer без окна!
От: akela  
Дата: 16.10.02 15:38
Оценка:
Здравствуйте igorl, Вы писали:

I>Здравствуйте Constructor, Вы писали:


C>>Но вот с решением этого вопроса... Какая-то фигня... Решил одну проблему — получил другую.

I>Тут во время просмотра ветки возникла интересная (но, возможно бредовая ) мысль (сам не проверял).
I>Нужно каким-то образом передавать указатель на объект класса (н-р, this) в функцию. Для этого можно попробовать использовать параметр nIDEvent.

Это работает (проверено). Но это, по-моему, относится к разряду опасных решений.
Re[13]: Есть Timer без окна!
От: igorl Россия  
Дата: 16.10.02 16:30
Оценка:
Здравствуйте akela, Вы писали:

A>Это работает (проверено). Но это, по-моему, относится к разряду опасных решений.

Согласен. Надежным это не выглядит .
Re: Есть Timer без окна?
От: AlexRb  
Дата: 17.10.02 03:51
Оценка:
Здравствуйте Constructor, Вы писали:

C>Здравствуйте!

C>Функция SetTimer требует указать хэндл окна, сообщения OnTimer шлются тоже окну.
C>А как быть, если у класса окна нет, а хожется получать собщения через заданные промежутки времени?

Может Вам поможет Multimedia Timers в MSDN. Т.е.:
CreateWaitableTimer()
SetWaitableTimer()
WaitForSingleObject()
Re[8]: Есть Timer без окна?
От: Pushkin Россия www.linkbit.com
Дата: 17.10.02 05:19
Оценка:
Здравствуйте akela, Вы писали:

C>>Объявить TimerProc1 вне класса или как static. Проблему доступа к нужному объекту класса COutControlCtrl из TimerProc1 придется как-то решать — например, если этот объект единственный, хранить ссылку на него в глобальной переменной.


А если не единственный? Поему бы не написать:

TIMERPROC TimerProc1(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
    CMyObject* obj=(CMyObject*)idEvent;
    ........
} 

SetTimer(0, (UINT)this, 100, TimerProc1);
Re[12]: Есть Timer без окна!
От: Constructor  
Дата: 17.10.02 13:06
Оценка:
Здравствуйте akela, Вы писали:

A>Здравствуйте Constructor, Вы писали:


C>>Здравствуйте akela, Вы писали:


A>>>Здравствуйте Constructor, Вы писали:


C>>Когда я начал писать новое сообщение, Вашего ответа ещё не было

C>>Но вот с решением этого вопроса... Какая-то фигня... Решил одну проблему — получил другую.

A>А в чем проблема? Объектов больше одного? Нужен один таймер на всех или каждому свой? Можно придумать пару грязных хаков .


Да, объектов больше одного. Каждому объекту нужен свой таймер. А если, например, создать глобальную перемнную-список, в него добавлять адрес создаваемого объекта, а в TimerProc проверять, совпадает ли idEvent с каким-нибудб адресом объекта. Если совпадает, то вызывать для этого объекта обработчик?
Re[13]: Есть Timer без окна!
От: akela  
Дата: 17.10.02 14:00
Оценка:
Здравствуйте Constructor, Вы писали:

C>Да, объектов больше одного. Каждому объекту нужен свой таймер. А если, например, создать глобальную перемнную-список, в него добавлять адрес создаваемого объекта, а в TimerProc проверять, совпадает ли idEvent с каким-нибудб адресом объекта. Если совпадает, то вызывать для этого объекта обработчик?


Там где-то среди ответов (и не один раз ) появлялось предложение передавать в качестве idEvent адрес объекта, а в TimerProc приводить его к нужному типу и вызывать метод класса.
Это будет работать, хотя лично у меня такая конструкция вызывает некоторое внутреннее противодействие. Мне больше нравиться конструкция вроде статического массива указателей на объекты класса, в который объект прописывается при создании, и использования в качестве idEvent индекса элемента в массиве. Разумных аргументов за то, чтобы делать именно так, привести не могу . В общем, выбирай что хочешь .
Re[14]: Есть Timer без окна!
От: Constructor  
Дата: 17.10.02 14:14
Оценка:
Здравствуйте akela, Вы писали:

A>Здравствуйте Constructor, Вы писали:


C>>Да, объектов больше одного. Каждому объекту нужен свой таймер. А если, например, создать глобальную перемнную-список, в него добавлять адрес создаваемого объекта, а в TimerProc проверять, совпадает ли idEvent с каким-нибудб адресом объекта. Если совпадает, то вызывать для этого объекта обработчик?


A>Там где-то среди ответов (и не один раз ) появлялось предложение передавать в качестве idEvent адрес объекта, а в TimerProc приводить его к нужному типу и вызывать метод класса.


Я так сделал. Но такой способ дает сбои. Я не понял почему, в какие моменты (не выяснял), но периодически получал ссобщение, что то ли пишется память, то ли читается память коряво, короче, прога закрывалась.

A>Это будет работать, хотя лично у меня такая конструкция вызывает некоторое внутреннее противодействие. Мне больше нравиться конструкция вроде статического массива указателей на объекты класса, в который объект прописывается при создании, и использования в качестве idEvent индекса элемента в массиве. Разумных аргументов за то, чтобы делать именно так, привести не могу . В общем, выбирай что хочешь .


Я хочу попробовать способ "вроде статического массива указателей". Только мне массив не подходит — число элементов заранее неизвестно. Вот и хочу список попробовать.
Re[15]: Есть Timer без окна!
От: akela  
Дата: 17.10.02 14:24
Оценка:
Здравствуйте Constructor, Вы писали:

Только мне массив не подходит — число элементов заранее неизвестно. Вот и хочу список попробовать.

Упс. Я пользуюсь внутренней библиотекой, у нас все массивы динамические . Вот и забываю, что бывают другие массивы .
Re: Есть Timer без окна?
От: dandy  
Дата: 18.10.02 02:42
Оценка:
Здравствуйте Constructor, Вы писали:

C>Здравствуйте!

C>Функция SetTimer требует указать хэндл окна, сообщения OnTimer шлются тоже окну.
C>А как быть, если у класса окна нет, а хожется получать собщения через заданные промежутки времени?

A> Можно попробовать воспользоваться WaitableTimer, кое — какие примеры есть у Рихтера:


HANDLE CreateWaitableTimer(
PSECURITY_ATTRIBUTES psa,
BOOL fManualReset,
PCTSTR pszName);

Если пишешь будильник, скорее всего проще будет как-то получить хендл.
A>
Re[12]: Нет Timer без окна!
От: Constructor  
Дата: 18.10.02 11:50
Оценка:
Здравствуйте igorl, Вы писали:

I>Здравствуйте Constructor, Вы писали:


C>>Но вот с решением этого вопроса... Какая-то фигня... Решил одну проблему — получил другую.

I>Тут во время просмотра ветки возникла интересная (но, возможно бредовая ) мысль (сам не проверял).
I>Нужно каким-то образом передавать указатель на объект класса (н-р, this) в функцию. Для этого можно попробовать использовать параметр nIDEvent. Тут могут возникнуть две проблемы:
I>1. Если захочется создать несколько таймеров, работающих с одним классом (указатель одинаков, а должен быть разным, но — см. п. 2)
I>2. В MSDN сказано, что если hWnd == NULL, то параметр nIDEvent игнорируется. Поэтому возможно его и можно использовать и даже задавать одинаковым для любого таймера (однако возможно, что игнорирование также заключается и в том, что он не передается в обработчик — надо проверять). Если же нельзя, то тогда плохо, т.к. тогда придется действительно пользоваться глобальными переменными или еще что-то придумывать.

Что-то не выходит каменный цветок

Завел статический список указателей, в который добавляются адреса содаваемых объектов класса.
В функции TimerProc сравниваю idEvent с PtrToUlong(адрес объекта) в цикле по всем объектам. Если бы idEvent совпал с адресом, то для этого объекта я бы вызвал функцию — обработчик. Так вот никода они не совпадают! Я смотрел значения idEvent и адресов. Вот, например, адреса двух объектов: 17211120 и 17300632, в то время как в idEvent бывают 32474 и 32475! Видимо, ::SetTimer урезает числа до short... Но почему???
Re[13]: Нет Timer без окна!
От: akela  
Дата: 18.10.02 14:32
Оценка:
Здравствуйте Constructor, Вы писали:

C>Завел статический список указателей, в который добавляются адреса содаваемых объектов класса.

C>В функции TimerProc сравниваю idEvent с PtrToUlong(адрес объекта) в цикле по всем объектам. Если бы idEvent совпал с адресом, то для этого объекта я бы вызвал функцию — обработчик. Так вот никода они не совпадают!

C>Я смотрел значения idEvent и адресов. Вот, например, адреса двух объектов: 17211120 и 17300632, в то время как в idEvent бывают 32474 и 32475! Видимо, ::SetTimer урезает числа до short... Но почему???


Странно, у меня все работало...
Почему ты не хочешь в качестве idEvent использовать индекс объекта в списке, а не его адресс? Это более логично. Надо только заботиться о том, чтобы он не менялся на протяжении жизни объекта.
Re[14]: Все-таки есть Timer без окна!
От: Constructor  
Дата: 21.10.02 06:08
Оценка:
Здравствуйте akela, Вы писали:

A>Здравствуйте Constructor, Вы писали:


C>>Завел статический список указателей, в который добавляются адреса содаваемых объектов класса.

C>>В функции TimerProc сравниваю idEvent с PtrToUlong(адрес объекта) в цикле по всем объектам. Если бы idEvent совпал с адресом, то для этого объекта я бы вызвал функцию — обработчик. Так вот никода они не совпадают!

C>>Я смотрел значения idEvent и адресов. Вот, например, адреса двух объектов: 17211120 и 17300632, в то время как в idEvent бывают 32474 и 32475! Видимо, ::SetTimer урезает числа до short... Но почему???


A>Странно, у меня все работало...

A>Почему ты не хочешь в качестве idEvent использовать индекс объекта в списке, а не его адресс? Это более логично. Надо только заботиться о том, чтобы он не менялся на протяжении жизни объекта.

Я разобрался!
Дело в том, что в SetTimer вторым переметром передаешь жедаемый номер таймера, но реальный номер таймера возвращает сама функция! Его-то надо запомнить. А я в TimerProc сравнивал idEvent с теми номерами, что передавал в SetTimer! Вот в чем была фишка! Теперь все работает!
Выходит, передавать в качестве idEvent можно и индекс в списке, и адрес, и всякую лабуду!

Всем спасибо за помощь!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.