Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Непонятки с таймером 
:(
    Опции темы
Nemesis
Дата 18.3.2006, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 20.2.2005
Где: Москва

Репутация: нет
Всего: 5



Всем привет!!!

Встал в ступор, проблема следующая:

Создаю я таймер, как обычно, но ничего не происходит по прошествию отведенного времени, вообще не пойму в чем дело, вот урезаный код:

Код

#include <windows.h>
#include "InitGL.h"

#define IDT_TIMER1        1    // таймер для произведения вычислений

// Global Variables:
HWND        hWnd;        // handle окна
HINSTANCE    hInst;        // instance окна
RECT                 wndRect;            // размеры и позиция окна
UINT                 idTimer;              // id таймера
OpenGL        gl;                      // объект OpenGL

ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

void CALLBACK TimerProc(HWND hWnd,UINT iMsg,UINT iTimerID,DWORD dwTime);

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_KEYDOWN:
        gl.Keyboard(wParam, 0, 0);
        switch (wParam)
                  {
        case VK_ESCAPE:
            PostQuitMessage(0);
            break;
        default:
            break;
                  }
        break;
    case WM_PAINT:
        gl.Display();
        break;
    case WM_TIMER:       // пытаемся поймать таймер (1ый способ)
        switch(wParam)
        {
        case IDT_TIMER1:
            gl.Idle();
            break;
        default:
            break;
        }
        break;
    case WM_SIZE:
        GetWindowRect(hWnd, &wndRect);
        gl.Reshape(wndRect.right - wndRect.left, wndRect.bottom - wndRect.top);
        InvalidateRect(hWnd, &wndRect, FALSE);
        break;
    case WM_CREATE:
        gl.init_gl(hWnd);
        gl.MainInit(hWnd);
        idTimer = SetTimer(hWnd, IDT_TIMER1, 100, (TIMERPROC)TimerProc);         // ставим таймер
        break;
    case WM_DESTROY:
        KillTimer(hWnd, idTimer);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

void CALLBACK TimerProc(HWND hWnd,UINT iMsg,UINT iTimerID,DWORD dwTime) // пытаемся поймать таймер (2ой способ)
{
    int al;
    al = 0;
}


В чем может быть дело???

Это сообщение отредактировал(а) Nemesis - 18.3.2006, 20:44
--------------------
PM MAIL   Вверх
Romikgy
Дата 18.3.2006, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



Имхо ставится либо процедура, либо
Цитата(Nemesis @ 18.3.2006, 19:43 Найти цитируемый пост)
WM_TIMER

ловишь,
это первое,
а второе у тя ниче нигде не выполняется, что ты пытаешься увидеть??
Окромя
Цитата(Nemesis @ 18.3.2006, 19:43 Найти цитируемый пост)
gl.Idle();

что это за ф-ция неизвестно


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fixin
Дата 18.3.2006, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Цитата(Romikgy @ 18.3.2006, 21:32 Найти цитируемый пост)
Имхо ставится либо процедура, либо
Какое ИМХО? smile МСДН!
Цитата(MSDN)
If lpTimerFunc is NULL, the system posts a WM_TIMER message to the application queue
Так что, gl.Idle(); придется совать в коллбеку.

PM MAIL ICQ   Вверх
Nemesis
Дата 18.3.2006, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 20.2.2005
Где: Москва

Репутация: нет
Всего: 5



Ок, объясню по порядку. Я делал сначала первый вариант (2ой коментился и ставился NULL в (TIMERPROC), затем пробовал 2ой вариант - коментился WM_TIMER. Ни тот ни др не работал, в функциях я ставил break и туда ничего не попадало.
--------------------
PM MAIL   Вверх
Fixin
Дата 18.3.2006, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Однако, интересная конструкция... (Для отладки?)
Код
{    
    int al;    
    al = 0;    
}
А это:
Код
InvalidateRect(hWnd, &wndRect, FALSE);
перерисовывает контекст графического вывода окна, ИМХО, к ГЛю не относится, повторяю: ИМХО.
PM MAIL ICQ   Вверх
Romikgy
Дата 18.3.2006, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



Цитата(Fixin @ 18.3.2006, 21:01 Найти цитируемый пост)
Какое ИМХО? smile МСДН!

Ну не лез я в мсдн, не лез вот и сказал, что имхо!!! smile
Цитата(Nemesis @ 18.3.2006, 19:43 Найти цитируемый пост)
void CALLBACK TimerProc(HWND hWnd,UINT iMsg,UINT iTimerID,DWORD dwTime) // пытаемся поймать таймер (2ой способ)
{
    int al;
    al = 0;
}

А что здесь должно работать?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Nemesis
Дата 18.3.2006, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 20.2.2005
Где: Москва

Репутация: нет
Всего: 5



InvalidateRect(hWnd, &wndRect, FALSE); - заставляет послать WM_PAINT где вызывается мой метод отрисовки.

void CALLBACK TimerProc(HWND hWnd,UINT iMsg,UINT iTimerID,DWORD dwTime) // пытаемся поймать таймер (2ой способ)
{
int al;
al = 0;
}

а тут я ловлю операцию присвоения al = 0; это чисто для отладки, сама функция просто не вызывается вот в чем беда.. ((
--------------------
PM MAIL   Вверх
alkorax
Дата 19.3.2006, 06:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 11.3.2006

Репутация: нет
Всего: нет



Цитата(Nemesis @ 18.3.2006, 20:43 Найти цитируемый пост)
idTimer = SetTimer(hWnd, IDT_TIMER1, 100, (TIMERPROC)TimerProc);

Если указан последний параметр, сообщение окну не посылается.
Цитата(MSDN)

lpTimerFunc
[in] Pointer to the function to be notified when the time-out value elapses.
If lpTimerFunc is NULL, the system posts a WM_TIMER message to the application queue.


PM MAIL   Вверх
Nemesis
Дата 19.3.2006, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 20.2.2005
Где: Москва

Репутация: нет
Всего: 5



Цитата

If lpTimerFunc is NULL, the system posts a WM_TIMER message to the application queue.


Угу, именно так и делал в начале:

idTimer = SetTimer(hWnd, IDT_TIMER1, 100, NULL);

и пытался ловить WM_TIMER, но ничего не ловилось... Я уже даже не знаю в чем дело(( у кого-нибудь такое бывало?
--------------------
PM MAIL   Вверх
Fixin
Дата 19.3.2006, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Вызывай ghostbusters-ов. Честно говоря, бывает и такое smile попробуй отключить гл (закомментируй строку с определением его класса и все строки с ним).
PM MAIL ICQ   Вверх
Earnest
Дата 20.3.2006, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Не уверена, но что-то 1 в качестве ид-ра таймера мне не нравится. Ты проверял, что SetTimer тебе возвращает 1? Это я про способ, когда ловится WM_TIMER, без TimerProc - вроде в коде все выглядит честно. Проверь, приходит ли WM_TIMER вообще, не конкретизируя ID.


--------------------
...
PM   Вверх
maxim1000
Дата 20.3.2006, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



совсем на всякий случай - цикл обработки сообщений в порядке?


--------------------
qqq
PM WWW   Вверх
Fixin
Дата 20.3.2006, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Цитата(maxim1000 @ 20.3.2006, 19:00 Найти цитируемый пост)
цикл обработки сообщений в порядке?
Судя по приведенному коду - да.
PM MAIL ICQ   Вверх
maxim1000
Дата 20.3.2006, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



Цитата(Fixin @ 20.3.2006, 18:06 Найти цитируемый пост)
Судя по приведенному коду - да.

а что в приведенном коде наводит на такую мысль?
просто как раз самого цикла я и не увидел



--------------------
qqq
PM WWW   Вверх
Fixin
Дата 20.3.2006, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Дыыы. Перепутал обработчик с циклом. Да, пусть покажет. Но цикл редко меняется...
PM MAIL ICQ   Вверх
Nemesis
Дата 20.3.2006, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 20.2.2005
Где: Москва

Репутация: нет
Всего: 5



Прошу прощения, дома появляюсь только ближе к вечеру.
Так вот,

Цитата

Не уверена, но что-то 1 в качестве ид-ра таймера мне не нравится. Ты проверял, что SetTimer тебе возвращает 1? Это я про способ, когда ловится WM_TIMER, без TimerProc - вроде в коде все выглядит честно. Проверь, приходит ли WM_TIMER вообще, не конкретизируя ID.


Угу, SetTimer мне возвращал 1. А сообщение WM_TIMER вообще не присылается, не говоря уже о wParam`е...

Цитата

совсем на всякий случай - цикл обработки сообщений в порядке?


Вот приведу цикл:

Код

while(msg.message != WM_QUIT)
 { 
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}


а еще вот такой пробовал:

Код

while(GetMessage(&msg, 0, 0, 0))
{
    DispatchMessage(&msg);
}


Все остальные соощения нормально обрабатываются, т.е. не думаю что в этом проблема... я вообще честно говоря не понимаю в чем проблема(( впервые такое вижу... попробую сделать заново чистый проект и попробовать поставить таймер...
--------------------
PM MAIL   Вверх
B2_Russia
Дата 20.3.2006, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


В доску свой :)
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 3.7.2003
Где: Тверь

Репутация: нет
Всего: 1



1. Проверь hWnd в WM_CREATE
2. Проверь что за ошибку возвращает GetLastError если она есть при создании таймера.
3. Выше уже говорилось, посмотри вообще то приходит WM_TIMER
PM WWW ICQ   Вверх
Nemesis
Дата 20.3.2006, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 20.2.2005
Где: Москва

Репутация: нет
Всего: 5



1. hWnd правильный, есть глобальная ссылка на него (сверял).
2. При создании таймера возвращается 1, а в МСДН говорится, что при ошибке возвращается 0.
3.
Цитата
А сообщение WM_TIMER вообще не присылается
. Не, WM_TIMER не приходит...
--------------------
PM MAIL   Вверх
Nemesis
Дата 20.3.2006, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 20.2.2005
Где: Москва

Репутация: нет
Всего: 5



Создал читстый проджект, ничего не ловится.. очень странно, подскажите, где напортачил? и если не затруднит попробуйте у себя его запустить...

Код

#include <windows.h>

#define IDT_TIMER1        1    // таймер для произведения вычислений

// Global Variables:
HWND        hWnd;        // handle окна
HINSTANCE    hInst;        // instance окна
RECT        wndRect;    // размеры и позиция окна
UINT        idTimer;    // id таймера

ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int a;
    switch (message)
    {
    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            PostQuitMessage(0);
            break;
        default:
            break;
        }
        break;
    case WM_PAINT:
        break;
    case WM_TIMER:
                  a += 10;           // !тут ставлю break
        break;
    case WM_SIZE:
        GetWindowRect(hWnd, &wndRect);
        InvalidateRect(hWnd, &wndRect, FALSE);
        break;
    case WM_CREATE:
        GetWindowRect(hWnd, &wndRect);
        idTimer = SetTimer(hWnd, IDT_TIMER1, 20, (TIMERPROC)NULL);
        break;
    case WM_DESTROY:
        KillTimer(hWnd, idTimer);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    MSG msg;

    MyRegisterClass(hInstance);

    if (!InitInstance (hInstance, nCmdShow))
        return FALSE;

    ZeroMemory(&msg, sizeof(msg));

    // Main message loop:

    while(msg.message != WM_QUIT)
    { 
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    HBRUSH backColor;
    backColor = CreateSolidBrush(RGB(0,0,0));

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = (WNDPROC)WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(NULL, IDI_WINLOGO);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(backColor);
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    = LPCSTR("TEST");
    wcex.hIconSm        = 0;

    DeleteObject(backColor);

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance;

   hWnd = CreateWindow(LPCSTR("TEST"), LPCSTR("Test"), WS_OVERLAPPEDWINDOW |
       WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
      300, 300, 500, 500, NULL, NULL, hInstance, NULL);

   if (!hWnd)
      return FALSE;

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}


Это сообщение отредактировал(а) Nemesis - 20.3.2006, 23:38
--------------------
PM MAIL   Вверх
Earnest
Дата 21.3.2006, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Фокус решается просто: у тебя все жрут бесконечные paint'ы, которые ничего не делают...
Видимо, таймер имеет меньший приоритет. Закомментируй обработку WM_PAINT и убедись.
Если уж вставляешь обработчик WM_PAINT, делай как минимум BeginPaint-EndPaint - это Validate'ит окно...
И еще - у тебя там кисть создается при регистрации класса и сразу уничтожается, даже еще до регистрации. Ты уж храни ее, раз создал, а удаляй только в конце. Не обратил внимания, что окно у тебя белое, тогда как кисть вроде черная?


--------------------
...
PM   Вверх
Fixin
Дата 21.3.2006, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Код

while(msg.message != WM_QUIT)    
    {    
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))    
        {    
            TranslateMessage(&msg);    
            DispatchMessage(&msg);    
        }    
    }
А оно тебе так надо? Я не против, но можно и так:
Код

while (GetMessage(&Msg, NULL, 0, 0))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

PM MAIL ICQ   Вверх
Nemesis
Дата 22.3.2006, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 206
Регистрация: 20.2.2005
Где: Москва

Репутация: нет
Всего: 5



Цитата

Фокус решается просто: у тебя все жрут бесконечные paint'ы, которые ничего не делают...
Видимо, таймер имеет меньший приоритет. Закомментируй обработку WM_PAINT и убедись.
Если уж вставляешь обработчик WM_PAINT, делай как минимум BeginPaint-EndPaint - это Validate'ит окно...
И еще - у тебя там кисть создается при регистрации класса и сразу уничтожается, даже еще до регистрации. Ты уж храни ее, раз создал, а удаляй только в конце. Не обратил внимания, что окно у тебя белое, тогда как кисть вроде черная?


Блин, огромное спасибо! вот это отличный ликбез, все поправилось! А с кистью я мальца перемудрилsmile Просто раньше-то реально делал бегин/энд, а тут средствами опенгл решил рисовать и забыл про них вовсе.smile

Цитата

А оно тебе так надо? Я не против, но можно и так:


да честно говоря привык просто...

Большое Всем спасибо!smile

Это сообщение отредактировал(а) Nemesis - 22.3.2006, 01:47
--------------------
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1280 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.