Configuring new document in MFC


When the user creates a new document in my SDI-application, I need to present a dialog specifying details on the document to be created (think: resolution, bit-depth, etc.) I initially put the code for displaying this dialog in OnNewDocument() (I don't need it when opening an existing document), but putting user-interface code in the document-class just doesn't feel right (also, I don't have any CWnd* to use as a parent for the dialog).
Is there a better place to do this in MFC?

Best Solution

You're right, the document class is no good place for UI.

CDocTemplate::[OpenDocumentFile][1](pszPath) looks like a better candidate:

pszPath==NULL means 'create a new document'.

The method is virtual -> Just derive CMySingleDocTemplate from CSingleDocTemplate and use an instance of this class in CMyWinApp::InitInstance().

This class is responsible for creating docs, frames and views, hence I think it's a good place to put a UI operation.

BOOL CMyWinApp::InitInstance()
  CSingleDocTemplate* pDocTemplate;
  pDocTemplate = new CMySingleDocTemplate( // <--Derives from CSingleDocTemplate

CDocument* CMySingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
    BOOL bMakeVisible)
  CDocument *pDoc = 
    CSingleDocTemplate::OpenDocumentFile(lpszPathName, bMakeVisible);

  if (lpszPathName==NULL)
    // GUI to get user info

    // update doc

    // update view

This might not be ideal though: In SDI, there is one and only doc object. It's re-used accross File/Load and File/New operation.

This function will then be called a first time before the initial mainframe is created. You may not want to have a dialog presented to user before the frame is created. Ouch! It's a little more complicated: Instead of popping up a GUI in in OpenDocumentFile(NULL) as above, just post a custom message/command to the main frame. Then add a handler that will react by the sequence pop up GUI/update doc/update views. That way, the main frame will be displayed before the GUI is popped up and your user will be happier.

This also solves your problem where you don't have a CWnd parent: the main frame is already created and your dialog will use it byt default.

BTW, another solution consists in adding a command handler for ID_FILE_NEW in your CMyWinApp's message map and add your own override of OnFileNew(). But when you write OnFileNew(), I believe you'll quickly find out that it's an ugly solution :-(

Related Question