Solved

How to implement an import command

Posted on 1998-08-17
8
197 Views
Last Modified: 2013-11-20
I need to implement an import command in my MDI application but I cannot figure out how to do it using the MFC serialization mechanism.  My application needs to import files coming from different machines (these  files have no extension). I have tried to follow the tips given in the  Technical note 22:

"One common customization of ID_FILE_OPEN is to customize the FileOpen
dialog or add additional file filters. The recommended way to customize
this is to replace the default implementation with your own FileOpen
dialog, and call CWinApp::OpenDocumentFile with the document's file or path
name. There is no need to call the base class."

I have followed this procedure but without success. This is the code:
void CMyApp::OnFileOpen()
{
      CMyCustomFileOpenDlg dlg(TRUE);
      
      int nResponse=dlg.DoModal();
      //In this dialog, the user must set in the m_fileType member variable
      //the file format.
      //Later, the MyDoc::Serialize function will use this variable to proceed.
      
      
      CWinApp::OpenDocumentFile(filename);
      
}

I have discovered that when   CMyApp::OnFileOpen is overrided, the CMyDoc::Serialize function is not called so I cannot do something as follows:
void MyDoc::Serialize (CArchive& ar)
 {
  if (ar.IsStoring())
  {
   // Storing code
 
  }
  else
  {
   // Reading code
   if (m_FileType== FILE_TYPE_A)
   {
    //import doc A
 
   }
   if (m_FileType== FILE_TYPE_B)
   {
    //import doc B
 
   }
  }
 }

What am I doing wrong?
Might be there is a best way to implement an import option, but I don't really know how.
0
Comment
Question by:qocarlos
  • 4
  • 4
8 Comments
 
LVL 6

Accepted Solution

by:
snoegler earned 100 total points
ID: 1320918
I am not totally sure if i did get your right, but i think this is what you want:
- your import function should convert external files into your internal document structure
- you want to do this from within the standard 'File open' dialog

In general, if you do not want the MFC serialization procedure to read your document data,
just override the CDocument::OnOpenDocument(LPCTSTR lpFilename) function.
The default function creates a CArchive object, calling Serialize() and so on. To alter this
behavior, just do *not* call the base function.
Instead read the data by constructing a CFile object, using its Read() and Write() functions.

In particular, a way would be to add multiple document templates - see the
CMultiDocTemplate constructor.
You'll pass a string to the constructor which defines for which file extension this template
applies. All of these templates will be listed in your standard 'File open' dialog box
automatically, this is done by the framework.
Now - if the files you want to import all use the same CDocument class - you only need
to test the GetDocTemplate() result in your CDocument::OnFileOpen

Refer to
- CDocument::OnFileOpen
- CMultiDocTemplate
- "KB: Visual C++","Format of the document template string"

Sample:

CMyDoc::OnFileOpen(LPCTSTR lpFilename)
{
  CDocTemplate *pDocTemplate=GetDocTemplate();
  CString extension;

  pDocTemplate->GetDocString(extension,CDocTemplate::filterExt);
  if(extension==".myd") // mydocument type
     ....
  if(extension==".xls") // excel document type
     ...
// If you want for a certain doc type to process the default Serialize() thing, just
// invoke CDocument::OnFileOpen(lpFilename)
}
0
 
LVL 3

Author Comment

by:qocarlos
ID: 1320919
I need to customize the standar FileOpen dialog because the user must select more than one file by selecting the file and then adding each file to a list box (this is because the files to be opened are in separate folders). I have also added to the customized File Open dialog a combo box where the user can select the file type. I store all the files in a CStringList member variable.
All these external  files must be converted then in one internal document.
I cannot use something like:

if(extension==".myd") // mydocument type
         ....
if(extension==".xls") // excel document type

because these files has no extension.

I'm still very confused...
0
 
LVL 6

Expert Comment

by:snoegler
ID: 1320920
I don't understand your problem.
Take a look at this:

void CMyApp::OnFileOpen()
    {
    CMyCustomFileOpenDlg dlg(TRUE);

    int nResponse=dlg.DoModal();
    //In this dialog, the user must set in the m_fileType member variable
    //the file format.
    //Later, the MyDoc::Serialize function will use this variable to proceed.

   // *dlg.m_FileListBox contains the files the user selected*
   int i,size=dlg.m_FileListBox.GetCount();
   for(i=0;i<size;i++) {
      CString cur_file;
      m_FileListBox.GetText(i,cur_file);
      // m_pMainWnd points to the main CFrameWnd of your app( i.e. CMainFrame)
      ((CFrameWnd*)m_pMainWnd)->GetActiveDocument()->ImportFile(cur_file,dlg.m_fileType);
    }
}

