tags:

views:

140

answers:

1

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?

+2  A: 

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
    IDR_MAINFRAME,
    RUNTIME_CLASS(CMyDoc),
    RUNTIME_CLASS(CMainFrame),
    RUNTIME_CLASS(CMyView));
  AddDocTemplate(pDocTemplate);
  ...
}

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

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

    // update doc
    m_pOnlyDoc->Blah(input);

    // update view
    m_pOnlyDoc->UpdateAllViews(NULL,...,...);
  }
}

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 :-(

Serge - appTranslator