Click here to Skip to main content
11,704,768 members (60,492 online)
Rate this: bad
good
Please Sign up or sign in to vote.
See more: MFC VC++
I created MDI Template like Following
CMultiDocTemplate* pRunTemplate;
 
                pRunTemplate = new CMultiDocTemplate(IDR_MerilisaRTYPE,
		RUNTIME_CLASS(CMerilisaRDoc),
		RUNTIME_CLASS(CChildFrame), // custom MDI child frame
		RUNTIME_CLASS(CRunView));
	if (!pRunTemplate)
		return FALSE;
	AddDocTemplate(pRunTemplate);
I am opening view on toolbar button click
ON_COMMAND(ID_RUNVIEW, &CMerilisaRApp::OnRunview)
 
 void CMerilisaRApp::OnRunview()
   {
	this->pRunTemplate->OpenDocumentFile(NULL,1);
   }
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
Edited 17-Sep-12 4:44am
v2
Comments
Richard MacCutchan at 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 at 17-Sep-12 12:11pm
   
Yah it seems to be very nice solution , I will surely try it Tomorrow

1 solution

Rate this: bad
good
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:
ON_UPDATE_COMMAND_UI(ID_RUNVIEW, OnUpdateRunview)
  Permalink  
Comments
adityarao31 at 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 at 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 at 17-Sep-12 12:14pm
   
Yes It is perfectly good solution,Thank you very much.
adityarao31 at 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 at 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(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 at 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 at 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()
{
protected:
int m_nType;
public:
inline int GetType() const { return m_nType; }
}
class CView1 : public CBaseView ...
And in the constructor of your derived view classes
CView1::CView1()
{
m_nType = VIEW1;
}
adityarao31 at 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 at 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 at 17-Sep-12 13:00pm
   
Yah thats the way,
Jochen Arndt at 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 at 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 at 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 at 17-Sep-12 13:14pm
   
Yah its much better solution ,than creating intermediate class,Isn't it?
I liked it more.
Jochen Arndt at 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 at 17-Sep-12 13:19pm
   
:)
adityarao31 at 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
0 Sergey Alexandrovich Kryukov 679
1 OriginalGriff 460
2 CPallini 242
3 Andy Lanng 235
4 F-ES Sitecore 160
0 OriginalGriff 8,864
1 Sergey Alexandrovich Kryukov 8,245
2 CPallini 5,189
3 Maciej Los 4,726
4 Mika Wendelius 3,606


Advertise | Privacy | Mobile
Web03 | 2.8.150819.1 | Last Updated 17 Sep 2012
Copyright © CodeProject, 1999-2015
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