0
votes

I have an MFC MDI application, in which it is possible for documents to have multiple views, and for users to customise and then save layout data for the views. This data is associated with the views, not the documents.

I would like to prompt the users to save if they choose to close a view with unsaved layout changes, and am running into problems, as it seems MFC is only geared towards changes in the document. Here are some approaches I've tried:

  1. Override CDocument::SaveModified function, which gets called by the framework when a document is closed. In this function, I send a message to all the document's views, which can then check for unsaved changes and prompt the user.

  2. Perform the check inside the View's destructor.

  3. Perform the check inside the View's OnClose handler

Each of these approaches has problems. (1) is the best, but it fails to deal with cases where there are several views onto one document, and the user closes one of the views. As the document is still open, SaveModified is not called.

The problem with (2) is that on application shutdown, the application has already disappeard by the time any CView destrutors are called. This can leave an orphan dialog box open on the desktop. This is also the case if I try performing the check inside OnDestroy.

I can't get (3) to work - I can't get my views to respond to WM_CLOSE.

Currently, my best solution is to do both (1) and (2), but this requires some smelly logic to prevent the app from prompting the user to save view changes twice on app shutdown.

Anyone know of a better way of doing this? Where is the correct place to hook in?

1
Probably bad data definition and/or modelling. Views are not meant to hold any data - at least such that can be saved in the document file. If you have such data put them in the CDocument class instead. Views may modify the document data (GetDocument()). The only "data" that can be contained in Views are maybe display options - you could store them in the registry and reload them when your app is loaded again (kinda "remembering user setting"). And the SaveModified() function rarely needs to be overridden (default is just fine), basically you just need to call GetDocument()->SetModifiedFlag(). - Constantine Georgiou
Forgot to mention, if you want to do something "on closing View window", and as your app is MDI, maybe try catching the OnClose() (or what) handler of the MDI chlid frame (normally parent window of your Views) instead? - Constantine Georgiou
The data I wish to save is related to the view layout, not the data being viewed. It would be totally wrong to put this data into the document. The same document can have many views, each with different settings. - Tom Davies
Sadly, even by the time the child frame gets to the PreCloseFrame stage, it's too late - the main app window is gone. - Tom Davies
Write your own WM_CLOSE handler for your frame classes that are parents of the views--your classes derived from CMDIChildWnd. That will handle individual closings of the views. You'll probably need to write one for the main frame too. It's not that hard. - Joseph Willcoxson

1 Answers

0
votes

I'm not sure if it is your solution, but I have several views that can not close on condition and I handle them in DestroyWindow( ). And a message box there does come up over the app before it closes down. So try using DestroyWindow( ) rather than the destructor.