1. 创建一个SDI应用程序SimSence。
2. 在CSimSenceView创建线程,调用第三方动态库,进行周期性数据采集处理。
3. 重载CMainFrame类DestroyWindow()函数,在该函数中设置线程jieshu释放加载的Dll等资源。
4. 添加工具栏图标按钮,ID为ID_EXIT_BAR,并为该按钮添加消息处理 函数OnExitProgramme(),在OnExitProgramme()中调用DestroyWindow(),目的是退出应用程序。
实际结果是:
1. 点击退出按钮图标,调用DestroyWIndow()关闭了CMainFrame主框架窗口,但由于数据采集处理线程中申请的资源还没有释放,线程仍在运行导致程序崩溃。
2. 直接点击主框架窗口的关闭按钮,数据采集线程可以正常退出,从而程序也可以正常结束运行。
由此引起的思考是:点击关闭按钮和直接调用DestryWindow()函数MFC的消息处理过程有何不同?
DestroyWindow()关闭当前窗口,销毁与指定CWnd窗口对象关联的窗口,但未销毁CWnd对象,这种方法适合关闭当前窗口时使用。
点击关闭按钮发送是WM_CLOSE消息,SendMessage(WM_CLOSE),此时CMainFrame会收到WM_CLOSE消息。CFrameWnd(CMainFrame的父类)间接会调用CWnd::DestroyWindow;它首先向CSimSenceView发送WM_DESTORY和WM_NCDESTROY消息,并触发相应的处理函数;在CSimSenceView的析构函数中执行了确保采集完全退出并释放资源的逻辑后,程序安全退出。
解决办法是:
在OnExitProgramme()函数中添加如下语句:
AfxGetMainWnd()->SendMessage(WM_CLOSE);替代DestroyWindow();
由于对MFC的应用程序框架和消息映射机制认识有限,能想到的只有这些。