?
Solved

Dynamic Docuemnt Templates in MDI

Posted on 1999-01-17
16
Medium Priority
?
226 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 7
16 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 400 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
Will your db performance match your db growth?

In Percona’s white paper “Performance at Scale: Keeping Your Database on Its Toes,” we take a high-level approach to what you need to think about when planning for database scalability.

 

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

Get MySQL database support online, now!

At Percona’s web store you can order your MySQL database support needs in minutes. No hassles, no fuss, just pick and click. Pay online with a credit card.

Question has a verified solution.

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

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 …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
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.
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses
Course of the Month9 days, 11 hours left to enroll

762 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