Click here to Skip to main content
15,884,388 members
Articles / Desktop Programming / MFC
Article

How to find a doctemplate object given its resource identifier

Rate me:
Please Sign up or sign in to vote.
4.94/5 (12 votes)
29 Oct 20032 min read 54.1K   593   29   6
A useful function to find the doctemplate object by its numeric resource identifier in a MFC application.

Introduction

I have developed some very large applications, with tens of different doctemplate objects. Sometimes in my applications one view must respond to the user selection by opening another document of a different template. Thanks to the CWinApp member functions, we can search among all doctemplates and their open documents but how can we recognize a particular doctemplate?

We could check a string against the string returned by the GetDocString member function of CDocTemplate, but strings may change during the development of the application. The CDocTemplate class has a member variable named m_nIDResource which contains the numeric resource identifier passed to the constructor when the doctemplate object is created. This identifier is used for loading the doctemplate string from the resource, but also for the default menu associated to those documents and the default icon of the frame of the documents. The application knows well the resource identifiers, so they would be perfect for identifying the doctemplates, but the base class CDocTemplate declares the member variable m_nIDResource as protected and does not have any member function to get the value read.

With a little C++ trick, we can extract the desired member variable without being constricted to use a custom CDocTemplate derived class for our doctemplates.

The function(s)

UINT AfxGetDocTemplateId(CDocTemplate* pDocTemplate)
{
    // Helper class to extract the m_nIDResource member
    class CHelperDocTemplate : public CDocTemplate
    {
    public:
        CHelperDocTemplate():CDocTemplate(0, NULL, NULL, NULL){}
        UINT GetResourceId(){return m_nIDResource;}
    };
    return  ((CHelperDocTemplate*)pDocTemplate)->GetResourceId();
}


CDocTemplate* AfxFindDocTemplate(UINT nIDResource)
{
    POSITION pos = AfxGetApp()->GetFirstDocTemplatePosition();
    while ( pos )
    {
        CDocTemplate* pDocTemplate = AfxGetApp()->GetNextDocTemplate(pos);
        if ( AfxGetDocTemplateId(pDocTemplate) == nIDResource )
            return pDocTemplate;
    }
    return NULL; // Not found
}

Notice that the helper class is declared in the function body, i.e. it is a local class. In this way, it does not clutter the namespace of the application. The helper class must declare a constructor because CDocTemplate does not have a default constructor. Finally a static member function in the class cannot access the protected member variables of the base class, so a non static member function and the cast are needed.

Using the code

I named the function like the MFC global functions because it really is a little function which is missing from MFC ones. Because it is a global function, you can use it anywhere in the program, just include the header file and add the implementation file to the project. I usually include such a header at the end of the StdAfx.h file and don't think to it anymore.

So just grab it and mail me know if you appreciated it!

History

  • Submitted 29 October 2003

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralNice solution. Pin
rtischer827719-May-11 10:39
rtischer827719-May-11 10:39 
GeneralVery Nice Pin
aaronmhawkins21-Jan-08 17:29
aaronmhawkins21-Jan-08 17:29 
AnswerRe: Very Nice Pin
visualc30-Jan-08 2:52
visualc30-Jan-08 2:52 
GeneralRe: Very Nice Pin
aaronmhawkins30-Jan-08 5:36
aaronmhawkins30-Jan-08 5:36 
GeneralExactly what I needed Pin
Rolando Cruz4-Nov-03 4:52
Rolando Cruz4-Nov-03 4:52 
GeneralNice trick ! Pin
Emilio Garavaglia29-Oct-03 23:55
Emilio Garavaglia29-Oct-03 23:55 

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

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