Win32 function for scheduled tasks in C++ - c++

I have a function in C++ that needs to be called after a period of time and this task is repeated. Do you know any built-in function or sample code in Win32 or pthread?
Thanks,
Julian

How about SetTimer.
Create a wrapper function to use as the callback for set timer.
Wrapper function calls your function.
After your function finishes, wrapper function calls SetTimer again to re-set the timer.

Just as a side note, I hope that you aren't doing something in code which could be done via the OS. (I don't know enough about your requirements to say, but I thought I'd point it out).
Things such as task-scheduler (windows) are made for scheduling recurring tasks, and they often do a better job than hand-rolled solutions.

SetTimer!
An example:
#include <windows.h>
#include <stdio.h>
void CALLBACK scheduled_task_1 (HWND hwnd, UINT msg, UINT id, DWORD time)
{
puts("Executing scheduled_task_1 every half-second event");
}
void CALLBACK scheduled_task_2 (HWND hwnd, UINT msg, UINT id, DWORD time)
{
puts("Executing scheduled_task_2 every two seconds event");
}
void CALLBACK scheduled_task_3 (HWND hwnd, UINT msg, UINT id, DWORD time)
{
puts("Executing scheduled_task_3 24 hours event");
}
void messageLoop(void) {
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0)
DispatchMessage( &msg );
}
int main(void)
{
while(true)
{
SetTimer (NULL, 0, 500, scheduled_task_1); /* every half-second */
SetTimer (NULL, 0, 2000, scheduled_task_2); /* every two seconds */
SetTimer (NULL, 0, 60*60*24*1000, scheduled_task_3); /* after 24 hours or 86400000 milliseconds */
messageLoop();
}
return 0;
}

Related

Timer ID in timer call back is different from defined timer ID

I implemented two timers with SetTimer function :
UINT TimerId1 = SetTimer(NULL, IDT_TIMER1, 2000, TimerProc);
UINT TimerId2 = SetTimer(NULL, IDT_TIMER2, 2000, TimerProc);
And pump windows messages with GetMessage loop to get timer messages too :
#define IDT_TIMER1 1
#define IDT_TIMER2 2
int main(int argc, char *argv[], char *envp[])
{
MSG Msg;
UINT TimerId1 = SetTimer(NULL, IDT_TIMER1, 2000, TimerProc);
UINT TimerId2 = SetTimer(NULL, IDT_TIMER2, 2000, TimerProc);
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0;
}
Due to handle timer messages, i implemented my custom function callback for my timer :
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
if (nMsg == WM_TIMER)
{
switch (nIDEvent)
{
case IDT_TIMER1:
cout << "Timer 1" << endl;
break;
case IDT_TIMER2:
cout << "Timer 2" << endl;
break;
}
}
}
The problem is in my callback, i cannot get the correct timer id because none of the cases are true. My timer id(s) defined as 1 and 2, but timer id(s) in callback are absolutely different, its something like 31270.
Any Suggestion?
Thread timers (when hWnd is null), as opposed to window timers, do not use the ID you give them - instead they assign their own, which is returned to you by the SetTimer function.
This is described in the docs for SetTimer:
If the hWnd parameter is NULL, and the nIDEvent does not match an
existing timer then it is ignored and a new timer ID is generated.
Note that once a thread timer is created, you can use that ID in future calls to SetTimer to modify it.
This is the solution :
At first notice that in the second parameter of SetTimer function according microsoft page (as #Jonathan Potter guidance) :
nIDEvent
Type: UINT_PTR
A nonzero timer identifier. If the hWnd parameter is NULL, and the nIDEvent does not match an existing timer then it is ignored and a new timer ID is generated.
So, my hWnd for timers are both NULL and there's no matching timer id with 1 and 2. consequently timer id returned by SetTimer (which desired id according application decision) and i have to use that to handle in my callback.
// Defined as public to use in callback
UINT TimerId1;
UINT TimerId2;
And my callback defined as the following :
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
if (nMsg == WM_TIMER)
{
if (nIDEvent == TimerId1)
{
cout << "Timer 1" << endl;
}
if (nIDEvent == TimerId2)
{
cout << "Timer 2" << endl;
}
}
}
The output is :
Timer 2
Timer 1
Timer 2
Timer 1
Timer 2
Timer 1
.
.
.

SendNotifyMessage do not send correct messages

From one thread I send the message to main thread in window procedure.
But it is unsuccessful. When I send messages from the same thread - all is ok
include "stdafx.h"
#include <Windows.h>
#include <atlbase.h>
#define MAX_THREADS 1
HWND m_wnd;
enum
{
EVENT_CALL = (WM_APP + 0x30),
};
static LRESULT CALLBACK function_call()
{
//some code
int test = 0;
return 0;
}
static LRESULT CALLBACK http_message_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case EVENT_CALL:
function_call();
return 0;
}
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
void CreateNotifyWnd()
{
WNDCLASSEX w = { 0 };
w.cbSize = sizeof(w);
w.hInstance = (HINSTANCE)&__ImageBase;
w.lpszClassName = L"uistone_http_event_wnd";
w.lpfnWndProc = http_message_proc;
::RegisterClassEx(&w);
int error = GetLastError();
m_wnd = ::CreateWindowEx(0, w.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, w.hInstance, 0);
error = GetLastError();
}
DWORD WINAPI SendThread(void* request_param)
{
::SendNotifyMessage(m_wnd, EVENT_CALL, 11, 12);
int error = GetLastError();
return 0;
}
int main()
{
CreateNotifyWnd();
HANDLE hThreadArray[MAX_THREADS];
hThreadArray[0] = CreateThread(nullptr, 0, SendThread, nullptr, 0, nullptr);
//::SendNotifyMessage(m_wnd, EVENT_CALL, 11, 12);
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
return 0;
}
Why I can not catch messages from another thread?
Thanks.
This is documented behavior. This is the relevant part from the SendNotifyMessage documentation:
If the window was created by the calling thread, SendNotifyMessage calls the window procedure for the window and does not return until the window procedure has processed the message. If the window was created by a different thread, SendNotifyMessage passes the message to the window procedure and returns immediately; it does not wait for the window procedure to finish processing the message.
This appears to work when used with a window created on the same thread, because when you call SendNotifyMessage, the function synchronously calls into the window procedure associated with the target window before returning.
If the call crosses threads, on the other hand, you'd have to run a message loop for the - now queued - message to get picked up and passed to the window procedure1). Your application doesn't run a message loop, and it exits before the message ever reaches the target window.
To fix this you'd have to run a message loop. This may or may not be the right approach to your problem. Since we don't know, what problem you are trying to solve, we cannot suggest potentially superior approaches and solutions.
1) See About Messages and Message Queues: Message Routing.

