FMD Studio VC Programming Technical Articles:
[
Back to previous points]
Numbering
Subject
Originate
Recording time
5
Multi-template document view structure application
Self-writer
00.05.08
Multi-template document view structure application
I. Overview
1 In an MDI program, you need to use different types of sub-windows, and each type window may have many, corresponding to different data.
At this time, the document view structure of the multi-template can be used. It is convenient to use the document view structure.
2 When establishing some type of MDI child window, call the OpenDocumentFile of the corresponding document template ()
And its parameters LPCTSTR LPSZFILENAME can be used as a parameter when establishing an MDI window.
3 During use, the document object does not have to correspond to the disk file, but define the internal data structure as needed.
However, in the MFC document structure, many places are connected to the actual files, so in use, some detail needs to be processed.
Second, the establishment of multi-document document template
1 Create multiple document template pointers in the application class as a member data
example:
CMULTIDEMPLATE * PCALCDOCTEMPLATE;
CMULTIDEMPLATE * PDATADOCTEMPLATE;
2 Build multiple document template objects in the application class initInstance.
Each document template corresponds to a different document, and the view class combination.
example:
PCALCDOCTEMPLATE = New CMULTIDOCTEMPLATE
IDR_VFPTYPE,
Runtime_class (cvfpdoc),
Runtime_class (cchildframe), // Custom MDI Child Frame
Runtime_class (cvfpview));
AddDDOCTemplate (PCALCDOCTEMPLATE);
PDATADEMPLATE = New CMULTIDOCTEMPLATE
IDR_DATATYPE,
Runtime_class (cdatadoc),
Runtime_class (cdatachildframe), // Custom MDI Child Frame
Runtime_class (cdataListView);
AddDDOCTemplate (pdatadoctemplate);
3 Add a member of the creation window to the application class.
example:
CDocument * cxxxApp :: OpenDATADocumentFile (LPCTSTR LPSZFILENAME)
{
PDATADEMPLATE
Return pdatadoCtemplate-> OpenDocumentFile (LPSZFILENAME);
Else
Return NULL;
}
CDocument * CXXXAPPPP :: OpenCalcDocumentFile (LPCTSTR LPSZFILENAME)
{
IF (PCALCDOCTEMPLATE)
Return PCALCDOCTEMPLATE-> OpenDocumentFile (LPSZFILENAME);
Else
Return NULL;
}
4 When you need to establish different types of MDI sub-windows, call the above members.
Third, detail processing
1 Avoid opening the MDI child window corresponding to the same parameter multiple open.
When the disk file is processed, the document manager checks if the document manager checks if it is opened, and the window has been opened.
This check is bypassed when you call the OpenDocumentFile of the Document Template.
But when needed, you can add the corresponding code in your own open "file" member function (substantially the copy of the MFC original code).
Example: The above OpenCalcDocumentFile can be changed to:
CDocument * cxxxApp :: OpenCalcDocumentfile (lpctstr lpszfilename) {
IF (PCALCDOCTEMPLATE)
{
CDocument * poverocument = NULL;
PCALCDOCTEMPLATE-> MatchDOCTYPE (LPSZFILENAME, POPENDOCUMENT); / / Determine if lpszfilename window has been established
IF (POPENDOCUMENT! = null) // If it has been established, activate
{
Position POS = POS = POPENDOCUMENT-> getFirstViewPosition ();
IF (POS! = NULL)
{
CView * PView = Poverocument-> GetNextView (POS); // Get First ONE
Ask_VALID (PVIEW);
CframeWnd * pframe = pView-> getParentFrame ();
IF (pframe! = null)
Pframe-> ActivateFrame ();
Else
TRACE0 ("Error: Can Not Find A Frame for Document To Activate./N");
CframeWnd * Pappframe;
IF (Pframe! = (PAPPFRAME = (CFrameWnd *) AFXGetApp () -> m_pmainwnd))
{
Assert_kindof (cframeWnd, PAPPFrame);
PAPPFRAME-> ActivateFrame ();
}
}
Else
{
TRACE0 ("Error: Can Not Find A View for Document To Activate./N);
}
Return Poverocument;
}
ELSE / / Otherwise open directly
Return PCALCDOCTEMPLATE-> OpenDocumentFile (LPSZFILENAME);
}
Else
Return NULL;
}
But after rewriting, it is found that the window is still turned on in some cases. The reason is that matchdoctype is judged.
In MatchDOCTYPE, you need to compare the file names and input document names saved in the document object.
However, when the document object is established, the document is fully path, and the "file name" as a parameter is considered to be a relative path to add a directory name. It is naturally not equal to comparison.
Fortunately, the MFC has considered these, and the document class provides virtual functions setPathname (LPCTSTSTSZPATHNAME, BOOL BADDTOMRU),
In your own document class, overload SetPathName, shield its default implementation, change to:
Void cxxxdoc :: setPathname (LPCTSTR LPSZPATHNAME, BOOL BADDTOMRU)
{
m_strpathname = lpszpathname; / / directly into the incoming name as the last document name
m_bembedded = false; // mode (not embedded object)
Settitle (LPSZPATHNAME); // Set the title (can be changed)
}
When actually use, for each document template, its OpenDocumentFile is not convenient to add a lot of code, which is inconvenient, this is, you can build a shared part into a member function.
example:
CDocument * cxxxapp :: OpenWithTemplate (cmultidoctemplate * pdoctemplate, lpctstr lpszfilename) {
IF (PDOCTemplate)
{
CDocument * poverocument = NULL;
PDOCTemplate-> MatchDoctype (LPSZFILENAME, POPENDOCUMENT); / / Avoid repeated open
IF (Poverocument! = NULL)
{
Position POS = POS = POPENDOCUMENT-> getFirstViewPosition ();
IF (POS! = NULL)
{
CView * PView = Poverocument-> GetNextView (POS); // Get First ONE
Ask_VALID (PVIEW);
CframeWnd * pframe = pView-> getParentFrame ();
IF (pframe! = null)
Pframe-> ActivateFrame ();
Else
TRACE0 ("Error: Can Not Find A Frame for Document To Activate./N");
CframeWnd * Pappframe;
IF (Pframe! = (PAPPFRAME = (CFrameWnd *) AFXGetApp () -> m_pmainwnd))
{
Assert_kindof (cframeWnd, PAPPFrame);
PAPPFRAME-> ActivateFrame ();
}
}
Else
{
TRACE0 ("Error: Can Not Find A View for Document To Activate./N);
}
Return Poverocument;
}
Else
Return pdoctemplate-> OpenDocumentFile (LPSZFILENAME);
}
Else
Return NULL;
}
[Back to previous points]