VC,Windows编程心得
2011-07-04 13:17
176 查看
结束了一周的工作,好好总结一下! 关于MFC的线程 由于需要做文件上传的工作,起初做的对话框很死板,只是单纯的使用主线程直接执行上传文件的操作,上传过程中界面卡在哪里,虽然是模态窗口,但让人感觉很不友好,并且界面非常不友好,所以就决定另外开一个线程来执行上传的操作,并美化界面。 在做了必要的验证之后,便开始编写线程。主要的思路是,在用户点击上传按钮以后,便开启一个工作线程UplaodTthread(working thread),并做好对话框中对应控件的控制(如隐藏、disable等操作)。然后在UplaodTthread中执行上传的操作。 原本以为这样就可以了,但突然想到用户是可以取消的,于是决定加上取消的操作。于是问题就来了,如果取消,必定是要终止上传的线程UplaodTthread,如何终止线程又成了个问题,这就涉及到线程同步的问题。在这里实在花了一点时间,网上说法一大堆,用MFC类的,用win32函数的,都试了试,也许我还理解的不透彻,所以都失败,最后就直接用了最原始的方法去同步线程——直接使用公共变量来实现线程之间的同步。 在UplaodTthread中使用设置一个标志bool值,用户在主线程发出了终止上传的消息,开启另一个线程UploadAbortedThread线程,在次线程中改变这个值,就可以让UploadThread的上传过程终止,也就是让UploadThread这个working thread直接返回,上传线程终止。而此时,并不能直接关闭对话框,因为UploadThread是需要用到对话框里面的资源的,所以在UploadAbortedThread中还要判断另一个标志bool值,判断UploadThread是否已经返回,UploadThread在return之前改变这个标志bool值(严格的说,这是不严谨的,因为执行这两个指令是可能被打断的,但考虑到return指令不涉及任何其他资源的引用,而且工作线程是全局函数,所以我个人觉得是可以忽略),UploadAbortedThread得知之后,便发送消息,对话框拦截消息,对话框关闭。 这里主要技术点是在创建MFC线程和线程之间的通信,以及工作线程和主线程之间的通信。 工作线程之间的通信:如前所述,我采用的方法是让这两个线程使用同一个对话框里面的同一个变量(比较原始,也许有更好的方法)。 工作线程与主线程之间的通信:AfxBeginThread(FileUploadAbortedThread,this)。由于是主线程(对话框)开启的线程,所以可以把对话框的指针(this)传递给工作线程,工作线程中队指针进行转换,于是就可以获得对话框对象中的所有公有成员函数以及变量。 如何使工作线程的行为影响到主线程:使用cwnd::PostMessage,在本例中,因为工作线程已经获得了对话框的指针,于是就可以使用pCDialog->PostMessage(WM_USER_DEFINE_MSG),对话框自己拦截捕获这个消息,处理消息。在本例中,对话框的关闭,都是使用这种方法,工作线程发送消息,主线程(对话框)截获,做收尾工作,然后关闭对话框。 当然,这里也涉及到自定义消息和在MFC中消息传递路径,把自定义消息放到消息队列中的宏是: ON_MESSAGE(WM_USER_DEFINE_MSG, pFunc) WM_USER_DEFINE_MSG 一般的定义是 #define WM_UPLOA_FILE_OK (WM_USER + 101) 消息函数的声明: afx_msg LRESULT OnUploadAborted(WPARAM wParam, LPARAM lParam); 至于MFC消息的传递路径,这就和MFC框架有关了,由于在本例中是由对话框对象发送的消息,所以,此对话框类只要有对自定义消息的拦截(也就是在此对话框类中插入了消息映射宏),就会首先截获消息,然后处理消息。 关于CFileDialog类 文件上传,必然要支持多选,即一次上传多个文件,除了在构造函数的第四个参数中指定OFN_ALLOWMULTISELECT外,所选文件的名称也是需要特殊的方法保存的,如下代码CString csFileNameBuffer;cf.m_ofn.lpstrFile = csFileNameBuffer.GetBuffer(NMAXFILE) ;cf.m_ofn.nMaxFile = NMAXFILE;其中cf就是CFileDialog的一个对象,它使用CString的一个对象来保存所选文件的所有路径,这里就体现了MFC类提供的功能,下面代码是依次获得所有文件名:POSITION pos = cf.GetStartPosition();for (int i = 0;pos != NULL;++i){ fileName = cf.GetNextPathName(pos);}csFileNameBuffer.ReleaseBuffer();当然,在使用之后需要释放CString 对象所申请的空间,说明,CString对象可以动态申请空间(可是为什么不能自己在析构的时候去释放申请的空间呢?困惑~~~)
相关文章推荐
- 并行编程之跨平台使用SSE、AVX指令集心得——以单精度浮点数组求和为例(支持vc、gcc,兼容Windows、Linux、Mac)
- 并行编程之跨平台使用SSE、AVX指令集心得——以单精度浮点数组求和为例(支持vc、gcc,兼容Windows、Linux、Mac)
- 并行编程之跨平台使用SSE、AVX指令集心得——以单精度浮点数组求和为例(支持vc、gcc,兼容Windows、Linux、Mac)
- Windows下的VC++动态链接库编程
- VC++ 外壳扩展编程之windows右键菜单
- (转)VC++ 外壳扩展编程之windows右键菜单
- 实验一:VC编程环境灵活应用—>实验心得--信管1133-09
- VC++编程之第一课笔记――Windows程序内部运行原理
- VC++ 外壳扩展编程之windows右键菜单
- windows环境下unicode编程总结c++/vc
- VC Windows shell扩展编程(为系统右键菜单添加二级菜单傻瓜教程)
- 在VC中使用Windows管道技术编程
- windows编程经典书籍+VC++学习路线资料
- 关于Windows编程的一些心得
- VC++ Windows平台字符透明编程大总结(转)
- windows vc socket编程
- 在VC中使用Windows管道技术编程
- VC:windows自带的防火墙的相关编程
- 【VC编程技巧】文件☞2.6Windows上多级目录的创建和删除
- Windows下Openssl安装以及编程(VC.net环境)