Проблема с SetWaitableTimer

Тема в разделе "WASM.WIN32", создана пользователем Puncher, 18 ноя 2005.

  1. Puncher

    Puncher New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2005
    Сообщения:
    16
    Адрес:
    Russia
    Проблема собственно следующая:



    Создаю таймер и пытаюсь его настроить. Функция SetWaitableTimer заканчивается с нулём в EAX, код ошибки:

    ERROR_NOACCESS (000003E6)



    Вот кусок кода:


    Код (Text):
    1.  
    2. ...
    3.  
    4. pParam  dd 10h                  ;параметр передаваемый в процедуру
    5. pTime   dd -10000000,-1             ;время до старта (10000000 х 0.1мс -> 1с)
    6. hTimer  dd ?                    ;хендл таймера
    7.  
    8. ...
    9. ...
    10.  
    11. lbtn1:  invoke  CreateWaitableTimer,0,0,0   ;Создаём таймер
    12.         mov     [hTimer],EAX            ;Сохраняем его нендл
    13.         invoke  SetWaitableTimer,\      ;настраиваем...
    14.                 EAX,\               ;его хендл
    15.                 pTime,\             ;указатель на время пуска (qword)
    16.                 1000,\              ;интервал действия (longword -> dword)
    17.                 TimerProc,\         ;адрес вызываемой таймером процедуры
    18.                 pParam,\            ;адрес параметра передоваемого в процедуру
    19.                 0               ;выход из suspend mode (1-да\0-нет)
    20.  
    21.         test    EAX,EAX
    22.     jz      lbtn2               ;если таймер не настроился, закрываем хендл
    23.         jmp     xfinish             ;выходим
    24.  
    25. lbtn2:  invoke  CloseHandle,[hTimer]        ;закрываем хендл таймера
    26.         jmp     xfinish
    27.  
    28. ...
    29. ...
    30.  
    31. xfinish:xor     EAX,EAX
    32. finish: pop edi esi ebx
    33.     ret
    34.  
    35. ...
    36. ...
    37.  
    38. proc TimerProc param,tmrlo,tmrhi            ;процедура таймера
    39.     push    ebx esi edi
    40.         invoke  MessageBox,[hMain],tTitle,tTitle,0 
    41.         pop     edi esi ebx
    42.     ret
    43. endp
    44.  
    45.  




    Описание параметров функции SetWaitableTimer из MSND:


    Код (Text):
    1.  
    2. BOOL SetWaitableTimer(
    3.     HANDLE hTimer,          // handle to a timer object
    4.     const LARGE_INTEGER *pDueTime,  // when timer will become signaled
    5.     LONG lPeriod,           // periodic timer interval
    6.     PTIMERAPCROUTINE pfnCompletionRoutine,  // pointer to the completion routine
    7.     LPVOID lpArgToCompletionRoutine,    // data passed to the completion routine
    8.     BOOL fResume            // flag for resume state
    9.    );
    10.  




    Памагите разобратся...



    [​IMG] _860427706__timer.rar
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    //offtop

    Я смотрю, отладка MessageBox'ами — наилюбимейшее средство начинающих и не только..
     
  3. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Puncher Умеешь задавать вопросы и хорошо что исходник выложил :) проблема в выравнивании на 4 структуры pTime, данные лучше размещать в таком порядке:



    - структуры\массивы (размером кратно 4)

    - переменные dd

    - строковые db



    У тебя же все наоборот, если так нравится то после db ставь align 4
     
  4. Puncher

    Puncher New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2005
    Сообщения:
    16
    Адрес:
    Russia
    Ага точно. Выровнять надо было :)

    Вот. Таймер создался, только теперь надо его заставить процедуру вызывать. У меня что-то нехочет :dntknw:
     
  5. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    SetTimer не выпоняет вызов процедуры это если тебе нужен обычный таймер, для асинхронных надо юзать не DispatchMessage, а SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsEx
    Код (Text):
    1. ;=====================================================================
    2. handle      dd      0
    3. ftime       FILETIME -10000000,-1
    4. ;=====================================================================
    5. entry       $
    6.             stdcall [CreateWaitableTimer],0,0,0
    7.             mov     [handle],eax
    8.             stdcall [SetWaitableTimer],eax,ftime,0,timer_proc,0,0
    9.             stdcall [SleepEx],-1,1
    10.             stdcall [CloseHandle],[handle]
    11.             stdcall [ExitProcess],0
    12. ;=====================================================================
    13. proc        timer_proc,param,tmrlo,tmrhi
    14.             stdcall [MessageBeep],MB_OK
    15.             ret
    16. endp
    17. ;=====================================================================
     
  6. Puncher

    Puncher New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2005
    Сообщения:
    16
    Адрес:
    Russia
    В общем на данном этапе сделал так:


    Код (Text):
    1.  
    2. ...
    3. invoke  SetTimer,0,ID_TIMER,1000,TimerProc
    4. mov     [hTimer],EAX
    5. ...
    6. ...
    7.  
    8. proc TimerProc hwnd,umsg,tmrid,time
    9. push ebx esi edi
    10. ...
    11. pop edi esi ebx
    12. ret
    13. endp
    14.  
    15.  




    Используя эту весч можно избежать проверки сообщения WM_TIMER. Вот только с SeetWaitableTimer пака не всё ястно, буду разбираться.

    [​IMG] _1097733319__timer_01.rar
     
  7. irrona

    irrona Member

    Публикаций:
    0
    Регистрация:
    26 май 2004
    Сообщения:
    178
    Адрес:
    Тирасполь
    Puncher

    С SetWaitableTimer работать просто, когда знаешь как
    Код (Text):
    1.  
    2. LOCAL hTimer:DWORD
    3. LOCAL dTime:ULARGE_INTEGER
    4.  
    5. or dTime.HighPart,-1  ; периодичность срабатывания
    6. mov dTime.LowPart,-100000000  ; заводим на 10 секунд
    7. invoke SetWaitableTimer,hTimer,addr dTime,0,NULL,0,FALSE
    8.  




    И все. В данном примере таймер сработает один раз через 10 секунд. После этого можешь его завести еще раз, либо отпустить вот так:
    Код (Text):
    1.  
    2. invoke CancelWaitableTimer,hTimer
    3.