I have strange problem and I dont know where it does come from.
First I list here the struct I have problem :
struct _THREADPARMS{ //global definition in one of my header file
HWND h_wnd;
BOOL bContinueAccept;
BOOL bConnected;
CProgressCtrl* pProgress;
CDialog* pDialog;
};
then I declare global variables of the type at a begining in one of my *.cpp file
_THREADPARMS THREADPRMS,*PTHREADPRMS;
As I understand these variables are allocated at compilation time, one without pointing to specific lacation.
Also I use PTHREADPRMS in another file and there the problem begins.
First I declare in the file "a referencial declaration":
extern _THREADPARMS* PTHREADPRMS;
First I will explain the logic of the program. When I choose from my app menu option "connect" it brins me a standard dialog with one button and one progress bar.
When I click button I initializes CProgressCtrl* pProgress,CDialog* pDialog with current values and it creates a thread for loop witch checks whether my app accepted incoming connection and it increases one step progress bar each loop cycle.
But if I decide to quit from the dialog without click the connect button(it goes stright to excute CConnectDialog::OnCancel()) debunger catches the error Access violation writing location 0x00000010
// ConnectDialog.cpp : implementation file
//
#include "stdafx.h"
#include "chat_client.h"
#include "ConnectDialog.h"
#include "stddefn.h"
#include "afxmt.h"
CCriticalSection g_CriticalSection[5];
extern _THREADPARMS* PTHREADPRMS,THREADPRMS;
BOOL isProcess();
BOOL isDialog();
// CConnectDialog dialog
IMPLEMENT_DYNAMIC(CConnectDialog, CDialog)
CConnectDialog::CConnectDialog(CWnd* pParent)
: CDialog(CConnectDialog::IDD, pParent)
{
}
CConnectDialog::~CConnectDialog()
{
}
void CConnectDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS1, m_ctlProgressBar);
}
BEGIN_MESSAGE_MAP(CConnectDialog, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, &CConnectDialog::OnBnClickedButton1)
END_MESSAGE_MAP()
// CConnectDialog message handlers
void CConnectDialog::OnBnClickedButton1()
{
//create secondary thread for progressbar and checks for connection
AfxGetMainWnd()->SendMessage(WM_ACCEPT_CONNECTIONS);
(CButton*)GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
PTHREADPRMS->pProgress=&m_ctlProgressBar;
PTHREADPRMS->pDialog=this;
m_pThread=AfxBeginThread(ThreadConnect,NULL);
}
UINT CConnectDialog::ThreadConnect(LPVOID lParam)
{
if (isProcess())
{
PTHREADPRMS->pProgress->SetStep(2);
PTHREADPRMS->pProgress->SetRange(0,100);
while (isProcess()){
if (PTHREADPRMS->bConnected)
break;
g_CriticalSection[T_PROGRESS_BAR].Lock();
PTHREADPRMS->pProgress->StepIt();
g_CriticalSection[T_PROGRESS_BAR].Unlock();
::Sleep(500);
}
if (PTHREADPRMS->bConnected&&isDialog())
{
g_CriticalSection[T_PROGRESS_BAR].Lock();
PTHREADPRMS->pProgress->SetPos(100);
g_CriticalSection[T_PROGRESS_BAR].Unlock();
g_CriticalSection[T_DIALOG].Lock();
((CConnectDialog*)(PTHREADPRMS->pDialog))->OnOK();
g_CriticalSection[T_DIALOG].Unlock();
return 0;
}
}
return 0;
}
void CConnectDialog::OnOK()
{
g_CriticalSection[T_DIALOG].Lock();
PTHREADPRMS->pDialog=NULL;
g_CriticalSection[T_DIALOG].Unlock();
g_CriticalSection[T_PROGRESS_BAR].Lock();
PTHREADPRMS->pProgress=NULL;
g_CriticalSection[T_PROGRESS_BAR].Unlock();
SendMessage(WM_ABORT_ACCEPT_CONNECTIONS);
WaitForSingleObject(m_pThread->m_hThread,INFINITE);
CDialog::OnOK();
}
void CConnectDialog::OnCancel()
{
m_ctlProgressBar.SetPos(0);
g_CriticalSection[T_DIALOG].Lock();
PTHREADPRMS->pDialog=NULL; //Access violation writing location 0x00000010
g_CriticalSection[T_DIALOG].Unlock();
g_CriticalSection[T_PROGRESS_BAR].Lock();
PTHREADPRMS->pProgress=NULL;
g_CriticalSection[T_PROGRESS_BAR].Unlock();
::SendMessage(AfxGetMainWnd()->m_hWnd,WM_ABORT_ACCEPT_CONNECTIONS,0,0);
WaitForSingleObject(m_pThread->m_hThread,INFINITE);
CDialog::OnCancel();
}
BOOL isProcess()
{
g_CriticalSection[T_PROGRESS_BAR].Lock();
if (PTHREADPRMS->pProgress!=NULL)
{
g_CriticalSection[T_PROGRESS_BAR].Unlock();
return TRUE;
}
return FALSE;
}
BOOL isDialog()
{
g_CriticalSection[T_DIALOG].Lock();
if (PTHREADPRMS->pDialog!=NULL)
{
g_CriticalSection[T_DIALOG].Unlock();
return TRUE;
}
return FALSE;
}
I do not understand the variable it is created on a stack it occurs at location 0x00000010. So I have no clue whats happenning, tried to secure the variable with critical section but I seems the problem is something deifferent.