As I mentioned in a comment, the way I do it is to call a callback function in the function that reads data from the connection. This callback sends notification to the main window that there is updated download progress available. The main window then displays this information.
Here's a short example of the mechanism in use:
1. Code to handle button click in program's main window
void onTestBtn()
{
downloadHeader_t curDownload;
char fileName[MAX_PATH];
int i, numFiles;
numFiles = sizeof(szUrls) / sizeof(*szUrls);
ListView_DeleteAllItems(listWnd);
for (i=0; i<numFiles; i++)
addListViewItem(listWnd, szUrls[i]);
downloadList.clear();
for (i=0; i<numFiles; i++)
{
curDownload.szUrl = szUrls[i];
curDownload.callback = (voidFuncPtr)fileDownloadedCallbackFunc;
curDownload.progCallback = (voidFuncPtr)fileProgressCallbackFunc;
curDownload.saveFilePath = getFilename(curDownload.szUrl);
curDownload.lParam = (void*)i;
curDownload.contentLen = 0;
curDownload.bCancelled = false;
downloadList.push_back(curDownload);
}
for (i=0; i<numFiles; i++)
{
_beginthread(DownloadThread, NULL, (void*)&(downloadList[i]));
}
}
2. The callback function itself
void fileProgressCallbackFunc(PVOID data)
{
SendMessage(mainDlgWnd, WM_FILE_DOWNLOAD_PROGRESS_AVAILABLE, 0, (LPARAM)data);
}
3. Calling the callback (buried in DownloadThread(*void) )
if (hdr->progCallback)
hdr->progCallback(hdr);
4. Handling the message posted in the callback function - in the windowProcedure of the main window
case WM_FILE_DOWNLOAD_PROGRESS_AVAILABLE:
progHdr = (downloadHeader_t*)lParam;
if (progHdr->bComplete)
sprintf(buffer, "Complete");
else
{
if (progHdr->contentLen > 1024*1024)
sprintf(buffer, "%.2f MB", (float)progHdr->contentLen / (1024*1024) );
else if (progHdr->contentLen > 1024)
sprintf(buffer, "%.1f KB", (float)progHdr->contentLen / (1024) );
else
sprintf(buffer, "%.1f B", (float)progHdr->contentLen);
}
setListViewItemDownloaded(listWnd, (int)progHdr->lParam, buffer);
5. The definition of downloadHeader_t
typedef void (*voidFuncPtr)(void*);
struct downloadHeader_t
{
string szUrl;
voidFuncPtr callback;
voidFuncPtr progCallback;
string saveFilePath;
PVOID lParam;
SOCKET conn;
char *readBuffer, *sendBuffer, *tmpBuffer, *result;
string server, filepath, filename;
long thisReadSize, headerLen, contentLen, totalLen;
string statusTxt;
bool bCancelled;
bool bComplete;
};