如何禁用MFC将工作区设置写入注册表?

7
默认情况下,Visual Studio 2010中的基本MFC C++项目将在用户可配置的键名下将其所有工作区设置存储在HKCU注册表中。这包括最后的窗口大小/位置、功能区设置、状态栏等。
如何完全禁用此功能,以便根本不写入注册表?
我尝试了不设置 SetRegistryKey() ,结果框架在第一次读/写注册表时出现了调试断言。 SetRegistryKey((LPCTSTR)NULL) 也得到了相同的结果。 SetRegistryBase() 似乎没有效果。 CWinApp / CWinAppEx 中的其他方法似乎也没有帮助。
2个回答

6

编辑:我的原始答案是错误的。我已经编辑了答案。


你可以告诉MFC将设置存储在.ini文件中,而不是注册表中。请参见这个之前的答案。(更新:如果您正在使用CWinAppEx,则只适用于该方法无效)

如果您想要阻止MFC完全保存菜单和工具栏的部分状态,请将以下内容添加到应用程序的构造函数中:

m_bSaveState = FALSE;

只有当您的应用程序派生自CWinAppEx时,m_bSaveState成员才被定义。

或者,您可以重写CWinAppEx::SaveStateCWinAppEx::LoadState来实现。


如果要消除WindowPlacement注册表键,则需重写CWinAppEx::StoreWindowPlacement

您仍可能会得到其他注册表项被写入。一个完整的解决方案是子类化CSettingsStore,然后在应用程序中调用CSettingsStoreSP::SetRuntimeClass。(点击这里获取更多信息。)这相当困难,因为您将不得不覆盖自定义CSettingsStore类中的一整堆虚函数。


这部分有所作为。将其设置为“FALSE”禁用了一些注册表键,但仍有一些保留。覆盖SaveState()/LoadState()以不执行任何操作,将其减少到只保存“WindowPosition”。参考问题中的答案无效。省略对SetRegistryKey()的调用会导致断言错误,即使没有省略,也不会创建.ini文件。可能是VS2010的差异? - spoulson
哎呀,我正在使用一个派生自CWinApp的类进行测试,而不是CWinAppEx。感谢您提醒我。我更新了答案,展示了如何摆脱WindowPlacement。(当您说“WindowPosition”时,您是指这个吗?) - Nate

2

我知道这对很多人来说已经晚了,但我发现CFrameWndEx——它将在您的CMainFrame类中——使用WM_CLOSE窗口来保存应用程序的默认位置。我不知道什么加载了位置。然而,如果您覆盖WM_CLOSE,则在退出程序时将永远不会保存该窗口状态。它将尝试重新加载上次的窗口状态,但由于从未保存过任何内容,因此无需担心。

一个容易出错的情况: 既然框架仍然调用某种WM_INIT函数来加载最后的位置,如果你按照正常的方式编译代码,最大化应用程序窗口,然后使用X关闭程序,WM_CLOSE会将应用程序状态保存为MAXIMIZED。如果像上面提到的那样重写WM_CLOSE重新编译应用程序,重新启动应用程序,您会注意到它始终以最大化状态启动!显然不是您想要的。因此,在关闭为普通窗口时重新激活(注释掉WM_CLOSE),让程序保存应用程序状态。重新启动程序后,允许覆盖的WM_CLOSE再次起作用,您会看到正常窗口重新出现。

代码:

在您的CMainFrame.h中

public: afx_msg void OnClose();

在你的CMainFrame.cpp文件中...扩展你的消息映射表。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)



*ON_WM_CLOSE() // <<< I ADDED THIS*

...... END_MESSAGE_MAP()

CMainFrame 类中的 void OnClose() {

PostQuitMessage(0);
//CFrameWndEx::OnClose(); << WE DO NOT WANT TO HAVE THIS CALLED!

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接