Valhalla Legends Archive

Programming => General Programming => C/C++ Programming => Topic started by: Eli_1 on February 07, 2004, 11:13 PM

Title: SetTimer()?
Post by: Eli_1 on February 07, 2004, 11:13 PM
I remember using SetTimer with VB but I don't know how to do it with C++. I tryed researching it for about an hour but everything I found uses CWnd:: which wasn't working for me. if anyone knows how I can use the SetTimer() and KillTimer() APIs with c++ please tell me.
Title: Re:SetTimer()?
Post by: Adron on February 08, 2004, 05:16 AM
You were previously making a console app - so I just wanted to warn you that SetTimer and KillTimer aren't the best for console apps.

From MSDN:
Quote

UINT_PTR SetTimer(
 HWND hWnd,              // handle to window
 UINT_PTR nIDEvent,      // timer identifier
 UINT uElapse,           // time-out value
 TIMERPROC lpTimerFunc   // timer procedure
);


You have two choices:

* Call SetTimer with the handle to your window, an (nonzero) identifier of your choice and the timeout value, then write a handler for WM_TIMER in your WindowProc. You will get that message when the timeout elapses.

* Call SetTimer with the pointer to a function you've written and the timeout value. You still need to be processing window messages or it won't work. Your function will be called when the timeout elapses.

In both cases, unused arguments should be zero.

To abort the timer, you call KillTimer with your window + identifier in the first case, or with the return value from the SetTimer call in the second case.
Title: Re:SetTimer()?
Post by: Eli_1 on February 08, 2004, 12:02 PM
Quote from: Adron on February 08, 2004, 05:16 AM
* Call SetTimer with the handle to your window, an (nonzero) identifier of your choice and the timeout value, then write a handler for WM_TIMER in your WindowProc. You will get that message when the timeout elapses.

Here's the code I have for the timer.

#include <windows.h> // for windowproc??
#include <winuser.h> // same??
#include <iostream.h>
#include <stdlib.h>

HWND hwnd;
// WNDCLASSEX wc;
int my_timer;

int main() {
   bool nostop=true;
   char input[256];
   
   hwnd=GetForegroundWindow();

   // wc.lpfnWndProc = WindowProc;
   my_timer=SetTimer(hwnd, 1, 1000, NULL);
   cout << "Timer created. hWnd->" << hwnd << "\n";
   while (nostop==true) { continue; }
   KillTimer(hwnd,my_timer);
   return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
   cout << "Timer! - uMsg->" << uMsg << "\n";
}

Output:

Timer created! hWnd->00000A70

The problem is WindowProc is never being called? any ideas?
Title: Re:SetTimer()?
Post by: iago on February 08, 2004, 12:42 PM
Like Adron said, you have to be processing messages for it to work.  In a console ap, you generally dont process messages, so it might be a lot trickier.

On a side note, that "continue;" in your code was completely unnecessary.  When it gets to the end up a loop, it will continue anyway.  A sleep(0) might be better there
Title: Re:SetTimer()?
Post by: Maddox on February 08, 2004, 02:16 PM
Quote from: Eli_1 on February 08, 2004, 12:02 PM
The problem is WindowProc is never being called? any ideas?

The reason is this is happening is because you've left the lpTimerFunc argument NULL and your TIMERPROC function's declaration is incorrect.

Try this

// this should changed in main()
my_timer=SetTimer(hwnd, 1, 1000, MyTimer);


// timer proc
VOID CALLBACK MyTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
    cout << "Timer! - uMsg->" << uMsg << "\n";
}


Hope that helps.
Title: Re:SetTimer()?
Post by: Eli_1 on February 08, 2004, 04:49 PM
Quote
error C2664: 'SetTimer' : cannot convert parameter 4 from 'void (struct HWND__ *,unsigned int,unsigned long,unsigned long)' to 'void (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,un
signed long)'
       None of the functions with this name in scope match the target type
Error executing cl.exe.

Here's some of the code I'm using

//prototypes
VOID CALLBACK TimProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);


