Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Работа с таймером


Автор: decembrist 28.2.2005, 15:52
Народ, подскажите, кто знает!
Я работаю с функцией
Код

int main (int argc,char **argv)
{
   ...
 Init();
   ...
 auxReshapeFunc((AUXRESHAPEPROC)Reshape);
 auxMainLoop(Draw);
 return 0;
}

где в Draw у меня основной код, перерисовывается по auxMainLoop(Draw); в цикле.
А мне нужно, работать через таймер. Как это сделать???
Я вызвал в main
SetTimer(NULL, 0, 40, (TIMERPROC) MyTimerProc);
где в MyTimerProc код идентичный ф-ции Draw:
Код

int main (int argc,char **argv)
{
   ...
 Init();
   ...
 SetTimer(NULL, 0, 40, (TIMERPROC) MyTimerProc);
 auxReshapeFunc((AUXRESHAPEPROC)Reshape);
 //auxMainLoop(Draw);
 return 0;
}
По идее MyTimerProc() должна вызываться в цикле вместо Draw(), но не выходит. В чем моя ошибка? smile

Автор: Ni@m 28.2.2005, 16:39
По спецификации

// это вроде в апи
UINT SetTimer(
UINT nIDEvent,
UINT nElapse,
void ( CALLBACK* lpfnTimer )(HWND, UINT, UINT, DWORD) = NULL
) throw();


// a вот это в SDK
UINT_PTR SetTimer(
HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc
);

Попробуй апишную

Автор: decembrist 1.3.2005, 11:20
Спасибо, сейчас попробую smile

Автор: decembrist 1.3.2005, 12:02
Ni@m в апи не получится, мне тогда код программы нужно будет переписывать под апи, это дофига работы. Мне в SDK нужно smile

Автор: chipset 1.3.2005, 12:11
Может быть такое, что auxMainLoop ещё что-то делает, кроме вызова функции?

Автор: decembrist 1.3.2005, 12:38
Нет, у меня в main только одна строка auxMainLoop(Draw)
Добавлено @ 12:41
Дело в том, что в Draw по инкременту перерисовывается некий объект, скорость перерисовки зависит от приращения. А я хочу чтобы он перерисовывался по таймеру smile

Автор: maxim1000 1.3.2005, 12:57
Цитата
мне тогда код программы нужно будет переписывать под апи

а можно поинтересоваться, что это за среда разработки и почему программу придется переписывать под API?

Добавлено @ 12:58
а точнее, что мешает в первой строке программы написать #include <windows.h> и потом пользоваться API-шными функциями?

Автор: maxim1000 1.3.2005, 13:35
Код

SetTimer(NULL, 0, 40, (TIMERPROC) MyTimerProc);
auxReshapeFunc((AUXRESHAPEPROC)Reshape);
//auxMainLoop(Draw);
return 0;

здесь происходит запуск таймера, а потом почти сразу выход из программы вообще, таймер просто не успевает сработать
нужно зациклить программу (например while(true))

Автор: decembrist 2.3.2005, 12:53
Блин, совсем запутался!
Еще раз
Код

int main (int argc,char **argv)
{
  ...
Init();
  ...
auxReshapeFunc((AUXRESHAPEPROC)Reshape);

SetTimer(NULL, 0, 40, (TIMERPROC) MyTimerProc);

 return 0;
}

где в MyTimerProc() у меня основной код который должен повторяться через определенный интервал времени. Почему он не успевает сработать?
Пробовал maxim1000
while (true)
{
SetTimer(NULL, 0, 40, (TIMERPROC) MyTimerProc);

}
тогда происходит запуск в цикле таймера, а не процедуры MyTimerProc?

Автор: maxim1000 2.3.2005, 12:55
не так
SetTimer(...) всего лишь запускает процесс периодических вызовов
через указанное время процедура будет вызвана
единственное, что нужно - чтобы приложение в этот момент еще не завершилось
поэтому нужно сделать:
Код

SetTimer(...);
while(true);

Автор: decembrist 2.3.2005, 13:02
Спасибо smile , сейчас попробую!
Добавлено @ 13:07
Попробовал, последняя строка while(true); зациклила прогу, а таймер не вызывает ф-цию MyTimerProc? smile

Автор: maxim1000 2.3.2005, 13:23
хм...непонятно...
с одной стороны в MSDN говорится, что необходимо наличие окна для обработки сообщения от таймера хотя бы для того, чтобы автоматически вызвать функцию таймера
Цитата
An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER

с другой стороны там же (только выше) говорится, что можно обойтись без окна вообще:
Цитата
Handle to the window to be associated with the timer. This window must be owned by the calling thread. If this parameter is NULL, no window is associated with the timer and the nIDEvent parameter is ignored.

