|
// BackgroundTaskDialog.cpp : implementation file
//
#include "stdafx.h"
#include "BackgroundTaskDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
static UINT RunBackgroundTaskProc(LPVOID pParam);
/////////////////////////////////////////////////////////////////////////////
// CBackgroundTaskDialog dialog
CBackgroundTaskDialog::CBackgroundTaskDialog(UINT nIDD, CWnd* pParent /*=NULL*/)
: CDialog(nIDD, pParent)
{
//{{AFX_DATA_INIT(CBackgroundTaskDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
hKillBackgroundThreadEvent = hDoneBackgroundThreadEvent = NULL;
lpBackgroundThread = NULL;
return;
}
CBackgroundTaskDialog::~CBackgroundTaskDialog()
{
StopBackgroundTask();
return;
}
void CBackgroundTaskDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBackgroundTaskDialog)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CBackgroundTaskDialog, CDialog)
//{{AFX_MSG_MAP(CBackgroundTaskDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
int CBackgroundTaskDialog::StartBackgroundTask()
{
if (lpBackgroundThread != NULL) {
if (IsBackgroundTaskRunning() != FALSE)
return -1;
//If the thread has ended call StopBackgroundTask in order
//to cleanup some stuff
StopBackgroundTask();
}
//create kill thread event
hKillBackgroundThreadEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if (hKillBackgroundThreadEvent == NULL)
return -2;
//create work-done thread event
hDoneBackgroundThreadEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if (hDoneBackgroundThreadEvent == NULL) {
::CloseHandle(hKillBackgroundThreadEvent);
hKillBackgroundThreadEvent = NULL;
return -3;
}
//create thread itself
lpBackgroundThread = AfxBeginThread(RunBackgroundTaskProc, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if (lpBackgroundThread == NULL) {
::CloseHandle(hDoneBackgroundThreadEvent);
hDoneBackgroundThreadEvent = NULL;
::CloseHandle(hKillBackgroundThreadEvent);
hKillBackgroundThreadEvent = NULL;
return -4;
}
lpBackgroundThread->m_bAutoDelete = FALSE;
//resume thread
::ResumeThread(lpBackgroundThread->m_hThread);
return 1;
}
int CBackgroundTaskDialog::StopBackgroundTask(int nTimeOut)
{
MSG msg;
DWORD dwExitCode;
int tim, nTimeCounter;
if (lpBackgroundThread == NULL)
return -1;
//I dont know why sometimes finished threads don't get signalled
if ((::WaitForSingleObject(hDoneBackgroundThreadEvent, 0) != WAIT_OBJECT_0) &&
(::GetExitCodeThread(lpBackgroundThread->m_hThread, &dwExitCode) && dwExitCode==STILL_ACTIVE)) {
//thread is still active...
//send kill event
::SetEvent(hKillBackgroundThreadEvent);
//wait for thread completion
for (nTimeCounter=nTimeOut;;) {
if (nTimeOut > 0) {
if ((tim = nTimeCounter) > 100)
tim = 100;
}
else
tim = 0;
if (::WaitForSingleObject(hDoneBackgroundThreadEvent, tim) == WAIT_OBJECT_0)
break;
if (::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE) != 0) {
if (AfxGetThread()->PumpMessage() == FALSE) {
::TerminateThread(lpBackgroundThread->m_hThread, 0);
::PostQuitMessage(msg.wParam);
break;
}
}
if (::GetExitCodeThread(lpBackgroundThread->m_hThread, &dwExitCode) && dwExitCode!=STILL_ACTIVE)
break;
if (nTimeOut > 0) {
if ((nTimeCounter -= tim) == 0) {
::TerminateThread(lpBackgroundThread->m_hThread, 0);
break;
}
}
}
}
//cleanup
if (lpBackgroundThread != NULL) {
delete lpBackgroundThread;
lpBackgroundThread = NULL;
}
if (hDoneBackgroundThreadEvent != NULL) {
::CloseHandle(hDoneBackgroundThreadEvent);
hDoneBackgroundThreadEvent = NULL;
}
if (hKillBackgroundThreadEvent != NULL) {
::CloseHandle(hKillBackgroundThreadEvent);
hKillBackgroundThreadEvent = NULL;
}
return 1;
}
BOOL CBackgroundTaskDialog::CheckForBackgroundTaskAbort()
{
if (lpBackgroundThread == NULL)
return TRUE;
if (::WaitForSingleObject(hKillBackgroundThreadEvent, 0) == WAIT_OBJECT_0)
return TRUE;
return FALSE;
}
BOOL CBackgroundTaskDialog::IsBackgroundTaskRunning()
{
DWORD dwExitCode;
if (lpBackgroundThread == NULL)
return FALSE;
if (::WaitForSingleObject(hDoneBackgroundThreadEvent, 0) == WAIT_OBJECT_0)
return FALSE;
if (::GetExitCodeThread(lpBackgroundThread->m_hThread, &dwExitCode) && dwExitCode!=STILL_ACTIVE)
return FALSE;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// OVERRIDABLES
void CBackgroundTaskDialog::RunBackgroundTask()
{
return;
}
/////////////////////////////////////////////////////////////////////////////
// INTERNAL FUNCTIONS
static UINT RunBackgroundTaskProc(LPVOID pParam)
{
CBackgroundTaskDialog *bt_dlg;
bt_dlg = (CBackgroundTaskDialog*)pParam;
bt_dlg->RunBackgroundTask();
::SetEvent(bt_dlg->hDoneBackgroundThreadEvent);
return 1;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
My name is Mauro Leggieri. I am 30 year-old, married and have a child.
I am a system engineer (UTN university) and am being programming for more than 20 years from the C64 to the PC and some microcontrollers.
Mostly of my time, I program games for Windows.
Soon, my site http://www.mauroleggieri.com.ar