my_timer=SetTimer(hwnd,1,int_input,TimProc);



VOID CALLBACK TimProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
   cout << "Timer! - uMsg->" << uMsg << "\n";
}
Title: Re:SetTimer()?
Post by: iago on February 08, 2004, 06:39 PM
Read the error message for this one:
Quote
error C2664: 'SetTimer' : cannot convert parameter 4 from
'void (struct HWND__ *,unsigned int,unsigned long,unsigned long)'
to
'void (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,unsigned long)'

Seems pretty obvious to me.
Title: Re:SetTimer()?
Post by: Eli_1 on February 08, 2004, 06:55 PM
what's __stdcall*?  ???
Title: Re:SetTimer()?
Post by: MrRaza on February 08, 2004, 07:13 PM
MSDN explains this all for you.
Title: Re:SetTimer()?
Post by: iago on February 08, 2004, 07:59 PM
Declare your function with _stdcall there.

void __stdcall myFunc(.....);

or, if it has to be a pointer, it's either
void *__stdcall myFunc(.....);
or
void __stdcall *myFunc(.....);
I'm not sure which is right, but I'm sure Skywing or Kp or somebody else will clear that up, or you can just try both.
Title: Re:SetTimer()?
Post by: Kp on February 08, 2004, 08:39 PM
Quote from: iago on February 08, 2004, 07:59 PM
Declare your function with _stdcall there.

void __stdcall myFunc(.....);

or, if it has to be a pointer, it's either
void *__stdcall myFunc(.....);
or
void __stdcall *myFunc(.....);
I'm not sure which is right, but I'm sure Skywing or Kp or somebody else will clear that up, or you can just try both.

The compiler should've picked up on that part automatically.  If it didn't, then he should use &TimProc as the parameter to SetTimer (use an & to explicitly take its address).  Regardless, he needs to add _stdcall to the function declaration (as you mentioned).  I'm actually rather surprised to see that error, since iirc CALLBACK is aliased to _stdcall.
Title: Re:SetTimer()?
Post by: Adron on February 09, 2004, 12:13 AM
Quote from: Maddox on February 08, 2004, 02:16 PM
Quote from: Eli_1 on February 08, 2004, 12:02 PM
The problem is WindowProc is never being called? any ideas?

The reason is this is happening is because you've left the lpTimerFunc argument NULL and your TIMERPROC function's declaration is incorrect.


Like I said before, even with a timerproc, you have to process window messages. So it will never work as long as the program consists of an endless while loop doing nothing special. Making the while loop something like:


 MSG msg;
 while(GetMessage(&msg, 0, 0, 0) == TRUE)
    DispatchMessage(&msg);


should help things. In addition to that you should use either the timerproc way, or actually make a window for your windowproc.
Title: Re:SetTimer()?
Post by: Zakath on February 09, 2004, 09:41 AM
That error is puzzling. Kp was right about CALLBACK. See the MSVS tooltip when CALLBACK is pointed at?

(http://www.valhallalegends.com/zakath/CALLBACK.png)
Title: Re:SetTimer()?
Post by: dxoigmn on February 09, 2004, 11:36 PM
Quote from: Zakath on February 09, 2004, 09:41 AM
That error is puzzling. Kp was right about CALLBACK. See the MSVS tooltip when CALLBACK is pointed at?

(http://www.valhallalegends.com/zakath/CALLBACK.png)

Your answer lies in the declaration of the arguments.  Notice how he declares the type of idEvent to UINT_PTR, it should be UINT.  Even though MSDN documents it as UINT_PTR for TimerProc Function (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/Timers/TimerReference/TimerFunctions/TimerProc.asp), in their Using Timers (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/Timers/UsingTimers.asp) example it uses the UINT convention and this is the way it is specified in WinUser.h:

WINUSERAPI
UINT
WINAPI
SetTimer(
   HWND hWnd ,
   UINT nIDEvent,
   UINT uElapse,
   TIMERPROC lpTimerFunc);