qocarlos
asked on
How to implement an import command
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.
"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(
}
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.G etCount();
for(i=0;i<size;i++) {
CString cur_file;
m_FileListBox.GetText(i,cu r_file);
// m_pMainWnd points to the main CFrameWnd of your app( i.e. CMainFrame)
((CFrameWnd*)m_pMainWnd)-> GetActiveD ocument()- >ImportFil e(cur_file ,dlg.m_fil eType);
}
}
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 ...
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.G
for(i=0;i<size;i++) {
CString cur_file;
m_FileListBox.GetText(i,cu
// m_pMainWnd points to the main CFrameWnd of your app( i.e. CMainFrame)
((CFrameWnd*)m_pMainWnd)->
}
}
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 ...
ASKER
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_file Type);
}
where
CMyDoc * CMyDoc ::GetDoc()
{
CMDIChildWnd * pChild =
((CMDIFrameWnd*)(AfxGetApp ()->m_pMai nWnd))->MD IGetActive ();
if ( !pChild )
return NULL;
CDocument * pDoc = pChild->GetActiveDocument( );
if ( !pDoc )
return NULL;
// Fail if doc is of wrong kind
if ( ! pDoc->IsKindOf( RUNTIME_CLASS(CMestreCProD oc) ) )
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_file Type);
m_pDocTemplate->OpenDocume ntFile(NUL L);//creat e the new window
}
Probably this is a wrong way.
Can you give me solution that will allow me to correctly import the files?
Thanks
This is what I have tried using your previous advice:
void CMyApp::OnFileOpen()
{
(...)
CMyDoc *pDoc=CMyDoc::GetDoc();
pDoc->ImportFile(cur_file,
}
where
CMyDoc * CMyDoc ::GetDoc()
{
CMDIChildWnd * pChild =
((CMDIFrameWnd*)(AfxGetApp
if ( !pChild )
return NULL;
CDocument * pDoc = pChild->GetActiveDocument(
if ( !pDoc )
return NULL;
// Fail if doc is of wrong kind
if ( ! pDoc->IsKindOf( RUNTIME_CLASS(CMestreCProD
return NULL;
return (CMyDoc *) pDoc;
}
but after calling CMyDoc:: ImportFile(cur_file,dlg.m_
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,
m_pDocTemplate->OpenDocume
}
Probably this is a wrong way.
Can you give me solution that will allow me to correctly import the files?
Thanks
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=GetFirstDocTemplatePos ition();
if(pos==NULL) {
// error //
return;
}
CDocTemplate *pdTemp=GetNextDocTemplate (pos);
// 2nd.: Create Doc&Frame
CDocument *pNewDoc;
CChildFrame *pChildFrm;
pNewDoc =pdTemp->CreateNewDocument ();
pChildFrm =(CChildFrame*)pdTemp->Cre ateNewFram e(pNewDoc, NULL);
pdTemp->SetDefaultTitle(pN ewDoc);
// 3rd: Notify Doc of its existence
// *you could also do here the CFileDialog() and then pNewDoc->OnImportFiles(CLi stBox ...)
pNewDoc->OnNewDocument();
pdTemp->InitialUpdateFrame (pChildFrm ,pNewDoc,T RUE);
}
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()'
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=GetFirstDocTemplatePos
if(pos==NULL) {
// error //
return;
}
CDocTemplate *pdTemp=GetNextDocTemplate
// 2nd.: Create Doc&Frame
CDocument *pNewDoc;
CChildFrame *pChildFrm;
pNewDoc =pdTemp->CreateNewDocument
pChildFrm =(CChildFrame*)pdTemp->Cre
pdTemp->SetDefaultTitle(pN
// 3rd: Notify Doc of its existence
// *you could also do here the CFileDialog() and then pNewDoc->OnImportFiles(CLi
pNewDoc->OnNewDocument();
pdTemp->InitialUpdateFrame
}
ASKER
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.
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.
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).
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).
ASKER
I have also tried my code and it worked!!
Thanks again for your help
ASKER
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...