关于启动线程时传输窗口对象(指针?句柄?)的问题。

iq199 2003-09-13 12:28:33
关于启动线程时传输窗口对象(指针?句柄?)的问题:

在选择菜单中的开始线程后:
void CMainFrame::OnMenu_Start()
{
...
AfxBeginThread(MyThread, this);
...
}

线程函数如下:
UINT MyThread(LPVOID pParam)
{
CMainFrame* pMainFrm = (CMainFrame *)pParam;
...
}

问题一:
这样的代码是不是有问题?
(文档中说线程间不能直接传输MFC对象的指针,应该通过传输句柄实现)

问题二:
这样使用开始好像没有问题,直接通过pMainFrm访问窗口中的view都正常。
但发现访问状态条时:
pMainFrm->m_wndStatusBar.SetPaneText(2, "test);
出现Debug Assertion Failed!(在窗口线程中没有问题)
位置是wincore.cpp中的
ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
为什么访问View能正常,但访问状态条时不可以呢?

问题三:
如果通过传输句柄实现,怎样做呢?
我用下面的代码执行时有问题:
void CMainFrame::OnMenu_Start()
{
...
HWND hWnd = GetSafeHwnd();
AfxBeginThread(MyThread, hWnd);
...
}

UINT MyThread(LPVOID pParam)
{
CMainFrame* pMainFrm = (CMainFrame *)(CWnd::FromHandle((HWND)pParam));
...
}
执行时通过线程中得到pMainFrm,访问其成员时不正常。

...全文
70 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hewwatt 2003-09-13
  • 打赏
  • 举报
回复
到底是让工作线程等待界面刷新完成后再处理后续工作好呢,还是让界面反应稍微
落后一点好呢?(况且你还不一定看得出来) 这不是实时系统吧。
iq199 2003-09-13
  • 打赏
  • 举报
回复
如果我要在工作线程改写界面只能用postmessage吗?
我的工作线程要向界面中的一个CListView中插入大量数据(短时间),用PostMessage方式是不是会很影响效率?

有没有其它好的实现方式?
Hewwatt 2003-09-13
  • 打赏
  • 举报
回复
大致原因解释如下:
1. MFC的大多数类不是线程安全的,CWnd及其消息路由是其中之最
2. MFC界面类的大多数方法,最后都是通过SendMessage实现的,而消息处理的
过程中会引发其他消息的发送及处理。如果消息处理函数本身不是线程安全的
你从工作线程中调用这些方法迟早会同你界面线程的用户消息响应发生冲突
3. Cxxxx::FromHandle会根据调用者所在线程查表,如果查不到用户创建的Cxxxx
对应对象,它会创建一个临时对象出来。由于你在工作线程中调用该方法,当然
不可能查到界面主线程中你所建立起来的那个对象了。这时MFC会你创建一个临时
对象并返回给你,你根本不可能期望它的成员变量会是有意义的。 所以要用
也只能用CWnd::FromHandle,因为它只包含一个m_hWnd成员。 不过,要记住
跨线程直接或间接地调用::SendMessage,通常都是行为不可预测的。
Hewwatt 2003-09-13
  • 打赏
  • 举报
回复
在工作线程中直接访问界面元素通常都不是好的做法,传递MFC的CWnd对象
也同样,迟早会遇到问题。其实通过PostMessage(而不是SendMessage)
可以帮你解决90%以上的需求。

15,471

社区成员

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

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