One of the new features available in MFC in the Visual Studio 2010 CTP is the Restart Manager. This was introduced with Windows Vista to offer support for restarting application when a crash occurs or when an automatic update needs to close and then restart an application.
When you create a new MFC project in Visual Studio 2010, in the Advanced Features property page you can specify the level of support you want for the restart manager.
You can select one of the following:
- Support Restart Manager: restarts after crash or upgrade
- Reopen previously open documents: reopens previously open documents
- Support application recovery: recovers auto saved documents
There are three flags defined for these three options:
- AFX_RESTART_MANAGER_SUPPORT_RESTART for Support Restart Manager
- AFX_RESTART_MANAGER_SUPPORT_RESTART_ASPECTS for Reopen previously open documents
- AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS for Support application recovery
These are defined in the afxwin.h header.
// Restart Manager support flags #define AFX_RESTART_MANAGER_SUPPORT_RESTART 0x01 // restart support, means application is registered via RegisterApplicationRestart #define AFX_RESTART_MANAGER_SUPPORT_RECOVERY 0x02 // recovery support, means application is registered via RegisterApplicationRecoveryCallback #define AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART 0x04 // auto-save support is enabled, documents will be autosaved at restart by restart manager #define AFX_RESTART_MANAGER_AUTOSAVE_AT_INTERVAL 0x08 // auto-save support is enabled, documents will be autosaved periodically for crash recovery #define AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES 0x10 // reopen of previously opened documents is enabled, on restart all previous documents will be opened #define AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES 0x20 // restoration of auto-saved documents is enabled, on restart user will be prompted to open auto-saved documents intead of last saved #define AFX_RESTART_MANAGER_SUPPORT_NO_AUTOSAVE AFX_RESTART_MANAGER_SUPPORT_RESTART | AFX_RESTART_MANAGER_SUPPORT_RECOVERY | AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES #define AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS AFX_RESTART_MANAGER_SUPPORT_NO_AUTOSAVE | AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART | AFX_RESTART_MANAGER_AUTOSAVE_AT_INTERVAL | AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES #define AFX_RESTART_MANAGER_SUPPORT_RESTART_ASPECTS AFX_RESTART_MANAGER_SUPPORT_RESTART | AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART | AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES | AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES #define AFX_RESTART_MANAGER_SUPPORT_RECOVERY_ASPECTS AFX_RESTART_MANAGER_SUPPORT_RECOVERY | AFX_RESTART_MANAGER_AUTOSAVE_AT_INTERVAL | AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES | AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES
Enabling this support is done with a single line in the constructor of the CWinAppEx derived class.
CRecoveryDemoApp::CRecoveryDemoApp() { m_bHiColorIcons = TRUE; // support Restart Manager m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS; // TODO: add construction code here, // Place all significant initialization in InitInstance }
Here is an application with the full support for restart enabled. There are two opened documents, one that is saved (on the left) and one that is not saved (on the right).
When I hit the crash button, the application uses a null pointer and crashes.
Now, when I press the Ignore button of the crash report window, I get the restart manager window tha allows me to Restart the program.
The restart manager will attempt to restart the program and reopen my documents, which it successfully does.
However, you can see that though the support for recovering auto saved documents was enabled, the second, unsaved document was not recovered. The reason was that this document was not auto saved, because the default interval for the auto save is 5 minutes and I crashed the program immediatelly after writing into the document. This default interval can be changed by calling the SetAutosaveInterval() method of the data recovery handler. In the following example I change this interval to one minute.
BOOL CRecoveryDemoApp::InitInstance() { // ... CDataRecoveryHandler* autohandler = AfxGetApp()->GetDataRecoveryHandler(); autohandler->SetAutosaveInterval(60000); return TRUE; }
Here is another instance of the application with the first document saved, and the second not directly saved, but auto saved after one minute of inactivity.
When the application restarts, because there was an auto saved document that can be recovered, a new window is displayed.
If I choose Recover the auto-saved documents my unsaved (but auto saved) document is recovered.
These options for restarting the application and saving and loading the application data (documents) are exposed through virtual methods in the CWinAppEx class.
virtual void PreLoadState() {} // called before anything is loaded virtual void LoadCustomState() {} // called after everything is loaded virtual void PreSaveState() {} // called before anything is saved virtual void SaveCustomState() {} // called after everything is saved
You can override these methods in your application for custom handling of the save and load operations.
To learn more about this new feature I suggest you read the Visual C++ team’s blog.
Superb Article
Would be pleased if you publish more articles for Visual C++ 2010 and Visual C++ 2005
I was wondering if you couldn’t simplify the autosave interval without getting the auto handler pointer with simply:
// support Restart Manager
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
m_nAutosaveInterval = 60000;