Click here to Skip to main content
13,052,956 members (72,957 online)
Rate this:
Please Sign up or sign in to vote.
See more:
I created MDI Template like Following
CMultiDocTemplate* pRunTemplate;
                pRunTemplate = new CMultiDocTemplate(IDR_MerilisaRTYPE,
		RUNTIME_CLASS(CChildFrame), // custom MDI child frame
	if (!pRunTemplate)
		return FALSE;

I am opening view on toolbar button click
ON_COMMAND(ID_RUNVIEW, &CMerilisaRApp::OnRunview)
 void CMerilisaRApp::OnRunview()

But problem is that as many times I click toolbar button that many times view opens and I want to open view only ones.So how to find out that view is already opened?
Posted 17-Sep-12 4:41am
Updated 17-Sep-12 4:44am
Richard MacCutchan 17-Sep-12 11:12am
When you have opened the view set the menu item and/or toolbar to the disabled state so it cannot be selected again. Then when you close the view you can re-enable the toolbar item.
adityarao31 17-Sep-12 12:11pm
Yah it seems to be very nice solution , I will surely try it Tomorrow

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

You can iterate through your templates, documents, and views:
// Get the position of the first document template in the app
POSITION posTmpl = GetFirstDocTemplatePosition();	
while (posTmpl)
    // Get the first document template.
    CDocTemplate *pTmpl = GetNextDocTemplate(posTmpl);
    if (pTmpl)
        // Get the position of the first document associated with the template
        POSITION posDoc = pTmpl->GetFirstDocPosition();
        while (posDos)
            CDocument *pDoc = tmpl->GetNextDoc(posDos);
            if (pDoc)
                // Get the position of the first view for the document
                POSITION posView = pDoc->GetFirstViewPosition();
                while (posView)
                    CView *pView = pDoc->GetNextView(posView);

If you have only one template, you may remove the outer loop and use your pRunTemplate. If you have only one view per document, the innermost while condition can be replaced by an if condition.

The check if a view is already opened depends on your document/view organization. If no file is opened by your app, there is no document for the template. If a file is opened, you may compare the name using CDocument::GetPathName(). You may also check special state members of your document and view classes by casting the GetNext...() return values to your derived classes.

Finally you can put the check into an ID_RUNVIEW update handler. Then the command is disabled when the check fails indiacting this to the user:
adityarao31 17-Sep-12 12:05pm
Dear Sir, I have One Doc class ,but five templates with Five CFormView classes,In that case outer loop is applicable so CFormView *pFView = pDoc->GetNextView(posView); sentence I will write,I will get CFormView class pointer,but how I will know that Is it already Opened or not ?
Jochen Arndt 17-Sep-12 12:12pm
If you get a pointer to a view, the view exists. Views that are actually not opened are not enumerated (because there is actually no instance of the view in memory).
adityarao31 17-Sep-12 12:14pm
Yes It is perfectly good solution,Thank you very much.
adityarao31 17-Sep-12 12:19pm
One more doubt I have Five CFormView derived classes linked with single document
How I can know which view is currently opened,as Code above just seems to give CFormView pointer, How can I find which one is open ?
Jochen Arndt 17-Sep-12 12:41pm
You can do this by comparing the enumerated template pointer with those pointers stored when creating the templates (this requires that you store the pointers).

If you have a basic view class derived (e.g. CFormView -> CBaseView -> CView1, CView2, ...) you may add a member var to that class identifying the view/template type and check it using a cast for the enumerated view:
CBaseView *pView = static_cast<CBaseView*>(pDoc->GetNextViewPosition(posView));
if (pView->GetType() == VIEW1) ...

There are other solutions like tracking the views in the document class, using the title of the view and so on.
adityarao31 17-Sep-12 12:45pm
Yah,that means I have to add GetType Function to all Derived Views,yah thats nice idea. Thank you once more.
Jochen Arndt 17-Sep-12 12:51pm
Note that you need an intermediate class as described. You can't cast different views even if all have such a member function:
class CBaseView public CFormView()
int m_nType;
inline int GetType() const { return m_nType; }
class CView1 : public CBaseView ...
And in the constructor of your derived view classes
m_nType = VIEW1;
adityarao31 17-Sep-12 12:54pm
If that is the case then I need to do rework of deleting existing classes and adding new ones.yah I have to do it,Thanks Friend
Jochen Arndt 17-Sep-12 12:57pm
Don't delete the existing classes. Just create the intermediate class, include it's header file in the headers of your view classes and replace all occurences of CFormView by CBaseView in hedaer and source files of your view classes.
adityarao31 17-Sep-12 13:00pm
Yah thats the way,
Jochen Arndt 17-Sep-12 13:03pm
There's another solution if your views are dynamic (e.g. DECLARE_DYNCREATE(CView1)):
Then you may use pView->IsKindOf(RUNTIME_CLASS(CView1)) to get the view type.
adityarao31 17-Sep-12 13:06pm
Yah that I need to check in office Tomorrow,but will you please brief me,After selecting which options views become dynamic ?
Jochen Arndt 17-Sep-12 13:11pm
If you have a line with DECLARE_DYNCREATE() or DECLARE_DYNAMIC() in your view header files and a corresponding line IMPLEMENT_DYNCREATE / IMPLEMENT_DYNAMIC in the source files. E.g:
DECLARE_DYNCREATE(CView1) in the header file,
IMPLEMENT_DYNCREATE(CView1, CFormView) in the cpp file.
These are usually already present when creating view classes with the VS class wizard.
adityarao31 17-Sep-12 13:14pm
Yah its much better solution ,than creating intermediate class,Isn't it?
I liked it more.
Jochen Arndt 17-Sep-12 13:18pm
It's simple to implement and use. C++ purists don't like it. But Microsoft uses it often in the MFC.
adityarao31 17-Sep-12 13:19pm
adityarao31 17-Sep-12 13:20pm
Ok it was very nice talking with you,I really think you have answered my question very well

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

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Mobile
Web02 | 2.8.170713.1 | Last Updated 17 Sep 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100