lyar1031
June 14th, 2005, 02:09 PM
Take a look at this simple Thread App that I got from this website.
It starts a thread when a start button is pressed and the thread is stopped when the stop button is pressed.
Problem: After executing the application. When I try and run the application AGAIN through the degugger you get an error ".../debug/thread.exe/ cannot delete, check to see if the application has write protection or if another process is using this application.
As a result I need to reboot windows everytime I want to run the application. The problem seems to be when I create the events
Here is the Code below:
Thanks
#include "stdafx.h"
#include "Thread.h"
#include "ThreadDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);
//}}AFX_VIRTUAL
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CThreadDlg::CThreadDlg(CWnd* pParent /*=NULL*/)
: CDialog(CThreadDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CThreadDlg)
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_ThreadCreated = false;
m_hSemForStopThread = CreateEvent(0, TRUE, FALSE, 0);
m_hSemForWaitThread = CreateEvent(0, TRUE, FALSE, 0);
}
CThreadDlg::~CThreadDlg()
{
// Trigger thread to stop
SetEvent(m_hSemForStopThread);
// Wait until thread finished
WaitForSingleObject(m_hSemForWaitThread, INFINITE);
// Reset event
ResetEvent(m_hSemForWaitThread);
// Close handles
CloseHandle(m_hSemForStopThread);
CloseHandle(m_hSemForWaitThread);
}
void CThreadDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CThreadDlg)
DDX_Control(pDX, IDC_MESSAGE, m_Message);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CThreadDlg, CDialog)
//{{AFX_MSG_MAP(CThreadDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CREATETHREAD, OnCreateThread)
ON_BN_CLICKED(IDC_STOPTHREAD, OnStopThread)
ON_MESSAGE(WM_UPDATE_TEXT, OnMessageText)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CThreadDlg::OnInitDialog()
{
CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
m_Message.SetWindowText("Thread stopped!");
return TRUE;
}
void CThreadDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CThreadDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CThreadDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CThreadDlg::OnCreateThread()
{
if(!m_ThreadCreated)
{
// Create thread
AfxBeginThread(ThreadFunction, this);
m_ThreadCreated = true;
m_Message.SetWindowText("Thread created!");
}
}
void CThreadDlg::OnStopThread()
{
// Trigger thread to stop
SetEvent(m_hSemForStopThread);
// Wait until thread finished
WaitForSingleObject(m_hSemForWaitThread, INFINITE);
// Reset event
ResetEvent(m_hSemForWaitThread);
m_ThreadCreated = false;
m_Message.SetWindowText("Thread stopped!");
}
UINT CThreadDlg::ThreadFunction(LPVOID pvParam)
{
unsigned long count = 0;
CThreadDlg *pParent = static_cast<CThreadDlg *>(pvParam);
while(true)
{
// Check semaphore for stop thread
if(WaitForSingleObject(pParent->m_hSemForStopThread, 0) == WAIT_OBJECT_0)
{
// Reset event
ResetEvent(pParent->m_hSemForStopThread);
// Set event
SetEvent(pParent->m_hSemForWaitThread);
AfxEndThread(0,TRUE);
return 0;
}
// Send message
CString *pMessage = new CString;
pMessage->Format("Thread is running! Message number %d", ++count);
pParent->PostMessage(WM_UPDATE_TEXT, 0, reinterpret_cast<LPARAM>(pMessage));
Sleep(500);
}
}
LRESULT CThreadDlg::OnMessageText(WPARAM wParam, LPARAM lParam)
{
m_Message.SetWindowText(*reinterpret_cast<CString *>(lParam));
delete reinterpret_cast<CString *>(lParam);
return 0;
}
It starts a thread when a start button is pressed and the thread is stopped when the stop button is pressed.
Problem: After executing the application. When I try and run the application AGAIN through the degugger you get an error ".../debug/thread.exe/ cannot delete, check to see if the application has write protection or if another process is using this application.
As a result I need to reboot windows everytime I want to run the application. The problem seems to be when I create the events
Here is the Code below:
Thanks
#include "stdafx.h"
#include "Thread.h"
#include "ThreadDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);
//}}AFX_VIRTUAL
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CThreadDlg::CThreadDlg(CWnd* pParent /*=NULL*/)
: CDialog(CThreadDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CThreadDlg)
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_ThreadCreated = false;
m_hSemForStopThread = CreateEvent(0, TRUE, FALSE, 0);
m_hSemForWaitThread = CreateEvent(0, TRUE, FALSE, 0);
}
CThreadDlg::~CThreadDlg()
{
// Trigger thread to stop
SetEvent(m_hSemForStopThread);
// Wait until thread finished
WaitForSingleObject(m_hSemForWaitThread, INFINITE);
// Reset event
ResetEvent(m_hSemForWaitThread);
// Close handles
CloseHandle(m_hSemForStopThread);
CloseHandle(m_hSemForWaitThread);
}
void CThreadDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CThreadDlg)
DDX_Control(pDX, IDC_MESSAGE, m_Message);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CThreadDlg, CDialog)
//{{AFX_MSG_MAP(CThreadDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CREATETHREAD, OnCreateThread)
ON_BN_CLICKED(IDC_STOPTHREAD, OnStopThread)
ON_MESSAGE(WM_UPDATE_TEXT, OnMessageText)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CThreadDlg::OnInitDialog()
{
CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
m_Message.SetWindowText("Thread stopped!");
return TRUE;
}
void CThreadDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CThreadDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CThreadDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CThreadDlg::OnCreateThread()
{
if(!m_ThreadCreated)
{
// Create thread
AfxBeginThread(ThreadFunction, this);
m_ThreadCreated = true;
m_Message.SetWindowText("Thread created!");
}
}
void CThreadDlg::OnStopThread()
{
// Trigger thread to stop
SetEvent(m_hSemForStopThread);
// Wait until thread finished
WaitForSingleObject(m_hSemForWaitThread, INFINITE);
// Reset event
ResetEvent(m_hSemForWaitThread);
m_ThreadCreated = false;
m_Message.SetWindowText("Thread stopped!");
}
UINT CThreadDlg::ThreadFunction(LPVOID pvParam)
{
unsigned long count = 0;
CThreadDlg *pParent = static_cast<CThreadDlg *>(pvParam);
while(true)
{
// Check semaphore for stop thread
if(WaitForSingleObject(pParent->m_hSemForStopThread, 0) == WAIT_OBJECT_0)
{
// Reset event
ResetEvent(pParent->m_hSemForStopThread);
// Set event
SetEvent(pParent->m_hSemForWaitThread);
AfxEndThread(0,TRUE);
return 0;
}
// Send message
CString *pMessage = new CString;
pMessage->Format("Thread is running! Message number %d", ++count);
pParent->PostMessage(WM_UPDATE_TEXT, 0, reinterpret_cast<LPARAM>(pMessage));
Sleep(500);
}
}
LRESULT CThreadDlg::OnMessageText(WPARAM wParam, LPARAM lParam)
{
m_Message.SetWindowText(*reinterpret_cast<CString *>(lParam));
delete reinterpret_cast<CString *>(lParam);
return 0;
}