Добавлено @ 13:24
или,может,они полагаются на то, что Рабочий стол (0-й handle указывает на него, насколько мне известно) сам обработает это сообщение и вызовет функцию...как-то не верится...
Добавлено @ 13:25
ладно, я все равно обычно пользуюсь ожидаемыми таймерами:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/using_waitable_timer_objects.asp

Автор: decembrist 2.3.2005, 13:36
Я попробовал так
Код

int main (int argc,char **argv)
{
 ...
Init();
 ...
auxReshapeFunc((AUXRESHAPEPROC)Reshape);

SetTimer(NULL, 0, 40, (TIMERPROC) MyTimerProc);
auxMainLoop(Draw);

return 0;
}

VOID CALLBACK MyTimerProc(
   HWND hwnd,        // handle to window for timer messages
   UINT message,     // WM_TIMER message
   UINT idTimer,     // timer identifier
   DWORD dwTime)     // current system time
{
timeRadar++;
Draw();
}

auxMainLoop(Draw); работает как обработчик сообщения WM_PAINT
то есть вызывает перерисовку созданного мной изображения.
Теперь идет обращение к MyTimerProc().
Но у меня другой глюк всплыл. На SetTimer я устанавливаю разные интервалы временип, а у меня одна скорость smile

Автор: maxim1000 2.3.2005, 13:45
а-а-а-а... как же до меня не дошло сразу...
все предельно просто: надо просто вспомнить, что сообщения приходят не к окнам, а к потокам, которые их создали, а те уже (если захотят, конечно) рассылают их своим окнам
а тут ничего даже рассылать не надо:
Код

#include <windows.h>

void main()
{
 MSG msg;
 SetTimer(0,125,1000,0);
 while(GetMessage(&msg,0,0,0)>0)
 {
   if(msg.message==WM_TIMER)
     MessageBox(0,"timer","timer",MB_OK);//тут можно чего-нибудь вызывать...
   else
   {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
   }
 }
}

Добавлено @ 13:48
ну вот...а тут уже ответили...
http://forum.vingrad.ru/index.php?showtopic=44017&hl=
вот что бывает, когда в двух темах идет обсуждение практически одного вопроса...

Автор: decembrist 2.3.2005, 13:58
Спасибо,
maxim1000 за помощь.

Автор: decembrist 4.3.2005, 11:49
Народ, у меня всплыла такая фигня!Когда я переписал прогу под таймер (по вашим рекомендациям smile ) у меня изменился масштаб при перерисовке smile . Т.е. когда я запускаю программу, рисуется все нормально, но если я сворачиваю окно, а потом его активизирую, масштаб рисунка уменьшается в 5 раз.
Вот программа до включения таймера:
Код

int main (int argc,char **argv)
{
 if ((argc == GL_FALSE)||(argv == GL_FALSE))
 {
    auxQuit();
 }
 auxInitPosition(0, 0, 550, 550);//расположение окна 550 - 95mm
 auxInitDisplayMode(AUX_RGB|AUX_DOUBLE);
 
 if (auxInitWindow("Индикатор кругового обзора") == GL_FALSE)
 {
    auxQuit();
 }
 Init();
 auxIdleFunc(Draw);
 auxReshapeFunc((AUXRESHAPEPROC)Reshape);
 auxMainLoop(Draw);
 return 0;
}

а вот после:

Код

int main (int argc,char **argv)
{
 if ((argc == GL_FALSE)||(argv == GL_FALSE))
 {
    auxQuit();
 }
 auxInitPosition(0, 0, 550, 550);//расположение окна 550 - 95mm
 auxInitDisplayMode(AUX_RGB|AUX_DOUBLE);
 
 if (auxInitWindow("Индикатор кругового обзора") == GL_FALSE)
 {
    auxQuit();
 }
 Init();
 auxIdleFunc(Draw);
 auxReshapeFunc((AUXRESHAPEPROC)Reshape);
 SetTimer(NULL, 125,  40, (TIMERPROC) MyTimerProc);
 MSG msg;
  while (GetMessage(&msg, NULL, 0, 0))
  {
      TranslateMessage(&msg);
         DispatchMessage(&msg);
  }

  KillTimer(NULL, 125);
 //auxMainLoop(Draw);
 return 0;
}

где ф-ция MyTimerProc вызывает Draw()

Автор: decembrist 4.3.2005, 12:16
Тут что-то с перерисовкой auxReshapeFunc((AUXRESHAPEPROC)Reshape);
только я никак не могу понять что именно smile

Автор: decembrist 4.3.2005, 13:49
Тестировал пошагово, на строчке
auxReshapeFunc((AUXRESHAPEPROC)Reshape);
первый раз, при запуске нет вхождения в ф-цию Reshape, в отличие от первого варианта... Только вот почему понять не могу. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)