关于子窗口中线程函数中如何获取父窗口的指针

CrossGrave 2016-06-01 04:55:41
在一个模态对话框中使用一个线程代码如下:
AfxBeginThread(PickDayThreadProc, this);

把当前对话框指针作为参数传入线程函数,在线程中需要获取到该模态对话框的父窗口的几个成员代码如下:
UINT __cdecl PickDayThreadProc(LPVOID lpParam)
{
CMyDialog_GN* pThisDlg = (CMyDialog_GN*)lpParam;
CString strPickUrl, strGetUrl;
int iSel = pThisDlg->m_cbx_pick.GetCurSel();
strPickUrl = pThisDlg->m_PU[iSel].m_PickDayUrl;

//获取父窗口指针
Cfeifeicms网站应用Dlg* m_pPWnd = (Cfeifeicms网站应用Dlg*)(pThisDlg->GetParent());
//获取父窗口的网站地址
strGetUrl = m_pPWnd->strUrl;
return 0;
}

但是或出错,strUrl访问内存冲突。在
	Cfeifeicms网站应用Dlg* m_pPWnd = (Cfeifeicms网站应用Dlg*)(pThisDlg->GetParent());
这句里面,断下查看,其中所有的父窗口的成员都是为NULL 获取不到值。不知道为什么。如果吧以上代码放入模态对话框中的按钮响应函数里则获取正常。

请问:我获取父窗口指针是不是有错误?导致获取父窗口成员失败。另外,子窗口中线程函数中如何获取父窗口的指针,还有其他写法吗?线程中需要用到几个父窗口成员。
...全文
419 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
rxguoblp 2016-06-20
  • 打赏
  • 举报
回复
如果非要用父窗口指针的话,可以考虑额外声明一个全局的指针,用它来指向父窗口(在父窗口的InitialDialog()函数中为其赋值,非GetParent),然后在子线程中操作该全局指针。不过,这样做确实不太安全。
coder0621 2016-06-16
  • 打赏
  • 举报
回复
引用 7 楼 oyljerry 的回复:
[quote=引用 4 楼 CrossGrave 的回复:] [quote=引用 3 楼 CrossGrave 的回复:] [quote=引用 2 楼 VisualEleven 的回复:] 不要在线程函数中直接操作UI上的东西,该发消息的方式,如果一定要在线程中操作UI,可以将HWND作为线程函数的参数传递过去,而不是传递CWnd*窗口类的指针~
我没有太理解,新手一枚,因为这个线程函数实现的功能需要调用父窗口的2个类成员,我怎么才能访问到这两个类成员获取到正确 的值呢?[/quote]可否给写一个简单的例子?[/quote] 通过PostMessage发送消息个主线程,由它来调用父窗口函数。[/quote] 楼上正解,界面的操作最好在主线程里面,工作线程不要直接操作界面上的显示
oyljerry 2016-06-14
  • 打赏
  • 举报
回复
引用 4 楼 CrossGrave 的回复:
[quote=引用 3 楼 CrossGrave 的回复:] [quote=引用 2 楼 VisualEleven 的回复:] 不要在线程函数中直接操作UI上的东西,该发消息的方式,如果一定要在线程中操作UI,可以将HWND作为线程函数的参数传递过去,而不是传递CWnd*窗口类的指针~
我没有太理解,新手一枚,因为这个线程函数实现的功能需要调用父窗口的2个类成员,我怎么才能访问到这两个类成员获取到正确 的值呢?[/quote]可否给写一个简单的例子?[/quote] 通过PostMessage发送消息个主线程,由它来调用父窗口函数。
encoderlee 2016-06-01
  • 打赏
  • 举报
回复
Cfeifeicms网站应用Dlg* m_pPWnd = (Cfeifeicms网站应用Dlg*)(pThisDlg->GetParent()); 这句有问题,pThisDlg->GetParent()得到的并非真正的“Cfeifeicms网站应用Dlg”窗口对象指针, 而是一个临时对象,因为你是在线程中调用的,这和MFC的一些实现机制有关系,所以不能进行强制转换。 另外也不建议直接在线程中访问窗口类对象指针,因为这样不是线程安全的,一般线程需要与窗口通信都是用SendMessage发消息的方式
cutmelon 2016-06-01
  • 打赏
  • 举报
回复
这个涉及到MFC的线程安全和线程状态切换问题,不太建议像楼主这样直接操作。不过作为研究的话,还是有办法的。。。

//偷懒,弄一个全局变量
AFX_MODULE_THREAD_STATE* g_pmts;
//启动线程之前要执行这句
g_pmts=AfxGetModuleThreadState();
AfxBeginThread(PickDayThreadProc, this);

UINT __cdecl PickDayThreadProc(LPVOID lpParam)
{
    CMyDialog_GN* pThisDlg = (CMyDialog_GN*)lpParam;
    CString strPickUrl, strGetUrl;
    int iSel = pThisDlg->m_cbx_pick.GetCurSel();
    strPickUrl = pThisDlg->m_PU[iSel].m_PickDayUrl;
 
	//关键的地方,切换线程状态
	AFX_MODULE_THREAD_STATE* mts=AfxGetModuleThreadState();
	AFX_MODULE_THREAD_STATE backup_mts;
	memcpy(&backup_mts,mts,sizeof(AFX_MODULE_THREAD_STATE));
	memcpy(mts,g_pmts,sizeof(AFX_MODULE_THREAD_STATE));    //获取父窗口指针

    Cfeifeicms网站应用Dlg* m_pPWnd = (Cfeifeicms网站应用Dlg*)(pThisDlg->GetParent());
    //获取父窗口的网站地址
    strGetUrl = m_pPWnd->strUrl;

	//恢复作案现场
	memcpy(mts,&backup_mts,sizeof(AFX_MODULE_THREAD_STATE));

        return 0;
}
CrossGrave 2016-06-01
  • 打赏
  • 举报
回复
引用 3 楼 CrossGrave 的回复:
[quote=引用 2 楼 VisualEleven 的回复:] 不要在线程函数中直接操作UI上的东西,该发消息的方式,如果一定要在线程中操作UI,可以将HWND作为线程函数的参数传递过去,而不是传递CWnd*窗口类的指针~
我没有太理解,新手一枚,因为这个线程函数实现的功能需要调用父窗口的2个类成员,我怎么才能访问到这两个类成员获取到正确 的值呢?[/quote]可否给写一个简单的例子?
CrossGrave 2016-06-01
  • 打赏
  • 举报
回复
引用 2 楼 VisualEleven 的回复:
不要在线程函数中直接操作UI上的东西,该发消息的方式,如果一定要在线程中操作UI,可以将HWND作为线程函数的参数传递过去,而不是传递CWnd*窗口类的指针~
我没有太理解,新手一枚,因为这个线程函数实现的功能需要调用父窗口的2个类成员,我怎么才能访问到这两个类成员获取到正确 的值呢?
Eleven 2016-06-01
  • 打赏
  • 举报
回复
不要在线程函数中直接操作UI上的东西,该发消息的方式,如果一定要在线程中操作UI,可以将HWND作为线程函数的参数传递过去,而不是传递CWnd*窗口类的指针~
Karim_Benzema 2016-06-01
  • 打赏
  • 举报
回复
CWnd *q = AfxGetApp()->m_pMainWnd;//获取主窗口指针,

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