TimerProc
От: -Cheese-  
Дата: 12.09.06 08:37
Оценка:
Всем день добрый!

Делюсь проблемкой.
Есть класс, и есть у меня желание организовать там таймер для свох нужд.
Т.е. делаем SetTimer и передаём ему указатель на static функцию класса (чтоб она не была глобальной)
VOID CALLBACK TimerProc(
  HWND hwnd,     // handle of window for timer messages
  UINT uMsg,     // WM_TIMER message
  UINT idEvent,  // timer identifier
  DWORD dwTime   // current system time
);


Вопрос, как бы так закрутить, чтоб из функции TimerProc получить указатель на наш класс, ведь нет тут дополнительного параметра, чтоб при старте таймера можно было свой указатель впихнуть в вызов TimerProc (как, например, при создании потока)....
Спасибо.

P.s.: MSVC++ 6.0, MFC
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: TimerProc
От: Aera Беларусь  
Дата: 12.09.06 08:43
Оценка:
Здравствуйте, -Cheese-, Вы писали:


C>Вопрос, как бы так закрутить, чтоб из функции TimerProc получить указатель на наш класс, ведь нет тут дополнительного параметра, чтоб при старте таймера можно было свой указатель впихнуть в вызов TimerProc (как, например, при создании потока)....


а) Определять класс по номеру таймера
б) Создавать специальное окно, для которого вызывать таймер.
--
RedApe
Re: TimerProc
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.09.06 08:43
Оценка: 2 (1)
Здравствуйте, -Cheese-, Вы писали:

C>Т.е. делаем SetTimer и передаём ему указатель на static функцию класса (чтоб она не была глобальной)

C>
C>VOID CALLBACK TimerProc(
C>  HWND hwnd,     // handle of window for timer messages
C>  UINT uMsg,     // WM_TIMER message
C>  UINT idEvent,  // timer identifier
C>  DWORD dwTime   // current system time
C>);
C>


C>Вопрос, как бы так закрутить, чтоб из функции TimerProc получить указатель на наш класс, ведь нет тут дополнительного параметра, чтоб при старте таймера можно было свой указатель впихнуть в вызов TimerProc (как, например, при создании потока)....


Сделать глобальный (статический) map по idEvent для указателей на класс:
static std::map< UINT, MyHander * > m_timer_handlers;

И заносить в него указатель на объект как только оказываетс известным idTimer.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: TimerProc
От: Bell Россия  
Дата: 12.09.06 08:44
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Всем день добрый!


C>Делюсь проблемкой.

C>Есть класс, и есть у меня желание организовать там таймер для свох нужд.
C>Т.е. делаем SetTimer и передаём ему указатель на static функцию класса (чтоб она не была глобальной)
C>
C>VOID CALLBACK TimerProc(
C>  HWND hwnd,     // handle of window for timer messages
C>  UINT uMsg,     // WM_TIMER message
C>  UINT idEvent,  // timer identifier
C>  DWORD dwTime   // current system time
C>);
C>


C>Вопрос, как бы так закрутить, чтоб из функции TimerProc получить указатель на наш класс, ведь нет тут дополнительного параметра, чтоб при старте таймера можно было свой указатель впихнуть в вызов TimerProc (как, например, при создании потока)....

C>Спасибо.

C>P.s.: MSVC++ 6.0, MFC


Простейший вариант — положить рядом со статической функцией статический же член-указатель (если объект один) или мап hWnd->Указатель...
Любите книгу — источник знаний (с) М.Горький
Re[2]: TimerProc
От: -Cheese-  
Дата: 12.09.06 09:08
Оценка:
Здравствуйте, eao197, Вы писали:

E>Сделать глобальный (статический) map по idEvent для указателей на класс:

E>
E>static std::map< UINT, MyHander * > m_timer_handlers;
E>

E>И заносить в него указатель на объект как только оказываетс известным idTimer.
при попытке сделать хотя бы так ... у меня вываливается куча ошибок
m_timer_handlers[1]=10;


