Solved

Dynamic Docuemnt Templates in MDI

Posted on 1999-01-17
16
224 Views
Last Modified: 2013-11-20
I'm writing an MFC app that can handle a number of different file types.

I want the user to be able to decide which file formats they want to use.

The easiest way I thought of doing this is to place each document template and view document classes in separate DLLs, like a sort of MFC extension DLL, and the user can place the ones they require in the app directory.

Doing it this way means that the DLLs can't be linked to the app when it is compiled as the DLLs that will be used aren't know at this time.

Is this the best way of doing it and is it possible?

Thanks

Gavin Rouse
0
Comment
Question by:gav061697
  • 9
  • 7
16 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 100 total points
ID: 1327837
It is possible. I'm not sure whether it is the best way, but it's at least a good one.
>>Doing it this way means that the DLLs can't be linked to the
>>app when it is compiled as the DLLs that will be used aren't
>>know at this time.
As 'CMultiDocTemplate' is always known, you can do it this way:
Implement a function in the DLL that does the following:

__declspec (dllexport)
CMultiDocTemplate* DllGetDocTemplate()
{
      CMultiDocTemplate* pTemplate;
      pOeTemplate = new CMultiDocTemplate(
            IDR_MYTEMPLATE,
            RUNTIME_CLASS(CMyTemplate),
            RUNTIME_CLASS(CChildFrame), // custom MDI child frame
            RUNTIME_CLASS(CMyTemplatesView));

return ( pTemplate);
}

0
 
LVL 86

Expert Comment

by:jkr
ID: 1327838
Ooops, i forgot about the apllication's part:

typedef CMultiDocTemplate* ( *PDLLGETDOCTEMPLATE)();
HANDLE hDll = LoadLibrary( "mydoctpl.dll");
PDLLGETDOCTEMPLATE pGetTemplate = (PDLLGETDOCTEMPLATE) GetProcAddress( hDll, "DllGetDocTemplate);

CMultiDocTemplate* pTemplate = (pGetTemplate)();

      AddDocTemplate(pTemplate);

      // Connect the COleTemplateServer to the document template.
      //  The COleTemplateServer creates new documents on behalf
      //  of requesting OLE containers by using information
      //  specified in the document template.

      m_server.ConnectTemplate( clsid, pTemplate, FALSE);


0
 
LVL 86

Expert Comment

by:jkr
ID: 1327839
OK - i just noticed that there are several tasks to do (e.g. using a .def file so that 'DllGetDocTemplate()' is exported using the correct name and a function that retrieves the DLL's clsid from the DLL), so feel free to ask if you have further qestions regarding this issue...
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:gav061697
ID: 1327840
There's actually a MFC example which I found in the help files called DLLHusk which does exactly what I want in the same way that you described.

However, my version works fine in Debug mode, but when I try the Release version my program crashes in the InitDLL function at the AddDocTemplate call (see the DLLHusk example if you're not sure what I mean).  The only difference with my code is that the classes are in separte files rather than all in one.

Do you know what might cause the problem.

My first thought was that the GetProcAddress() call was returning the wrong address as the crash seemed to occur in the RichEditCtrl source file.  However, I mangaed to partly debug my code and it gets to the AddDocTemplate call then goes to two source files which it shouldn't (BarDock.cpp and the RichEdit source file)

I can provide the source code if you want it.
0
 
LVL 86

Expert Comment

by:jkr
ID: 1327841
I assume that there are problems regarding the runtime class information - if you could provide some source code, this could be a great help ;-)
0
 
LVL 86

Expert Comment

by:jkr
ID: 1327842
Hmm - your DLL is created as a MFC extension DLL, isn't it?
0
 

Author Comment

by:gav061697
ID: 1327843
How should I give it to you?

>> Hmm - your DLL is created as a MFC extension DLL, isn't it?
Yes
0
 

Author Comment

by:gav061697
ID: 1327844
How should I give it to you?

>> Hmm - your DLL is created as a MFC extension DLL, isn't it?
Yes
0
 
LVL 86

Expert Comment

by:jkr
ID: 1327845
The best thing would be if you post the relevant parts...
0
 

Author Comment

by:gav061697
ID: 1327846
Here's my InitDLL() function

// Exported DLL initialization is run in context of running application
extern "C" void WINAPI InitDLL()
{
      TRACE0("DOCVIEW.DLL: InitDLL()\n");

      // create a new CDynLinkLibrary for this app
      new CDynLinkLibrary(DocViewDLL);

      // Register the doc templates we provide to the app
      CWinApp* pApp = AfxGetApp();
      ASSERT(pApp != NULL);

      /* Release crashes here */
      pApp->AddDocTemplate(new CMultiDocTemplate(IDR_VCTYPE,
                  RUNTIME_CLASS(CVCDoc),
                  RUNTIME_CLASS(CMDIChildWnd),
                  RUNTIME_CLASS(CVCView)));
      // add other initialization here
}
0
 
LVL 86

Expert Comment

by:jkr
ID: 1327847
Hmm, seems fine at first glance... Is the app also a release version?
0
 
LVL 86

Expert Comment

by:jkr
ID: 1327848
I'd suggest
CMultiDocTemplate* pTempl= CMultiDocTemplate(IDR_VCTYPE,
RUNTIME_CLASS(CVCDoc),
RUNTIME_CLASS(CMDIChildWnd),
RUNTIME_CLASS(CVCView));

if ( !pTempl) AfxMessageBox( ...);

pApp->AddDocTemplate( pTempl);

to find out whether the problem is related to the template or the call...
0
 

Author Comment

by:gav061697
ID: 1327849
I think i've found the problem...in the release version pApp == NULL

I don't know why...i'll try and look into it further...if you have any ideas let me know

Thanks
0
 
LVL 86

Expert Comment

by:jkr
ID: 1327850
The most common reason for this: Is the app also a release version? If not, you might want to test it using a release version of the application, as mixing debug/release usually leads into trouble...
0
 

Author Comment

by:gav061697
ID: 1327851
i'll try that..

thiscode  may/may not help...it's how I load and call the InitDLL() function:

HINSTANCE hInstance = AfxLoadLibrary("docview\\release\\docview.dll");
FARPROC farproc = GetProcAddress( hInstance, "InitDLL" );
if(farproc != NULL)
     farproc();
else
     AfxMessageBox("Can't find InitDLL() function.");

0
 

Author Comment

by:gav061697
ID: 1327852
just tried it...works fine now...how annoying...thanks for your help..

have some points :-)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Decoding 32 bit binary streams 6 54
Question regarding Copy/Paste 16 98
sum67 challenge 35 116
Way to decrease size of apk file 9 112
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

730 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