win32 - timeSetEvent: my class Timer have 1 error?

seen my Timer class and the timeSetEvent(), do i have an error on Start() class function?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class Timer
{

private:
    UINT_PTR timerid=0;
    unsigned int intInterval=0;
    HWND windowtimer=NULL;
    UINT m_uResolution=0;

    static void CALLBACK _TimerProc(UINT wTimerID, UINT msg, DWORD_PTR dwUser, DWORD dw1, DWORD dw2)
    {
        Timer* obj =(Timer*) dwUser;
        if(obj!=nullptr && obj->timerprocedure!=nullptr)
            obj->timerprocedure();
    }

public:

    std::function<void()> timerprocedure=NULL;
    Timer(std::function<void()> tmrprocedure=NULL)
    {
        timerprocedure=tmrprocedure;
    }

    void Stop()
    {
        if(timerid!=0)
        {
            timeKillEvent(timerid);
            timeEndPeriod (m_uResolution);
            timerid=0;
        }
    }

    property <unsigned int> Interval
    {
        Get(unsigned int)
        {
            return intInterval;
        },
        Set(unsigned int uintInterval)
        {
            intInterval = uintInterval;
            Start();
        }
    };

    void Start()
    {
        Stop();
        TIMECAPS tc;
        timeGetDevCaps(&tc, sizeof(TIMECAPS));
        m_uResolution = tc.wPeriodMin;
        timeBeginPeriod(m_uResolution);
        timerid = timeSetEvent(intInterval, 0, &Timer::_TimerProc, (DWORD_PTR)this, TIME_PERIODIC);
    }

    ~Timer()
    {
        Stop();
    }
};

if i change the TIME_PERIODIC for TIME_ONESHOT, i can fix 1 error with GDIPlUS::Image, because some animations aren't playing and that change can help on that. but can anyone explain better?
(Interval it's a property... but just see what it's inside. but if is realy necessary for test 1 error, i can share it)
What kind of error do you get? Compiler, linker, runtime?
i'm sorry... i forget 'subcribe' the thread :(
in some cases the timerid is NULL and the GetLastError() give me 5: acess denied. i don't understand why. have something to do that i use a class and the _TimerProc() been static?
I would guess that the problem is threading. See:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd757634%28v=vs.85%29.aspx


This may cause race condition. See:

http://stackoverflow.com/questions/34510/what-is-a-race-condition


Another problem might be that std::function is not a pointer, hence you should neither set it to null nor compare it with null. It has the operator bool in order to find out whether it is callable or not. See:

http://www.cplusplus.com/reference/functional/function/?kw=function
i'm so sorry, but what you advice for fix it?
i'm sorry, but i don't get any idea for fix :(
1. Instead of timeSetEvent() use SetTimer():

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx

2. Do not assign NULL to std::function. Instead - for a not set function - use the default/empty contructor:

1
2
    std::function<void()> timerprocedure=NULL;
    Timer(std::function<void()> tmrprocedure=NULL std::function<void()>())


To check whether a std::function object is callable use the operator bool:

1
2
        if(obj!=nullptr && obj->timerprocedure!=nullptr)
            obj->timerprocedure();

See:

http://www.cplusplus.com/reference/functional/function/?kw=function
i'm sorry, but i use timeSetEvent() for let use 10ms or less
finally i fix these code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class Timer
{

private:
    static unsigned int TimerCount;
    UINT_PTR timerid=0;
    UINT m_uResolution=0;
    unsigned int TimerID=0;
    DWORD intInterval=0;

    static void CALLBACK MultiMediaProcedure(UINT wTimerID, UINT msg, DWORD_PTR dwUser, DWORD dw1, DWORD dw2)
    {
        Timer* obj =(Timer*) dwUser;
        if(obj!=NULL && obj->timerprocedure!=NULL)
            obj->timerprocedure();
        else
            DebugText("MultiMediaProcedure: timer not activated");
    }

public:

    std::function<void()> timerprocedure=EmptyEvent;
    Timer(std::function<void()> tmrprocedure=EmptyEvent)
    {
        TimerCount+=1;
        TimerID=TimerCount-1;
        timerprocedure=tmrprocedure;
    }

    void Stop()
    {
        if(timerid!=0)
        {
            if(timeKillEvent(timerid)==MMSYSERR_INVALPARAM)
                DebugText("error on destroying the timer: " + to_string(GetLastError()));
            timeEndPeriod (m_uResolution);
            timerid=0;
        }
    }

    DWORD GetInterval()
    {
        return intInterval;
    }

    void SetInterval(DWORD uintInterval)
    {
        intInterval = uintInterval;
    }

    //property <DWORD> Interval{GetProperty(Timer::GetInterval),SetProperty(Timer::SetInterval)};

    void Start()
    {
        Stop();
        TIMECAPS tc;
        timeGetDevCaps(&tc, sizeof(TIMECAPS));
        m_uResolution = tc.wPeriodMin;
        timeBeginPeriod(m_uResolution);
        timerid = timeSetEvent(intInterval, m_uResolution, Timer::MultiMediaProcedure, (DWORD_PTR)this, TIME_PERIODIC);
        if (timerid==NULL)
        {
            DebugText("No timer Started: " + to_string(GetLastError()));
        }
    }

    ~Timer()
    {
        if(timerid!=0)
            Stop();
        TimerCount-=1;
    }
};
unsigned int Timer::TimerCount=0;

the problems was:
1 - i had 16 timers working, without notice, but i found them;
2 - i had 1 memory leak on my image class: i was using 'delete' 2 times on a variable without recreate it.

now i only have 1 question: seems that i can have only 16 timers activated. can i change these limits?
Since these limits are not mentioned anywhere in the documentation, I have no idea how to circumvent them.


Again: Do not compare a function object (timerprocedure) with null.

test, yourself the class:
1
2
#define  min(x, y)   __min((x), (y))
#define  max(x,y)   __max((x), (y)) 

and you will see that after 16(they are Multimedia Timers), they don't fire.
in these case, i can't use SetTimer(), because i get several errors on destroying and creating on ms.
What has min()/max() to do with it?
forget that.. my mistake.. sorry. forget about that.. sorry. but test the class
that class works fine. i was getting problems from another place.
thanks for all
now i'm using, correctly, the CreateTimerQueueTimer().. thanks for all
Last edited on
Topic archived. No new replies allowed.