c:\program files\microsoft visual studio\vc98\include\map(94) : warning C4786: 'std::reverse_bidirectional_iterator<std::_Tree<unsigned int,std::pair<unsigned int const ,unsigned int>,std::map<unsigned int,unsigned int,std::less<unsigned int>,std::a
llocator<unsigned int> >::_Kfn,std::less<unsigned int>,std::allocator<unsigned int> >::iterator,std::pair<unsigned int const ,unsigned int>,std::pair<unsigned int const ,unsigned int> &,std::pair<unsigned int const ,unsigned int> *,int>' : identifie
r was truncated to '255' characters in the debug information
c:\program files\microsoft visual studio\vc98\include\map(93) : while compiling class-template member function 'unsigned int &__thiscall std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::operator [](c
onst unsigned int &)'
c:\program files\microsoft visual studio\vc98\include\map(94) : warning C4786: 'std::reverse_bidirectional_iterator<std::_Tree<unsigned int,std::pair<unsigned int const ,unsigned int>,std::map<unsigned int,unsigned int,std::less<unsigned int>,std::a
llocator<unsigned int> >::_Kfn,std::less<unsigned int>,std::allocator<unsigned int> >::const_iterator,std::pair<unsigned int const ,unsigned int>,std::pair<unsigned int const ,unsigned int> const &,std::pair<unsigned int const ,unsigned int> const *
,int>' : identifier was truncated to '255' characters in the debug information
c:\program files\microsoft visual studio\vc98\include\map(93) : while compiling class-template member function 'unsigned int &__thiscall std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::operator [](c
onst unsigned int &)'
c:\program files\microsoft visual studio\vc98\include\map(94) : warning C4786: 'std::pair<std::_Tree<unsigned int,std::pair<unsigned int const ,unsigned int>,std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::
_Kfn,std::less<unsigned int>,std::allocator<unsigned int> >::iterator,std::_Tree<unsigned int,std::pair<unsigned int const ,unsigned int>,std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::_Kfn,std::less<unsig
ned int>,std::allocator<unsigned int> >::iterator>' : identifier was truncated to '255' characters in the debug information
c:\program files\microsoft visual studio\vc98\include\map(93) : while compiling class-template member function 'unsigned int &__thiscall std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::operator [](c
onst unsigned int &)'
c:\program files\microsoft visual studio\vc98\include\map(94) : warning C4786: 'std::pair<std::_Tree<unsigned int,std::pair<unsigned int const ,unsigned int>,std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::
_Kfn,std::less<unsigned int>,std::allocator<unsigned int> >::const_iterator,std::_Tree<unsigned int,std::pair<unsigned int const ,unsigned int>,std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::_Kfn,std::less
<unsigned int>,std::allocator<unsigned int> >::const_iterator>' : identifier was truncated to '255' characters in the debug information
c:\program files\microsoft visual studio\vc98\include\map(93) : while compiling class-template member function 'unsigned int &__thiscall std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::operator [](c
onst unsigned int &)'
c:\program files\microsoft visual studio\vc98\include\utility(21) : warning C4786: 'std::pair<std::_Tree<unsigned int,std::pair<unsigned int const ,unsigned int>,std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int>
>::_Kfn,std::less<unsigned int>,std::allocator<unsigned int> >::iterator,bool>::pair<std::_Tree<unsigned int,std::pair<unsigned int const ,unsigned int>,std::map<unsigned int,unsigned int,std::less<unsigned int>,std::allocator<unsigned int> >::_Kfn
,std::less<unsigned int>,std::allocator<unsigned int> >::iterator,bool>' : identifier was truncated to '255' characters in the debug information
Linking...
MyClass.obj : error LNK2001: unresolved external symbol "private: static class std::map<unsigned int,unsigned int,struct std::less<unsigned int>,class std::allocator<unsigned int> > MyClass::m_timer" (?m_timer@MyClass@@0V?$map@IIU?$less@I
@std@@V?$allocator@I@2@@std@@A)
Debug/MyProg.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

MyProg.exe — 2 error(s), 5 warning(s)


кстати, на счёт варнингов... я делал
#pragma warning( disable:4786)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: TimerProc
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.09.06 09:14
Оценка:
Здравствуйте, -Cheese-, Вы писали:

E>>Сделать глобальный (статический) map по idEvent для указателей на класс:

E>>
E>>static std::map< UINT, MyHander * > m_timer_handlers;
E>>

E>>И заносить в него указатель на объект как только оказываетс известным idTimer.
C>при попытке сделать хотя бы так ... у меня вываливается куча ошибок
C>
C>m_timer_handlers[1]=10;
C>


Если вы декларировали m_timer_handlers как статический элемент класса, то вам затем ныжно было его объявить вне класса:
std::map< UINT, MyHandler * > MyTimerClass::m_timer_handlers;


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: TimerProc
От: -Cheese-  
Дата: 12.09.06 09:19
Оценка:
Здравствуйте, eao197, Вы писали:

E>Если вы декларировали m_timer_handlers как статический элемент класса, то вам затем ныжно было его объявить вне класса:

E>
E>std::map< UINT, MyHandler * > MyTimerClass::m_timer_handlers;
E>

Точно... забыл...
Ещё вопрос, а почему варнинги не убрались?
Спасибо!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: TimerProc
От: Left2 Украина  
Дата: 12.09.06 09:19
Оценка:
B>Простейший вариант — положить рядом со статической функцией статический же член-указатель (если объект один) или мап hWnd->Указатель...

Вариант покрасивее — это санки (thunks — смотри на CThunk в WTL) — чуть получше по производительности. Но поскольку они по сути своей есть хак, то могут быть проблемы с тем что современные процессоры могут отказаться работать с твоей программой без специального разрешения
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: TimerProc
От: Left2 Украина  
Дата: 12.09.06 09:21
Оценка:
C>Точно... забыл...
C>Ещё вопрос, а почему варнинги не убрались?
Потому что они совсем из другой оперы и не имеют никакого отношения к проблеме. Задави их прагмой или ключом компилятора, разрезолвить эту проблему по-человечески к сожалению нельзя
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: TimerProc
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.09.06 09:22
Оценка:
Здравствуйте, -Cheese-, Вы писали:

E>>Если вы декларировали m_timer_handlers как статический элемент класса, то вам затем ныжно было его объявить вне класса:

E>>
E>>std::map< UINT, MyHandler * > MyTimerClass::m_timer_handlers;
E>>

C>Точно... забыл...
C>Ещё вопрос, а почему варнинги не убрались?
C>Спасибо!

Про debug и отрезание имен? Это особенность MS VC 6.0, он генерирует слишком длинные mangled имена для C++, которые не помещаются в его отладочную информацию полностью. В Release или под более новыми версиями VC++ этой проблемы нет.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: TimerProc
От: -Cheese-  
Дата: 12.09.06 09:24
Оценка:
Туплю... разобрался...
Ещё раз спасибо.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: TimerProc
От: Trapper  
Дата: 12.09.06 19:31
Оценка:
Если нет необходимости поддерживать WIN95/98/ME, то можно использоваться CreateTimerQueue и CreateTimerQueueTimer. Это те же таймеры, только более навороченные, твоя проблема с их помощью решается в момент.
Trapper
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.