/* The original version of this program can be found at http://damb.dk */
#include <windows.h>
#include <iostream>

class ThreadBaseClass
{
public:
   static DWORD WINAPI ThreadFunc(void *aObj)
   {
      ThreadBaseClass *obj = (ThreadBaseClass *)aObj;
      return obj->ThreadEntry();
   }
   HANDLE Run()
   {
      ThreadHandle = CreateThread(0, 0, ThreadFunc, (void *)this, 0, &ThreadId);
      return ThreadHandle;
   }

   virtual DWORD ThreadEntry() = 0;
   DWORD ThreadId;
   HANDLE ThreadHandle;
};

class ThreadOneClass : public ThreadBaseClass
{
public:
   DWORD ThreadEntry();
};


class ThreadTwoClass : public ThreadBaseClass
{
public:
   DWORD ThreadEntry();
};

ThreadOneClass ThreadOne;
ThreadTwoClass ThreadTwo;
DWORD MainThreadId;

int main()
{
   MainThreadId = GetCurrentThreadId();
   ThreadOne.Run();
   ThreadTwo.Run();
   MSG msg;
   GetMessage(&msg, 0, 0, 0xFFFF);
   std::cout << "main received: " << msg.message << std::endl;
   return 0;
}

DWORD ThreadOneClass::ThreadEntry()
{
   MSG msg;
   do
   {
      GetMessage(&msg, 0, 0, 0xFFFF);
      std::cout << "Thread One Received: " << msg.message << std::endl;
      Sleep(500);
      PostThreadMessage(ThreadTwo.ThreadId, 1000, 0, 0);
   }
   while(msg.message != 1002);

   PostThreadMessage(MainThreadId, 1234, 0, 0);
   return 0;
}

DWORD ThreadTwoClass::ThreadEntry()
{
   MSG msg;
   int i = 0;
   do
   {
      Sleep(500);
      PostThreadMessage(ThreadOne.ThreadId, 1001, 0, 0);
      GetMessage(&msg, 0, 0, 0xFFFF);
      std::cout << "Thread Two Received: " << msg.message << std::endl;
   }
   while(i++ < 4);

   PostThreadMessage(ThreadOne.ThreadId, 1002, 0, 0);
   return 0;
}