And the CDocument::ImportFile() reads in the data, with m_fileType specifying the type of the
file to import.
Does this solve your problem? If not, please give a bit more information about what is to be
done ...
0
 
LVL 3

Author Comment

by:qocarlos
ID: 1320921
Thanks for your help but I'm still have problems!
This is what I have tried using your previous advice:

void CMyApp::OnFileOpen()
{
     (...)
      CMyDoc *pDoc=CMyDoc::GetDoc();
      pDoc->ImportFile(cur_file,dlg.m_fileType);
}

where
CMyDoc * CMyDoc ::GetDoc()
{
      CMDIChildWnd * pChild =
          ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();
 
      if ( !pChild )
          return NULL;
 
      CDocument * pDoc = pChild->GetActiveDocument();
 
      if ( !pDoc )
         return NULL;
 
      // Fail if doc is of wrong kind
      if ( ! pDoc->IsKindOf( RUNTIME_CLASS(CMestreCProDoc) ) )
         return NULL;
 
      return (CMyDoc *) pDoc;
}

but after calling CMyDoc:: ImportFile(cur_file,dlg.m_fileType) and reading
the files, how should I create the window? (all the files contained indlg.m_FileListBox must be opened in the same document).

My idea is to add a CMultiDocTemplate point to CMyApp derived class:
Class CMyApp:public CWinApp
{
   ...
   public CMultiDocTemplate* m_pDocTemplate;
   ...
}
In the InitInstance() function, remove the creation of the CMultiDocTemplate from the call to AddDocTemplate , set the pointer to point to the new CMultiDocTemplate and use the pointer to call AddDocTemplate.

So the OnFileOpen would be now:

void CMyApp::OnFileOpen()
{
     (...)
      CMyDoc *pDoc=CMyDoc::GetDoc();
      pDoc->ImportFile(cur_file,dlg.m_fileType);
      m_pDocTemplate->OpenDocumentFile(NULL);//create the new window
}

Probably this is a wrong way.
Can you give me  solution that will allow me to correctly import the files?

Thanks




0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 6

Expert Comment

by:snoegler
ID: 1320922
The code below creates a new document and associated view.
I am assuming that there's only one CDocTemplate in your app, but if there are more, just
iterate using GetNextDocTemplate() until you have the right one (see docs).
The line with 'pNewDoc->OnNewDocument()'  you could replace with the code which opens
the file dialog window, and call perhaps the pNewDoc->OnImportFile() for each file or so.
I hope this time i got you right =o)


void  CMestreCProApp::OnFileOpen()
{
  // TODO: Add your command handler code here
  // 1st.: Get the appropriate CDocTemplate()
  // I am assuming that there's only one CDocTemplate()
 
  POSITION pos=GetFirstDocTemplatePosition();
  if(pos==NULL) {
    // error //
    return;
  }
  CDocTemplate *pdTemp=GetNextDocTemplate(pos);
 
  // 2nd.: Create Doc&Frame
  CDocument *pNewDoc;
  CChildFrame *pChildFrm;
 
  pNewDoc =pdTemp->CreateNewDocument();
  pChildFrm =(CChildFrame*)pdTemp->CreateNewFrame(pNewDoc,NULL);
  pdTemp->SetDefaultTitle(pNewDoc);

  // 3rd: Notify Doc of its existence  
  // *you could also do here the CFileDialog() and then pNewDoc->OnImportFiles(CListBox ...)
  pNewDoc->OnNewDocument();
  pdTemp->InitialUpdateFrame(pChildFrm,pNewDoc,TRUE);
}
0
 
LVL 3

Author Comment

by:qocarlos
ID: 1320923
Snoegler,
I have tried your code and it worked great! Thanks a lot.
I'd just like to know if my code (see my previous comment) has any disavantage compared with your code.
0
 
LVL 6

Expert Comment

by:snoegler
ID: 1320924
I think what you wrote is exactly the same as what i proposed.
I didn't read your whole comment, sorry for that ... I don't like reading code, especially if it isn't
formatted at all like here at experts exchange. The way you want to do it should work - the
way i used is just an alternative way to that what you've done (i think so, but i didn't try what
you posted).
0
 
LVL 3

Author Comment

by:qocarlos
ID: 1320925

I have also tried my code and it worked!!
Thanks again for your help
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now