`
ladymaidu
  • 浏览: 678470 次
文章分类
社区版块
存档分类
最新评论

略谈如何从工作线程中弹出对话框

 
阅读更多

朱金灿

工作线程,在一些技术文章被称为辅助线程,是相对于主线程而言的。在工作线程中使用界面需要一些技巧。我就曾在工程线程中弹出对话框中遇到过莫名奇妙的错误。下面就我的经验谈谈如何从工作线程中弹出对话框(暂时只讲方法,原理还没彻底弄清楚)。

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

实际上在工作线程中直接弹出模式对话框中在debug模式下有时出错(这里的有时的意思是必然会出错,但是不是每次都出错),弹出模式对话框的代码如下:

  1. DWORDWINAPIRecvThread(LPVOIDlpParam)//工作线程函数
  2. {
  3. CAIDlgProductNamedlg;
  4. if(dlg.DoModal()==IDOK)
  5. {
  6. ……
  7. }
  8. }

错误截图:

如果跟踪DoModal函数,我们进入MFC源码找到出错的地方:

  1. #ifdef_DEBUG
  2. voidCWnd::AssertValid()const
  3. {
  4. if(m_hWnd==NULL)
  5. return;//null(unattached)windowsarevalid
  6. //checkforspecialwnd???values
  7. ASSERT(HWND_TOP==NULL);//sameasdesktop
  8. if(m_hWnd==HWND_BOTTOM)
  9. ASSERT(this==&CWnd::wndBottom);
  10. elseif(m_hWnd==HWND_TOPMOST)
  11. ASSERT(this==&CWnd::wndTopMost);
  12. elseif(m_hWnd==HWND_NOTOPMOST)
  13. ASSERT(this==&CWnd::wndNoTopMost);
  14. else
  15. {
  16. //shouldbeanormalwindow
  17. ASSERT(::IsWindow(m_hWnd));
  18. //shouldalsobeinthepermanentortemporaryhandlemap
  19. CHandleMap*pMap=afxMapHWND();
  20. ASSERT(pMap!=NULL);
  21. CObject*p;
  22. //在下面一句出错
  23. ASSERT((p=pMap->LookupPermanent(m_hWnd))!=NULL||
  24. (p=pMap->LookupTemporary(m_hWnd))!=NULL);
  25. ASSERT((CWnd*)p==this);//mustbeus
  26. //Note:ifeitheroftheaboveassertsfireandyouare
  27. //writingamultithreadedapplication,itislikelythat
  28. //youhavepassedaC++objectfromonethreadtoanother
  29. //andhaveusedthatobjectinawaythatwasnotintended.
  30. //(onlysimpleinlinewrapperfunctionsshouldbeused)
  31. //
  32. //Ingeneral,CWndobjectsshouldbepassedbyHWNDfrom
  33. //onethreadtoanother.Thereceivingthreadcanwrap
  34. //theHWNDwithaCWndobjectbyusingCWnd::FromHandle.
  35. //
  36. //ItisdangeroustopassC++objectsfromonethreadto
  37. //another,unlesstheobjectsaredesignedtobeusedin
  38. //suchamanner.
  39. }
  40. }

实际上当时给我启发的是上面那段Note。我用我浅薄的英文功底翻译一下大意就是:就是上面的asserts发生了同时你正在写的是一个多线程程序,那么asserts发生的原因很可能是你将一个C++对象从一个线程传递给另一个线程同时你无意中使用了那个C++对象(only simple inline wrapper functions should be used(抱歉,这一句不会翻译)),实际上线程之间传递CWnd对象应该传递句柄(HWND)。接收线程应该通过CWnd::FromHandle函数通过传递过来的句柄获取CWnd对象(这里准确的来说应该是CWnd对象的指针)。

线程之间传递C++对象是危险的,除非那个对象被设计为以那种方式使用。

由上面我想到一种在工作线程中弹出的对话框的办法:

1. 转递视图类句柄给线程函数:

  1. HWNDHView;
  2. …… // 获取视图类句柄

  3. CreateThread(NULL,0,RecvThread,HView
  4. ,0,&dwThreadId);

2. 在线程函数中通过句柄获取视图类指针,获取数据给视图类发送自定义消息:

  1. DWORDWINAPIRecvThread(LPVOIDlpParam)
  2. {
  3. HWNDHView=(HWND)lpParam;
  4. CWnd*pMyView=CWnd::FromHandle(HView);
  5. ……
  6. pMyView->SendMessage(WM_TASKDLG_MESSAGE,(WPARAM)(&str));
  7. …….
  8. }

3. 在视图类自定义一个消息函数OnTaskDlgMessage专门处理WM_TASKDLG_MESSAGE消息用于创建对话框:

  1. LRESULTCInteAView::OnTaskDlgMessage(WPARAMwParam,LPARAMlParam)
  2. {
  3. CAIDlgProductNamedlg;
  4. if(dlg.DoModal()==IDOK)
  5. {
  6. ……
  7. }
  8. return0;
  9. }

当然上面将视图类换为框架类也是可以的。上面就我的经验谈了一种从工作线程中弹出对话框的办法,不当之处还请大家指点。

分享到:
评论

相关推荐

    C#多线程之如何弹出一个模式窗口来显示进度条

    C#多线程之如何弹出一个模式窗口来显示进度条 学习版

    c# Winform 弹出式等待窗口,多线程

    网上有好多使用多线程弹出式等待窗口作为程序中较长时间后台运行提示的,但是做的都不完善,尤其是用 waitThread.Abort() 杀死线程时容易产生异常,进而出错。本程序是比较完善的改进,利用多线程弹出等待窗口,并...

    多线程解决mfc对话框未响应、卡死问题

    多线程解决mfc对话框未响应、卡死问题

    用独立线程解决弹出模态对话框后执行自定义函数问题-vcmfc-提供最全面实用的j(精编版).docx

    用独立线程解决弹出模态对话框后执行自定义函数问题-vcmfc-提供最全面实用的j(精编版).docx

    Android版本更新,多线程下载、断点续传(原创)

    Android版本更新实用的Demo,主要用到了HttpURLConnection、Xml PULL解析(其中也提供了JSON格式的解析)、丰富的辅助类、多线程下载与断点续传,界面虽然丑点但比较实用。如果你下载了该资源无法运行的话,别急着...

    易语言调整通用对话框窗口默认大小

    易语言调整通用对话框窗口默认大小源码,调整通用对话框窗口默认大小,线程事件,FindWindow,设置窗口位置_

    mfc 对话框 创建进度条 显示当前进度

    mfc 对话框 创建计算线程 使用进度条显示当前进度

    C# 多线程 模态 MessageBox

    在多线程中,有时候使用MessageBox.Show方法弹出对话框,弹出的Messagebox不是模态的,不能满足我的要求.所以有了这段代码.

    等待对话框(模态)

    在写程序时,经常会碰到处理大数据量的任务,例如读取尺寸...线程在处理的过程中,希望主界面弹出等待提示框,提示使用者软件正在处理数据,请等待;并且等待对话框最好是模态的,这样使用者就无法进行其他任何操作了。

    C# Winform 弹出进度条视窗 (ProgressBar) (NEW)

    利用BackGroundWorker实现在线程中处理进度,并弹出视窗显示当前进度 与上个没差异 补上当前进度的text而已

    java 多线程聊天系统

    1、点击”连接“弹出”连接服务器“对话框,分别填写服务器的地址(IP)、通信端口、用户登录的名字(用户ID不能为空); 2、点击”发送信息“或按”Ctrl+Enter“发送信息(发送的信息内容不能为空); 3、点击”...

    Android常用对话框使用大全

    1.当弹出对话框是会结束UI线程(即主线程); 2.当前的Activity会失去焦点; 3.消息对话框、确认对话框、列表对话框、单选和多选对话框、自定义对话框 二、对话框的组成(一般有四部分组成) 1.图标 2.标题 3.内容 4...

    vb6 dll 注入

    ATTACH”,说明.dll已经被注入并且被调用了,随后再弹出一个对话框,显示的是当前进程加载的所有模块的文件名,当然其中也包含我们的.dll文件,之后弹出对话框提示“DLL_THREAD_DEATH”,线程结束,当记事本进程结束...

    CESock类 多线程实现简单易用的套接字

    调试时保留 #define SHOW_ERROR_MSGBOX,如果运行时出错将弹出对话框. 注释掉此行时如果出错将不做处理. 建议发布软件时(即Release版)注释此行代码. 4. 建议不要在函数内部定义CESock类型变量. 5. 建议此模块...

    线程MessageBox

    线程使用过程中。经常会弹出一些对话框。使用 MessageBox.Show并不是模态的。这个可以

    PYQT5开启多个线程和窗口,多线程与多窗口的交互实例

    每点击一次按钮,弹出一个对话框(子窗口),同时开启一个子线程来执行任务并更新对话框内容,关闭对话框则关闭对应子线程 1. 建立一个简单的主界面和一个自定义对话框 from PyQt5 import QtCore, QtGui, QtWidgets ...

    科来MAC地址扫描器专业版

    果你要扫描某个网段,只需要在“选择网段”右边的下拉选框中选择...同时,科来物理地址扫描器还允许用户调整扫描的并发线程,如需更改,请单击“设置”按钮,在弹出对话框中调整线程的数量即可,默认使用的线程数是100

    用VS2008 ATL开发可以显示Gif的ActiveX控件源码.rar

     为GifAnimate项目添加类-选择ATL控件,点击添加,弹出对话框。  1.本文只是举例说明开发过程,抛砖而已。  2.样例只是框架,不能直接使用,所有代码没有经过测试  3.样例接收器GifSink和属性页卡片没有完成,懒...

    在Win32程序中应用OpenGL进行多窗口显示

    运行时点击渲染,弹出对话框后在四个text控件中分别显示四幅OpenGL渲染得到的图像。用到了多线程

Global site tag (gtag.js) - Google Analytics