访问线程内的主对话框变量 (MFC)
Access to main dialog variables within thread (MFC)
我有一个带有 MFC 的 GUI 应用程序。我正在启动线程以使用 AfxBeginThread() 处理一些数据。我在线程中访问主对话框时遇到问题:
通过这个结构,我将主对话框处理程序和指向主 dlg 对象的指针传递给线程。但是在 strcpy() 行调试器停止并显示 pDlg->0x430f0020 {CTabDlg hWnd=???}
typedef struct {
LPVOID myHandle;
LPVOID myPointer;
} sParamData;
UINT WorkerThreadProc_type2( LPVOID Param )
{
UpdInfo info;
sParamData *s;
s = (sParamData*)Param;
HWND hMainHandle = (HWND) (*s).myHandle;
CtabDlg* pDlg = (CtabDlg*)(*s).myPointer;
strcpy(apikey, pDlg->m_sVar);
...
}
我尝试了 XP 和 Windows7 OS。在 XP 中它总是崩溃,但在 7 中它可以工作。这就是我将结构传递给线程的方式:
sParamData s;
s.myHandle = (HWND)GetSafeHwnd();
s.myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
感谢您的宝贵时间!
如果您的代码与实际情况完全一样,那么您在这里声明了一个本地 sParamData 并将其地址传递给线程。这给出了一个竞争条件:s 可以在线程开始执行之前超出范围,(或到达其内容被复制的点)。
sParamData s;
s.myHandle = (HWND)GetSafeHwnd();
s.myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
最简单的解决方法可能是在堆上分配 s 并在其内容被复制后在线程中删除它。
像这样:
sParamData *s = new sParamData ;
s->myHandle = (HWND)GetSafeHwnd();
s->myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
然后,在线程内部
UINT WorkerThreadProc_type2( LPVOID Param )
{
UpdInfo info;
sParamData *s = (sParamData*)Param;
HWND hMainHandle = (HWND) s->myHandle;
CtabDlg* pDlg = (CtabDlg*)s->.myPointer;
// assuming s will no longer be used you can delete it here
delete s ;
我有一个带有 MFC 的 GUI 应用程序。我正在启动线程以使用 AfxBeginThread() 处理一些数据。我在线程中访问主对话框时遇到问题:
通过这个结构,我将主对话框处理程序和指向主 dlg 对象的指针传递给线程。但是在 strcpy() 行调试器停止并显示 pDlg->0x430f0020 {CTabDlg hWnd=???}
typedef struct {
LPVOID myHandle;
LPVOID myPointer;
} sParamData;
UINT WorkerThreadProc_type2( LPVOID Param )
{
UpdInfo info;
sParamData *s;
s = (sParamData*)Param;
HWND hMainHandle = (HWND) (*s).myHandle;
CtabDlg* pDlg = (CtabDlg*)(*s).myPointer;
strcpy(apikey, pDlg->m_sVar);
...
}
我尝试了 XP 和 Windows7 OS。在 XP 中它总是崩溃,但在 7 中它可以工作。这就是我将结构传递给线程的方式:
sParamData s;
s.myHandle = (HWND)GetSafeHwnd();
s.myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
感谢您的宝贵时间!
如果您的代码与实际情况完全一样,那么您在这里声明了一个本地 sParamData 并将其地址传递给线程。这给出了一个竞争条件:s 可以在线程开始执行之前超出范围,(或到达其内容被复制的点)。
sParamData s;
s.myHandle = (HWND)GetSafeHwnd();
s.myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
最简单的解决方法可能是在堆上分配 s 并在其内容被复制后在线程中删除它。
像这样:
sParamData *s = new sParamData ;
s->myHandle = (HWND)GetSafeHwnd();
s->myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
然后,在线程内部
UINT WorkerThreadProc_type2( LPVOID Param )
{
UpdInfo info;
sParamData *s = (sParamData*)Param;
HWND hMainHandle = (HWND) s->myHandle;
CtabDlg* pDlg = (CtabDlg*)s->.myPointer;
// assuming s will no longer be used you can delete it here
delete s ;