All the code for the background thread is contained in MtBackgroundThread.cpp.
unsigned long _stdcall CMtBackgroundApp_WorkerThread(void* pvData) {
// Data items
typedef struct tagDataItem {
const char* name;
double baseValue, value;
} DataItem;
static DataItem items[] = {
{ "one", 1.0 },
{ "two", 2.0 },
{ "three", 3.0 },
{ "four", 4.0 },
{ 0 }
};
CMtBackgroundApp* addin = (CMtBackgroundApp*)pvData;
int whichItem = -1;
// Get a list of all local hard drives
std::vector<CString> vecDrives;
GetDrives(vecDrives);
// Loop until killed
while (TRUE) {
::Sleep(addin->GetTickPeriod());
// Update disk space for each local hard drive
for (int i = 0; i < vecDrives.size(); i++)
addin->PostMessage(new CMtBackgroundMsg(vecDrives[i], GetDiskSpace(vecDrives[i])));
// Update memory usage
addin->PostMessage(new CMtBackgroundMsg("mem", GetMemUse()));
// Select the next item
if (items[++whichItem].name == 0)
whichItem = 0;
// Change item value
DataItem* item = items + whichItem;
item->value = item->baseValue + ((double)rand() / (double)RAND_MAX);
// Tell the main thread about the changed item
addin->PostMessage(new CMtBackgroundMsg(item->name, item->value));
}
// Never reached
return 0;
}
The most important line in the initialisation section is:
CMtBackgroundApp* addin = (CMtBackgroundApp*)pvData;
The thread keeps a pointer to the application class, which it will use to post messages to it.
In the main loop, the thread sleeps for TickPeriod milliseconds, and then wakes up and generates the three types of data.
In each case the thread posts the data to the main thread wrapped up in a CMtBackgroundMsg object, e.g.:
addin->PostMessage(new CMtBackgroundMsg("mem", GetMemUse()));
Note that the message is created in the background thread, but will be consumed and destroyed in the main thread.
The background thread loops until the main thread kills it with CloseHandle(m_thread).