持续化更新的视状态,在DLL中使用托管扩展
2006-07-20 11:43:22 来源:WEB开发网void CListViewShellWnd::OnDestroy() {
TRACE(_T("CListViewShellWnd::OnDestroy\n"));
...
}
现在运行“打开”对话框并切换文件夹。已经足够了,看一下文件夹视图便知了。CListViewShellWnd 忠实地保存了其视图模式,但当用户改变文件夹时,“打开”对话框销毁了它的 SHELLDLL_DefView,从而导致 MFC (在 CWnd::OnNcDestroy 中)对之进行自动反子类化(unsubclass)并将 m_hWnd 置为NULL。此后“打开”对话框创建新的 SHELLDLL_DefView,然而此时 CPersistOpenDlg 再也看不到这个 SHELLDLL_DefView,所以当 CPersistOpenDlg 将视图模式写入用户配置文件时,它写入的是用户改变文件夹之前的老数据。
幸运的是,这个 Bug 不属于那种难以再现的Bug。修复 CPersistOpenDlg 也不难,稍微想一想便可以解决。显而易见的事情是必须捕获 OnFolderChange 和重新子类化文件夹视图。重新进行子类化是正确的思路,但为什么要在 OnFolderChange 里做呢?不管什么时候,只要你在 Windows 中发现意想不到的事情,扪心自问一下:还有什么地方会出错?如果“打开对话框”在用户切换文件夹时销毁其自身文件夹视图,那么你怎么知道在其它时候不会销毁呢?比如在万圣节的午夜钟声敲响时,或者 Red Sox 在月蚀期间赢得世界棒球大赛的时候?为了找到问题的解决办法,我们要深入分析问题的根源,而不是只看表面现象。
CPersistOpenDlg 已经有一个私有消息 MYWM_POSTINIT 来初始化对话框。当对话框第一次启动时,CPersistOpenDlg 在 OnInitDialog 中将该消息发(POST)给自己,处理例程子类化该文件夹视图。当文件夹视图被销毁时,我只要再发一次 MYWM_POSTINIT 即可:
更多精彩
赞助商链接