Страница 1 из 1

Таймер в класс-модуле

СообщениеДобавлено: 28.10.2016 (Пт) 16:18
pronto
Доброго времени суток, уважаемые форумчане!

Кто знает простой способ создать таймер в класс-модуле? Требований к точности никаких, поэтому задача представлялась очень простой. Есть
CreateTimerQueueTimer, SetTimer. Но облом произошёл на AddressOf при попытке указать процедуру CallBack'а в самом класс-модуле. Да, это решается перемещением процедуры в обычный модуль, но такой вариант не устраивает из-за нарушения инкапсуляции. Есть вариант с использованием вэбэшного таймера VB.Timer. Таймер помещается на форму и используется в классе, но и тут есть подвох — он один на все экземпляры класса. Встречал инфу, что де можно получить адрес на процедуру CallBack'a в самом классе, но так и не встретил конкретного решения. Видимо из-за сложности реализации. Вот такая засада...

Re: Таймер в класс-модуле

СообщениеДобавлено: 28.10.2016 (Пт) 16:24
Хакер
Самое правильное решение: иметь callback-процедуру в модуле, и эта процедура должна находить соответствующий экземпляр класса и дёргать у него соответствующий метод, а метод — генерировать событие.

Получить адрес метода класса можно, да только вот у него количество аргументов больше, чем у стандартной TimerProc, и поэтому этот адрес всё равно не получится передать в SetTimer. Кое-кто сейчас предложит подход с генерацией «ассемблерных» переходничков на лету, но я такой подход считаю грязноватым и неоправданным в данном случае.

К тому же, даже если бы не было проблемы с несовпадением числа аргументов (и как следствие — несовпадение размера стекового фрейма), то всё равно оставался бы потенциальный риск, что система попытается вызвать TimerProc уже после того, как экземпляр умер. А это светит крэшем приложения.

Re: Таймер в класс-модуле

СообщениеДобавлено: 28.10.2016 (Пт) 16:48
pronto
Хакер писал(а):и эта процедура должна находить соответствующий экземпляр класса и дёргать у него соответствующий метод

Тогда как находить соответствующий экземпляр класса?

Re: Таймер в класс-модуле

СообщениеДобавлено: 28.10.2016 (Пт) 16:51
Хакер
pronto писал(а):Тогда как находить соответствующий экземпляр класса?

У SetTimer есть параметр nIDEvent. В качестве него можно использовать любой идентификатор. TimerProc получает этот идентификатор и может делать с ним что угодно. В общем случае нужно иметь таблицу сопоставления, по которой конвертировать nIDEvent в ссылку на экземпляр. В частном случае в качестве значения nIDEvent может использоваться непосредственно указатель на экземпляр.

Re: Таймер в класс-модуле

СообщениеДобавлено: 28.10.2016 (Пт) 17:14
pronto
Благодарствую! Буду двигаться в этом направлении.

Re: Таймер в класс-модуле

СообщениеДобавлено: 19.06.2017 (Пн) 11:19
pronto
Нашёл вот такой код. Хрен его знает, как оно работает...