I am encoutering a issues with win32 programming doing a serial port communication using a event-driven approach. I have my communication handle created as:
hComm = CreateFile(lpszCommName, GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, 0, NULL);
and i set my CommTimeouts as:
commTimeout.ReadIntervalTimeout = MAXWORD;
commTimeout.ReadTotalTimeoutConstant = 0;
commTimeout.ReadTotalTimeoutMultiplier = 0;
commTimeout.WriteTotalTimeoutConstant = 0;
commTimeout.WriteTotalTimeoutMultiplier = 0;
I created a thread for ReadFile which looks like this:
SetCommMask(hComm, EV_RXCHAR);
while (isConnected)
{
if (WaitCommEvent(hComm, &dwEvent, NULL)) //If i comment out this block my write file will work fine
{
ClearCommError(hComm, &dwError, &cs);
if ((dwEvent & EV_RXCHAR) && cs.cbInQue)
{
if (!ReadFile(hComm, str, cs.cbInQue, &read_byte, NULL))
/* Process error*/
else if (read_byte)
/* Print to screen */
}
else {
/* Process error*/
}
}
}
PurgeComm(hComm, PURGE_RXCLEAR);
My Wrifile goes into WndProc which sends characters to the communication device when WM_CHAR is triggered:
VOID Write_To_Serial(WPARAM wParam, HWND hwnd){
DWORD write_byte;
char str[10];
sprintf_s(str, "%c", (char)wParam); //Convert wParam to a string
WriteFile(hComm, str, strlen(str), &write_byte, NULL)//Program hangs here
}
My problem is everytime WriteFile() is called my application hangs and I have to force to close it. And if I comment out the WaitCommEvent() in my read thread it works fine, but I can't read then.Any pointers would be appreciated. thanks
This is the expected behavior of Synchronous IO operations.
As per the following description in Serial Communications article in MSDN (https://msdn.microsoft.com/en-us/library/ff802693.aspx),
It is the responsibility of the application to serialize access to the
port correctly. If one thread is blocked waiting for its I/O operation
to complete, all other threads that subsequently call a communications
API will be blocked until the original operation completes. For
instance, if one thread were waiting for a ReadFile function to
return, any other thread that issued a WriteFile function would be
blocked.
WriteFile has to wait until WaitCommEvent function has completed its operation.
A small workaround would be to cancel the pending WaitCommEvent operation (for instance by using CancelIoEx API) when WriteFile needs to be invoked.
VOID Write_To_Serial(WPARAM wParam, HWND hwnd){
DWORD write_byte;
char str[10];
sprintf_s(str, "%c", (char)wParam); //Convert wParam to a string
CancelIoEx(hComm, NULL);
WriteFile(hComm, str, strlen(str), &write_byte, NULL);//Program hangs here
}
WaitCommEvent returns FALSE when canceled. Hence,the code following WaitCommEvent will not be executed.
However, in extreme case, there is a chance, where the thread invoking the ReadFile function, re invokes the WaitCommEvent function, before WndProc gets to WriteFile. If this occurs, it needs to be handled separately. Maybe a small delay when WaitCommEvent returns FALSE would do.
Related
Background: generally, if we want to force an operation to happen asynchronously (to avoid blocking the main thread), using FILE_FLAG_OVERLAPPED is insufficient, because the operation can still complete synchronously.
So let's say that, to avoid this, we defer the operation to a worker thread dedicated to I/O. This avoids blocking the main thread.
Now the main thread can use CancelIoEx(HANDLE, LPOVERLAPPED) to cancel the I/O operation initiated (say, via ReadFile) by the worker.
However, for CancelIoEx to succeed, the main thread needs a way to guarantee that the operation has in fact started, otherwise there is nothing to cancel.
The obvious solution here is to make the worker thread set an event after its call to e.g. ReadFile returns, but that now brings us back to the original problem: since ReadFile can block, we'll have defeated the entire purpose of having a worker thread in the first place, which was to ensure that the main thread isn't blocked on the I/O.
What's the "right" way to solve this? Is there a good way to actually force an I/O operation to happen asynchronously while still being able to request its cancellation later in a race-free manner when the I/O hasn't yet finished?
The only thing I can think of is to set a timer to periodically call CancelIoEx while the I/O hasn't completed, but that seems incredibly ugly. Is there a better/more robust solution?
you need in general do next:
every file handle which you use to asynchronous I/O incapsulate to
some c/c++ object (let name it IO_OBJECT)
this object need have reference count
before start asynchronous I/O operation - you need allocate another
object, which incapsulate OVERLAPPED or IO_STATUS_BLOCK (let name
it IO_IRP) inside IO_IRP store referenced pointer to IO_OBJECT
and specific io information - I/O code (read, write, etc) buffers
pointers,..
check return code of I/O operation for determinate, are will be I/O
callback (packet queued to iocp or apc) or if operation fail (will be
no callback) - call callback by self just with error code
I/O manager save pointer which you pass to I/O in IRP structure (UserApcContext) and
pass it back to you when I/O finished (if use win32 api this pointer
equal pointer to OVERLAPPED in case native api - you can direct by
self control this pointer)
when I/O finishid (if not synchronous fail at begin) - callback with
final I/O status will be called
here you got back pointer to IO_IRP (OVERLAPPED) - call method of
IO_OBJECT and release it reference, delete IO_IRP
if you at some point can close object handle early (not in
destructor) - implement some run-down protection, for not access
handle after close
run-down protection very similar to weak-refefence, unfortunatelly no
user mode api for this, but not hard implement this byself
from any thread, where you have pointer (referenced of course) to your object, you can call CancelIoEx or close object handle - if file have IOCP, when last handle to file is closed - all I/O operations will be canceled. however for close - you need not call CloseHandle direct but begin run-down and call CloseHandle when run-down completed (inside some ReleaseRundownProtection call (this is demo name, no such api)
some minimal tipical implementation:
class __declspec(novtable) IO_OBJECT
{
friend class IO_IRP;
virtual void IOCompletionRoutine(
ULONG IoCode,
ULONG dwErrorCode,
ULONG dwNumberOfBytesTransfered,
PVOID Pointer) = 0;
void AddRef();
void Release();
HANDLE _hFile = 0;
LONG _nRef = 1;
//...
};
class IO_IRP : public OVERLAPPED
{
IO_OBJECT* _pObj;
PVOID Pointer;
ULONG _IoCode;
IO_IRP(IO_OBJECT* pObj, ULONG IoCode, PVOID Pointer) :
_pObj(pObj), _IoCode(IoCode), Pointer(Pointer)
{
pObj->AddRef();
}
~IO_IRP()
{
_pObj->Release();
}
VOID CALLBACK IOCompletionRoutine(
ULONG dwErrorCode,
ULONG dwNumberOfBytesTransfered,
)
{
_pObj->IOCompletionRoutine(_IoCode,
dwErrorCode, dwNumberOfBytesTransfered, Pointer);
delete this;
}
static VOID CALLBACK FileIOCompletionRoutine(
ULONG status,
ULONG dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped
)
{
static_cast<IO_IRP*>(lpOverlapped)->IOCompletionRoutine(
RtlNtStatusToDosError(status), dwNumberOfBytesTransfered);
}
static BOOL BindIoCompletion(HANDLE hObject)
{
return BindIoCompletionCallback(hObject, FileIOCompletionRoutine, 0));
}
void CheckErrorCode(ULONG dwErrorCode)
{
switch (dwErrorCode)
{
case NOERROR:
case ERROR_IO_PENDING:
return ;
}
IOCompletionRoutine(dwErrorCode, 0);
}
void CheckError(BOOL fOk)
{
return CheckErrorCode(fOk ? NOERROR : GetLastError());
}
};
///// start some I/O // no run-downprotection on file
if (IO_IRP* irp = new IO_IRP(this, 'some', 0))
{
irp->CheckErrorCode(ReadFile(_hFile, buf, cb, 0, irp));
}
///// start some I/O // with run-downprotection on file
if (IO_IRP* irp = new IO_IRP(this, 'some', 0))
{
ULONG dwError = ERROR_INVALID_HANDLE;
if (AcquireRundownProtection())
{
dwError = ReadFile(_hFile, buf, cb, 0, irp) ? NOERROR : GetLastError();
ReleaseRundownProtection();
}
irp->CheckErrorCode(dwError);
}
some more full implementation
However, for CancelIoEx to succeed, the main thread needs a way to
guarantee that the operation has in fact started, otherwise there is
nothing to cancel.
yes, despite you can safe call CancelIoEx at any time, even if no active I/O on file, by fact another thread can start new I/O operation already after you call CancelIoEx. with this call you can cancel current known single started operations. for instance - you begin conect ConnectEx and update UI (enable Cancel button). when ConnectEx finished - you post message to UI (disable Cancel button). if user press Cancel until I/O (ConnectEx) ative - you call CancelIoEx - as result connect will be canceled or finished normally bit early. in case periodic operations (for instance ReadFile in loop) - usually CancelIoEx not correct way for stop such loop. instead you need call CloseHandle from control thread - -which effective cancell all current I/O on file.
about how ReadFile and any asynchronous I/O api work and are we can force faster return from api call.
I/O manager check input parameter, convert handles (file handle to
FILE_OBJECT) to pointers, check permissions, etc. if some error on
this stage - error returned for caller and I/O finished
I/O manager call driver. driver (or several drivers - top driver can
pass request to another) handle I/O request (IRP) and finally
return to I/O manager. it can return or STATUS_PENDING, which mean
that I/O still not completed or complete I/O (call
IofCompleteRequest) and return another status. any status other
than STATUS_PENDING mean that I/O completed (with success, error
or canceled, but completed)
I/O mahager check for STATUS_PENDING and if file opened for
synchronous I/O (flag FO_SYNCHRONOUS_IO ) begin wait in place,
until I/O completed. in case file opened for asynchronous I/O - I/O
manager by self never wait and return status for caller, including
STATUS_PENDING
we can break wait in stage 3 by call CancelSynchronousIo. but if wait was inside driver at stage 2 - impossible break this wait in any way. any Cancel*Io* or CloseHandle not help here. in case we use asynchronous file handle - I/O manager never wait in 3 and if api call wait - it wait in 2 (driver handler) where we can not break wait.
as resutl - we can not force I/O call on asynchronous file return faster. if driver under some condition will be wait.
and more - why we can not break driver wait, but can stop I/O manager wait. because unknown - how, on which object (or just Sleep), for which condition driver wait. what will be if we break thread wait before contidions meet.. so if driver wait - it will be wait. in case I/O manager - he wait for IRP complete. and for break this wait - need complete IRP. for this exist api, which mark IRP as canceled and call driver callback (driver must set this callback in case it return before complete request). driver in this callback complete IRP, this is awaken I/O manager from wait (again it wait only on synchrnous files) and return to caller
also very important not confuse - end of I/O and end of api call. in case synchronous file - this is the same. api returned only after I/O completed. but for asynchronous I/O this is different things - I/O can still be active, after api call is return (if it return STATUS_PENDING or ERROR_IO_PENDING for win32 layer).
we can ask for I/O complete early by cancel it. and usually (if driver well designed) this work. but we can not ask api call return early in case asynchronous I/O file. we can not control when, how fast, I/O call (ReadFile in concrete case) return. but can early cancel I/O request after I/O call (ReadFile) return . more exactly after driver return from 2 and because I/O manager never wait in 3 - can say that I/O call return after driver return control.
if one thread use file handle, while another can close it, without any synchronization - this of course lead to raice and errors. in best case ERROR_INVALID_HANDLE can returned from api call, after another thread close handle. in worst case - handle can be reused after close and we begin use wrong handle with undefined results. for protect from this case need use handle only inside run-down protection (similar to convert weak reference to strong ).
demo implementation:
class IoObject
{
HANDLE _hFile = INVALID_HANDLE_VALUE;
LONG _lock = 0x80000000;
public:
HANDLE LockHandle()
{
LONG Value, PreviousValue;
if (0 > (Value = _lock))
{
do
{
PreviousValue = InterlockedCompareExchangeNoFence(&_lock, Value + 1, Value);
if (PreviousValue == Value) return _hFile;
} while (0 > (Value = PreviousValue));
}
return 0;
}
void UnlockHandle()
{
if (InterlockedDecrement(&_lock) == 0)
{
_hFile = 0; // CloseHandle(_hFile)
}
}
void Close()
{
if (LockHandle())
{
_interlockedbittestandreset(&_lock, 31);
UnlockHandle();
}
}
void WrongClose()
{
_hFile = 0; // CloseHandle(_hFile)
}
BOOL IsHandleClosed()
{
return _hFile == 0;
}
};
ULONG WINAPI WorkThread(IoObject* pObj)
{
ULONG t = GetTickCount();
int i = 0x1000000;
do
{
if (HANDLE hFile = pObj->LockHandle())
{
SwitchToThread(); // simulate delay
if (pObj->IsHandleClosed())
{
__debugbreak();
}
pObj->UnlockHandle();
}
else
{
DbgPrint("[%x]: handle closed ! (%u ms)\n", GetCurrentThreadId(), GetTickCount() - t);
break;
}
} while (--i);
return 0;
}
ULONG WINAPI WorkThreadWrong(IoObject* pObj)
{
ULONG t = GetTickCount();
int i = 0x10000000;
do
{
if (pObj->IsHandleClosed())
{
DbgPrint("[%x]: handle closed ! (%u ms)\n", GetCurrentThreadId(), GetTickCount() - t);
break;
}
SwitchToThread(); // simulate delay
if (pObj->IsHandleClosed())
{
__debugbreak();
}
} while (--i);
return 0;
}
void CloseTest()
{
IoObject obj;
ULONG n = 8;
do
{
if (HANDLE hThread = CreateThread(0, 0x1000, (PTHREAD_START_ROUTINE)WorkThread, &obj, 0, 0))
{
CloseHandle(hThread);
}
} while (--n);
Sleep(50);
//#define _WRONG_
#ifdef _WRONG_
obj.WrongClose();
#else
obj.Close();
#endif
MessageBoxW(0,0,0,0);
}
with WrongClose(); call we permanent will be catch __debugbreak() (use after close) in WorkThread[Wrong]. but with obj.Close(); and WorkThread we must never catch exception. also note that Close() is lock-free and caller of it never wait/hang even if api call inside rundown-protection will wait.
I'm trying to write a simple UDP transfer program in Labwindows/CVI.
The idea is it creates 2 UDP channels, uses one to write data to a port, and the other to receive the data and print it out.
Here's the receiving end:
//Called whenever data arrives on port
int CVICALLBACK udpCallback(unsigned channel, int eventType, int errCode, void *callbackData)
{
printf("Callback called\n");
//Gets the data from port
readChannel();
return 0;
}
void createReadChannel()
{
//Channel for given port, receiving from any IP address
CreateUDPChannelConfig(port, UDP_ANY_ADDRESS, 0, NULL, NULL, &readerChannel);
//Attach callback to channel (above)
SetUDPAttribute(readerChannel, ATTR_UDP_CALLBACK, udpCallback);
printf("Read channel created\n");
}
My main problem is just that when I run it in debug mode, the shown callback function is never called, i.e. "Callback called" is not printed, not is any data stored or printed in the resulting readChannel() call.
However, when compiled and executed as an .exe, it works as intended. Every time data is received on that port the callback executes.
What difference could there be between the debug and 'release' version that would cause this to happen?
EDIT: After much testing I believe it has to do with waiting for messages using functions like getchar() which caused the main thread to hang up. Why it worked in release mode I don't know, but it probably has something to do with the difference in output window(?). My solution was to remove the callbacks and run the receiving channel on it's own thread.
This way the thread is always waiting for a message, using:
UDPRead(readerChannel, 0, 0, UDP_WAIT_FOREVER, NULL, NULL)) < 0)
And then my main thread can pick up messages as needed.
If anyone has any additional info let me know.
Is it possible to wait for all processes launched by a child process in Windows? I can't modify the child or grandchild processes.
Specifically, here's what I want to do. My process launches uninstallA.exe. The process uninistallA.exe launches uninstallB.exe and immediately exits, and uninstallB.exe runs for a while. I'd like to wait for uninstallB.exe to exit so that I can know when the uninstall is finished.
Create a Job Object with CreateJobObject. Use CreateProcess to start UninstallA.exe in a suspended state. Assign that new process to your job object with AssignProcessToJobObject. Start UninstallA.exe running by calling ResumeThread on the handle of the thread you got back from CreateProcess.
Then the hard part: wait for the job object to complete its execution. Unfortunately, this is quite a bit more complex than anybody would reasonably hope for. The basic idea is that you create an I/O completion port, then you create the object object, associate it with the I/O completion port, and finally wait on the I/O completion port (getting its status with GetQueuedCompletionStatus). Raymond Chen has a demonstration (and explanation of how this came about) on his blog.
Here's a technique that, while not infallible, can be useful if for some reason you can't use a job object. The idea is to create an anonymous pipe and let the child process inherit the handle to the write end of the pipe.
Typically, grandchild processes will also inherit the write end of the pipe. In particular, processes launched by cmd.exe (e.g., from a batch file) will inherit handles.
Once the child process has exited, the parent process closes its handle to the write end of the pipe, and then attempts to read from the pipe. Since nobody is writing to the pipe, the read operation will block indefinitely. (Of course you can use threads or asynchronous I/O if you want to keep doing stuff while waiting for the grandchildren.)
When (and only when) the last handle to the write end of the pipe is closed, the write end of the pipe is automatically destroyed. This breaks the pipe and the read operation completes and reports an ERROR_BROKEN_PIPE failure.
I've been using this code (and earlier versions of the same code) in production for a number of years.
// pwatch.c
//
// Written in 2011 by Harry Johnston, University of Waikato, New Zealand.
// This code has been placed in the public domain. It may be freely
// used, modified, and distributed. However it is provided with no
// warranty, either express or implied.
//
// Launches a process with an inherited pipe handle,
// and doesn't exit until (a) the process has exited
// and (b) all instances of the pipe handle have been closed.
//
// This effectively waits for any child processes to exit,
// PROVIDED the child processes were created with handle
// inheritance enabled. This is usually but not always
// true.
//
// In particular if you launch a command shell (cmd.exe)
// any commands launched from that command shell will be
// waited on.
#include <windows.h>
#include <stdio.h>
void error(const wchar_t * message, DWORD err) {
wchar_t msg[512];
swprintf_s(msg, sizeof(msg)/sizeof(*msg), message, err);
printf("pwatch: %ws\n", msg);
MessageBox(NULL, msg, L"Error in pwatch utility", MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL);
ExitProcess(err);
}
int main(int argc, char ** argv) {
LPWSTR lpCmdLine = GetCommandLine();
wchar_t ch;
DWORD dw, returncode;
HANDLE piperead, pipewrite;
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
char buffer[1];
while (ch = *(lpCmdLine++)) {
if (ch == '"') while (ch = *(lpCmdLine++)) if (ch == '"') break;
if (ch == ' ') break;
}
while (*lpCmdLine == ' ') lpCmdLine++;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&piperead, &pipewrite, &sa, 1)) error(L"Unable to create pipes: %u", GetLastError());
GetStartupInfo(&si);
if (!CreateProcess(NULL, lpCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
error(L"Error %u creating process.", GetLastError());
if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED) error(L"Error %u waiting for process.", GetLastError());
if (!GetExitCodeProcess(pi.hProcess, &returncode)) error(L"Error %u getting exit code.", GetLastError());
CloseHandle(pipewrite);
if (ReadFile(piperead, buffer, 1, &dw, NULL)) {
error(L"Unexpected data received from pipe; bug in application being watched?", ERROR_INVALID_HANDLE);
}
dw = GetLastError();
if (dw != ERROR_BROKEN_PIPE) error(L"Unexpected error %u reading from pipe.", dw);
return returncode;
}
There is not a generic way to wait for all grandchildren but for your specific case you may be able to hack something together. You know you are looking for a specific process instance. I would first wait for uninstallA.exe to exit (using WaitForSingleObject) because at that point you know that uninstallB.exe has been started. Then use EnumProcesses and GetProcessImageFileName from PSAPI to find the running uninstallB.exe instance. If you don't find it you know it has already finished, otherwise you can wait for it.
An additional complication is that if you need to support versions of Windows older than XP you can't use GetProcessImageFileName, and for Windows NT you can't use PSAPI at all. For Windows 2000 you can use GetModuleFileNameEx but it has some caveats that mean it might fail sometimes (check docs). If you have to support NT then look up Toolhelp32.
Yes this is super ugly.
Use a named mutex.
One possibility is to install Cygwin and then use the ps command to watch for the grandchild to exit
So far I've worked with processes and threads only on Linux platform.
Now I tried to move on Windows. And I got immediately stopped on very simple program.
Can you tell me why my program doesn't write anything if I remove the line with getch?
I want my thread to finish without me pressing anything.
Thank you in advance
#include <windows.h>
#include <stdio.h>
DWORD WINAPI ThreadFunc()
{
printf("lets print something");
return 0;
}
VOID main( VOID )
{
DWORD dwThreadId;
HANDLE hThread;
hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadFunc, // thread function
NULL, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
// Check the return value for success.
if (hThread == NULL)
{
printf( "CreateThread failed (%d)\n", GetLastError() );
}
else
{
_getch();
CloseHandle( hThread );
}
}
If your box is relatively idle, the OS is quilte likely to signal the thread creation request to another core, so allowing the 'main' thread, (the one created by the process loader), to run on quickly. By the time your new thread gets round to calling the OS with the printf call, the main thread has already returned, the state of all threads for that process has been set to 'never run again' and a termination request queued up for it on its inter-processor core driver. The new thread is exterminated there and then and the now-redundant termination request discarded.
This question already has answers here:
Can I use a SetTimer() API in a console C++ application?
(6 answers)
Closed 9 years ago.
I have below program. I would like to know how setTimer works. So, I wrote a program but could not able to understand why TimerProc function not getting called. Why? What else need to be done to fire setTimer/TimerProc. Please help.
#include <windows.h>
#include <stdio.h>
VOID CALLBACK TimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
) {
printf("from callback\n");
}
int main(int argc, char *argv[])
{
UINT timerid = SetTimer(NULL,1,1000,TimerProc);/*changed the time from 1 to 1000, but no effect*/
printf("timerid %d\n",timerid);
int i,j;
//delay loop, waiting for the callback function to be called
for(j=0;j<0xffffffff;j++);
/*{
printf("%d\n", j);
}*/
printf("done \n");
system("PAUSE");
return 0;
}
The timer works via a Windows message queue and you have a console application.
If you create a basic Win32 application so you get a window and a message loop, when the WM_TIMER message is caught by the DefWndProc() call, that's where it will do the callback. Of course you can also trap the WM_TIMER yourself.
The SetTimer documentation says:
*When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.*
Instead the delay loop you need something like:
bool bStillBusy = false;
int main()
{
MSG msg;
bStillBusy = true;
id = SetTimer(NULL, 0, 3000, (TIMERPROC) TimerProc);
while(bStillBusy)
{
GetMessage(&msg, NULL, 0, 0);
DispatchMessage(&msg);
}
...
etc.
}
You set the bStillBusy to 'false' in the callback then.
You need to learn the message loop paradigm. You are trying to use Win32 api without actually doing the right Win32 initialization and operations.
If you come from Posix, you'd could use a SIGALRM and alarm.
On windows, I'm afraid you'll have more work to do (like starting a message loop, because even when you provide a callback function, you need a message loop pumping that's calling the default message loop processing function will call your timer's callback, check this:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx
An application can process WM_TIMER messages by including a WM_TIMER case statement in the
window procedure or by specifying a TimerProc callback function when creating the timer.
When you specify a TimerProc callback function, the default window procedure calls the
callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in
the calling thread, even when you use TimerProc instead of processing WM_TIMER.
Timer are handled using the normal Windows event system, so you need a normal event loop.