Здравствуйте Constructor, Вы писали:
C>Но вот с решением этого вопроса... Какая-то фигня... Решил одну проблему — получил другую.
Тут во время просмотра ветки возникла интересная (но, возможно бредовая ) мысль (сам не проверял).
Нужно каким-то образом передавать указатель на объект класса (н-р, this) в функцию. Для этого можно попробовать использовать параметр nIDEvent. Тут могут возникнуть две проблемы:
1. Если захочется создать несколько таймеров, работающих с одним классом (указатель одинаков, а должен быть разным, но — см. п. 2)
2. В MSDN сказано, что если hWnd == NULL, то параметр nIDEvent игнорируется. Поэтому возможно его и можно использовать и даже задавать одинаковым для любого таймера (однако возможно, что игнорирование также заключается и в том, что он не передается в обработчик — надо проверять). Если же нельзя, то тогда плохо, т.к. тогда придется действительно пользоваться глобальными переменными или еще что-то придумывать.
Здравствуйте igorl, Вы писали:
I>Здравствуйте Constructor, Вы писали:
C>>Но вот с решением этого вопроса... Какая-то фигня... Решил одну проблему — получил другую. I>Тут во время просмотра ветки возникла интересная (но, возможно бредовая ) мысль (сам не проверял). I>Нужно каким-то образом передавать указатель на объект класса (н-р, this) в функцию. Для этого можно попробовать использовать параметр nIDEvent.
Это работает (проверено). Но это, по-моему, относится к разряду опасных решений.
Здравствуйте Constructor, Вы писали:
C>Здравствуйте! C>Функция SetTimer требует указать хэндл окна, сообщения OnTimer шлются тоже окну. C>А как быть, если у класса окна нет, а хожется получать собщения через заданные промежутки времени?
Здравствуйте akela, Вы писали:
C>>Объявить TimerProc1 вне класса или как static. Проблему доступа к нужному объекту класса COutControlCtrl из TimerProc1 придется как-то решать — например, если этот объект единственный, хранить ссылку на него в глобальной переменной.
Здравствуйте akela, Вы писали:
A>Здравствуйте Constructor, Вы писали:
C>>Здравствуйте akela, Вы писали:
A>>>Здравствуйте Constructor, Вы писали:
C>>Когда я начал писать новое сообщение, Вашего ответа ещё не было C>>Но вот с решением этого вопроса... Какая-то фигня... Решил одну проблему — получил другую.
A>А в чем проблема? Объектов больше одного? Нужен один таймер на всех или каждому свой? Можно придумать пару грязных хаков .
Да, объектов больше одного. Каждому объекту нужен свой таймер. А если, например, создать глобальную перемнную-список, в него добавлять адрес создаваемого объекта, а в TimerProc проверять, совпадает ли idEvent с каким-нибудб адресом объекта. Если совпадает, то вызывать для этого объекта обработчик?
Здравствуйте Constructor, Вы писали:
C>Да, объектов больше одного. Каждому объекту нужен свой таймер. А если, например, создать глобальную перемнную-список, в него добавлять адрес создаваемого объекта, а в TimerProc проверять, совпадает ли idEvent с каким-нибудб адресом объекта. Если совпадает, то вызывать для этого объекта обработчик?
Там где-то среди ответов (и не один раз ) появлялось предложение передавать в качестве idEvent адрес объекта, а в TimerProc приводить его к нужному типу и вызывать метод класса.
Это будет работать, хотя лично у меня такая конструкция вызывает некоторое внутреннее противодействие. Мне больше нравиться конструкция вроде статического массива указателей на объекты класса, в который объект прописывается при создании, и использования в качестве idEvent индекса элемента в массиве. Разумных аргументов за то, чтобы делать именно так, привести не могу . В общем, выбирай что хочешь .
Здравствуйте akela, Вы писали:
A>Здравствуйте Constructor, Вы писали:
C>>Да, объектов больше одного. Каждому объекту нужен свой таймер. А если, например, создать глобальную перемнную-список, в него добавлять адрес создаваемого объекта, а в TimerProc проверять, совпадает ли idEvent с каким-нибудб адресом объекта. Если совпадает, то вызывать для этого объекта обработчик?
A>Там где-то среди ответов (и не один раз ) появлялось предложение передавать в качестве idEvent адрес объекта, а в TimerProc приводить его к нужному типу и вызывать метод класса.
Я так сделал. Но такой способ дает сбои. Я не понял почему, в какие моменты (не выяснял), но периодически получал ссобщение, что то ли пишется память, то ли читается память коряво, короче, прога закрывалась.
A>Это будет работать, хотя лично у меня такая конструкция вызывает некоторое внутреннее противодействие. Мне больше нравиться конструкция вроде статического массива указателей на объекты класса, в который объект прописывается при создании, и использования в качестве idEvent индекса элемента в массиве. Разумных аргументов за то, чтобы делать именно так, привести не могу . В общем, выбирай что хочешь .
Я хочу попробовать способ "вроде статического массива указателей". Только мне массив не подходит — число элементов заранее неизвестно. Вот и хочу список попробовать.
Здравствуйте Constructor, Вы писали:
C>Здравствуйте! C>Функция SetTimer требует указать хэндл окна, сообщения OnTimer шлются тоже окну. C>А как быть, если у класса окна нет, а хожется получать собщения через заданные промежутки времени?
A> Можно попробовать воспользоваться WaitableTimer, кое — какие примеры есть у Рихтера:
Здравствуйте 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... Но почему???
Здравствуйте Constructor, Вы писали:
C>Завел статический список указателей, в который добавляются адреса содаваемых объектов класса. C>В функции TimerProc сравниваю idEvent с PtrToUlong(адрес объекта) в цикле по всем объектам. Если бы idEvent совпал с адресом, то для этого объекта я бы вызвал функцию — обработчик. Так вот никода они не совпадают!
C>Я смотрел значения idEvent и адресов. Вот, например, адреса двух объектов: 17211120 и 17300632, в то время как в idEvent бывают 32474 и 32475! Видимо, ::SetTimer урезает числа до short... Но почему???
Странно, у меня все работало...
Почему ты не хочешь в качестве idEvent использовать индекс объекта в списке, а не его адресс? Это более логично. Надо только заботиться о том, чтобы он не менялся на протяжении жизни объекта.
Здравствуйте 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 можно и индекс в списке, и адрес, и всякую лабуду!