C++ Animating a button with MoveWindow()

I am new to C++ and seem to be stuck. I basically have a Window and a Button inside it(also created with CreateWindow()). I want to have the button moving on the X axis, I tried doing with MoveWindow() but I cant seem to do the animation effect. I tried writing it in a for loop but I have not found what to use to delay the animation. I would appreciate any help.
for (int i = 0; i < 50; i++) {
MoveWindow(g_MovingDot, i, ButtonTop, ButtonWidth, ButtonHeight, true);
//Delay it somehow
}
Would this be the right way to do it? I just want the button to move slowly to the right.
Use the SetTimer function to be notified when the time-out value is elapse.
Implement a function with the signature
VOID (CALLBACK* TIMERPROC)(HWND, UINT, UINT_PTR, DWORD);
and pass a function pointer to SetTimer, to register a callback procedure .
Use a global control variable, which controls the animation of the window. In the following code snippet the control variable is named i_g.
When the timer is elapsed, then the callback procedure is called. Increment the control variable, slightly move the dialog element and restart the timer, until the final position is reached.
The animation time is controlled by the number of animation steps and the time interval of a single step.
int g_i=0;
void CALLBACK BtnTimer( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
{
KillTimer( hwnd, idEvent );
if ( g_i < 50 )
{
MoveWindow(g_MovingDot, i, ButtonTop, ButtonWidth, ButtonHeight, true);
g_i ++;
SetTimer( hwnd, idEvent, 100 /* time milliseconds */, &BtnTimer );
}
}
void AnimateButton( HWND hDialogWnd //* HWND from Dialog */)
{
g_i = 0;
SetTimer( hDialogWnd, 0 /* idEvent */, 100 /* time milliseconds */, &BtnTimer );
}

win32 main loop interval issue C++

I'm making a keylogger that logs key strokes (duh..). Now when I've implemented the basic keylogger in C++, I wanted to add a new feature to the application: I want it to mail the logs to my email. So far so good, I found this open source email client that fits perfect for my needs. The only problem I have is to make the application send the logs in intervals of x minutes.
int main(int argc, char *argv[])
{
//stealth();
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelKeyBoardProc, NULL, 0);
if(hHook == NULL)
{
cout << "Hook failed" << endl;
}
MSG message;
while(GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return 0;
}
Somehow I need to implement somekind of counter which will at some point use a function send();.
Anyone got any idea how to modify the MSG loop to execute the funktion send(); each and every 5 minutes?
Take a look at the SetTimer function, I think it does exactly what you need.
Before event loop you should call this function with desired interval and you have to pass to it a callback function. Alternatively you can use another function CreateTimerQueueTimer
VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) {
}
UINT timer = SetTimer(NULL, 0, 500, &TimerProc);
MSG message;
while(GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
KillTimer(NULL, timerId);
Make a new thread to sleep x milis and then send in a while(!interrupted) loop.
As you may know, accessing the same data for read and write from 2 separate threads simultaneously will cause an error.
http://msdn.microsoft.com/en-us/library/kdzttdcb(v=vs.80).aspx
To avoid that you can use critical section
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686908(v=vs.85).aspx
Or just make your thread to sleep and turn a boolean value to true meaning 'yes we waited enough' and your main function always send data when that boolean is true then set it back to false.
edit:
I believe this is the simplier way to archieve this
while(!interrupted) { // Your thread will do this.
sleep(60000);
maysend = true;
}
[...]
if(maysend) { // Your main function will contain this
send();
maysend = false;
}

SetTimer function in a dll file

I'm writing a plugin for the musicplayer named MusicBee.
The plugin is for the Logitech G keyboards LCD.
Now I will look at buttons activity every 30ms so everyting is fast when pressing on it.
I will use the setTimer function of windows.h but I can't get it to work in my dll file.
Can someone help me with this little problem??
The code I have is (TimerProc function is a static function):
Logitech * Logitech::LogitechObject;
Logitech::Logitech(): stopthread(false), firstTime(true), position(0), duration(0)
{
LogitechObject = this;
SetTimer(NULL, 1, 30, &Logitech::TimerProc);
}
Logitech::~Logitech()
{
stopthread = true;
this->state = StatePlay::Undefined;
timerThread.detach();
}
VOID CALLBACK Logitech::TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
LogitechObject->time = 0;
LogitechObject->m_lcd.SetProgressBarPosition(LogitechObject->progressbar, static_cast<FLOAT>(100));
LogitechObject->m_lcd.Update();
SetTimer(NULL, 1, 30, &Logitech::TimerProc);
}
In order SetTimer to work the application should run "message pump" loop ( GetMessage()/DispatchMessage() ). Without it WM_TIMER message will not be delivered and so your TimerProc will not be invoked.
Use CreateTimerQueueTimer() instead.