Click here to Skip to main content
Click here to Skip to main content

Using a Doc/View exported from a dynamically loaded DLL

, 15 Nov 2001
Rate this:
Please Sign up or sign in to vote.
An article on on how to load DLLs which export doc/views.

Sample Image

Introduction

I recently needed to be able to create new document/view's that were contained within a DLL. After an initial search on developer sites, I didn't find any article which covered this subject. So I went ahead and tried to do it myself.

It comes down to overriding two classes which MFC uses to create and manage the document templates used. These are CDocManager and CMultiDocTemplate (I am doing this in an MDI app).

The CDocManager class was inherited from, to add the functionality to open a given document type without having to display the MFC "Select document type" dialog which is used when more than one document template exists in the project. The CMultiDocTemplate was inherited from and virtual functions re-written to allow the new class to load the resources from the DLL instance and not the EXEs.

Ok, so how do we go about doing this? First you need to create your DLL, and add a document/view class which will be your exported document/view. Create a class inheriting from CView, CScrollView or CFormView etc. Do the same for a class inheriting from CDocument. You will have to write the GetDocument() function for the view, it's just a copy of what you see in a regular .EXE file doc/view class but with the DLL class names.

#ifdef _DEBUG
void CDLLDocument::AssertValid() const
{
    CDocument::AssertValid();
}

void CDLLDocument::Dump(CDumpContext& dc) const
{
    CDocument::Dump(dc);
}
#endif //_DEBUG

You also have to add an exported function from the DLL as follows:

CMyMultiDocTemplate* DLLNewDocTemplate()
{
    CMyMultiDocTemplate    *pTemplate = NULL ;
    // add our document template
    pTemplate = new CMyMultiDocTemplate(
        theApp.m_hInstance, // the DLL's app object
                           // HINSTANCE for resource loading
        IDR_DLL_TYPE, // the document/view resource info
        RUNTIME_CLASS(CMyDLLDoc),
        RUNTIME_CLASS(CChildFrame), // custom MDI child frame 
                                   // (this will be the files from the exe)
        RUNTIME_CLASS(CMyDLLView));
    return pTemplate ;
}

When you call this procedure, it returns a pointer to a CMyMultiDocTemplate object which can be added to the list of available document types in your main exe's InitInstance procedure.

Your DLL must have the following resources defined with the ID of IDR_DLL_TYPE:

  • Menu - The menu that gets switched to when the doc/view type is open and selected.
  • Dialog - A CFormView dialog template if your class inherits from CFormView.
  • String table - Document type names in the same format as the type used in a .exe file. Example: "\nDLL\nDLL\n\n\nDLL.Document\nDLL Document".
  • Icon - The icon that appears on the window's title bar

What code goes in your InitInstance?

In your app's InitInstance, there will be some code to add the single document template that your app will currently support. You need to do some minor modification to this as follows:

// Register the application's document templates.  Document templates
// serve as the connection between documents, frame windows and views.
// need to setup our own document manager before the first call of
// AddDocTemplate(...)
m_pDocManager = new CMyDocManager ; // we replace the default doc manager
// MFC only creates its own one if m_pDocManager is NULL
CMyMultiDocTemplate* pDocTemplate; 
// change the template type to our inherited one
pDocTemplate = new CMyMultiDocTemplate(
    theApp.m_hInstance, // the apps HINTANCE so we can find the correct resources
    IDR_SOMECLASSTYPE,
    RUNTIME_CLASS(CSomeClassDoc),
    RUNTIME_CLASS(CChildFrame),
    RUNTIME_CLASS(CSomeClassView));
AddDocTemplate(pDocTemplate);
// See Example EXE project
// add your DLL calls here to DLLNewDocTemplate()
// e.g.
for (int i = 0 ;i < number_of_dlls ; i++)
    {
    pTemplate = SomeDLL.DLLNewDocTemplate() ;
    if (pTemplate != NULL)
        AddDocTemplate(pDocTemplate) ;
    }
// then call AddDoctemplate() on the returned values.
// you have to do this before the call to RegisterShellFileTypes()

You also have to modify your ExitInstance to deal with the inherited CMyDocManager. If you don't do this, MFC will fail to deallocate correctly.

Add these lines:

// delete doc manager before unloading dll's
delete (CMyDocManager*)m_pDocManager ;
m_pDocManager = NULL ;
// from this point you can unload your DLL's
// doing so before here will cause problems

This must be done before the call to CWinApp::ExitInstance and before your DLLs are unloaded!

Ok, that's the big work out of the way. How do you open a document of these new types? For your regular EXE doc/view type, the current mechanism will work as normal except that you will get the MFC "select document type" dialog. If you don't want this, change your app's OnFileNew as follows:

// this will open your regular .exe document type without
// using the "Select document type" dialog
//CWinApp::OnFileNew() ;
((CMyDocManager*)m_pDocManager)->CreateNewDocument(0) ; 
// create first document type

This command holds for any of the given document types that have been added. To create the 2nd document type:

((CMyDocManager*)m_pDocManager)->CreateNewDocument(1) ; 
// create 2nd document type

So that's it basically. You just need to put the regular doc/view code handling stuff in your DLL and add the .h and .cpp files to your projects as required. You also have to export your CChildFrame classes to your DLLs as well, to make the class accessible there.

Word of warning

Your menus could be the biggest problem after this point. If you have standard menu options like those in the default menu displayed when no documents are open, I recommend that you copy this menu across into your DLL as a base menu from which to build the menu used by your new document type(s), that way the IDs for all the original menu options will work without any problems. You should also check for possible clashes between any new menu items you add to the DLL menu to make sure they are not used by any in the menus used by the exe's document.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Roger Allen
Software Developer (Senior) Sirius Analytical Instruments
United Kingdom United Kingdom
A research and development programmer working for a pharmaceutical instrument company for the past 17 years.
 
I am one of those lucky people who enjoys his work and spends more time than he should either doing work or reseaching new stuff. I can also be found on playing DDO on the Cannith server (Send a tell to "Maetrim" who is my current main)
 
I am also a keep fit fanatic, doing cross country running and am seriously into [url]http://www.ryushinkan.co.uk/[/url] Karate at this time of my life, training from 4-6 times a week and recently achieved my 1st Dan after 6 years.

Comments and Discussions

 
QuestionCDocument and CView from DLL Pinmemberrupeshbari8321-Jan-14 18:10 
GeneralMy vote of 5 Pinmemberaydinsahin18-Feb-11 6:59 
GeneralExplanation Pinmembertom groezer3-Jun-07 10:34 
QuestionCan't work in "Use MFC in a Static Library" mode Pinmember9353201812-Apr-07 22:57 
AnswerRe: Can't work in "Use MFC in a Static Library" mode Pinmembercluster226-Jan-09 6:43 
GeneralRe: Can't work in "Use MFC in a Static Library" mode PinmemberSoundman32.219-Feb-09 3:55 
Questioncan this dll be c# application call? Pinmemberyanct29-Nov-06 19:45 
GeneralArticle superceeded PinmemberRoger Allen29-Jan-03 1:56 
GeneralPls suggest similary framework for dynamically load DLL Pinmembersanong28-Jan-03 17:53 
GeneralRe: Pls suggest similary framework for dynamically load DLL PinmemberRoger Allen29-Jan-03 1:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 16 Nov 2001
Article Copyright 2001 by Roger Allen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid