Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am writing an MFC SDI explorer style application.

I have moved the ON_COMMAND(ID_FILE_OPEN, &CMyView::OnFileOpen)
to CMyView from CMyApp as this is where I want to handle this.

However, the first time I use the menu to select file->open, the 'open' option is greyed out. The next time I open the file menu, open is not greyed out and the message is routed fine.

Does anyone have any idea why this is happening?

Many thanks
Posted

Hi, i think you know that in mfc, The menu items will be in disabled state if you wont handle ON_COMMAND of that item.Now coming to your case, When you moved the ON_COMMAND(ID_FILE_OPEN, &CMyView::OnFileOpen) from CMyApp and first time CMyView is not the active window, so the Menu item is in disabled state. I think it is not the second time the item is enabled but it is when you clicked on MyView(I guess it is Right view).To simulate this situation you click again on left view then again menu item will go to disable state.
 
Share this answer
 
Comments
Jackie Lloyd 29-Mar-11 7:24am    
Yes, you are right, that is exactly what happens.
Is there a correct way to make my file->open menu item be selectable whichever view I click in?
Very many thanks!
At this moment i have only one idea,
handle ON_COMMAND(ID_FILE_NEW, onFileOpen) in CChildFrame class.In onFileOpen() function you send your own message to CMyView window.Replay if you have any doubts.

Olivier Levrey 29-Mar-11 7:37am    
Good catch. My 5.
Thank You
Jackie Lloyd 29-Mar-11 8:40am    
Thankyou.
When you say 'send your own message to CMyView window', do you mean I just make a call from CChildFrame::OnFileOpen() to CMyView::OnFileOpen(), or do i actually create a message which is caught by the ON_COMMAND. If so, how do I do it please?
Is there a correct way to make my file->open menu item be selectable whichever view I click in?

You can use the ON_UPDATE_COMMAND_UI macro to update your menu item state:

C++
BEGIN_MESSAGE_MAP(CYourView, ...)
    ON_UPDATE_COMMAND_UI(YOUR_MENU_ITEM_ID, OnUpdateYourCommand)
END_MESSAGE_MAP()
...

void CYourView::OnUpdateYourCommand(CCmdUI* pCmdUI)
{
    //always enable the menu item
    pCmdUI->Enable(TRUE);
}


But for opening files, it is better to:
- let your CWinApp derived class handle the ID_FILE_OPEN message.
- you may optionnaly override the CDocument::OnOpenDocument method to open the file manually.
- store all necessary data in your CDocument derived class.
- after the file is loaded, call UpdateAllViews.
- override OnUpdate method in your CView derived class to retrieve data from the CDocument object.

--------

Just add members in your document class. For example:
In your .h file:
C++
class CYourDocument : public CDocument
{
public:
     //this function returns the view title
     LPCTSTR GetViewTitle() const { return m_viewTitle; }

protected:
   ...
   //the member variable which will hold the title for your view
   CString m_viewTitle;

   //load the file and store the data in this function
   virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
};


In your .cpp file:
C++
virtual BOOL CYourDocument::OnOpenDocument(LPCTSTR lpszPathName);
{
    //load the file
    ...
    //set the view title with the file name (for example)
    m_viewTitle = lpszPathName;
    //refresh all views
    UpdateAllViews();
    return TRUE;
}


Then in your CView .h file:
C++
class CYourView : public CView
{
protected:
    virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
};


And in your CView .cpp file:
C++
void CYourView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
    //get the data from the document class
    CYourDocument* pDoc = (CYourDocument*)GetDocument();
    SetWindowText(pDoc->GetViewTitle());
}
 
Share this answer
 
v2
Comments
Jackie Lloyd 29-Mar-11 9:14am    
I tried you first suggestion, I put the following code into myView.cpp

BEGIN_MESSAGE_MAP(CMyView, CRichEditView)
ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, OnUpdateFileOpen)
END_MESSAGE_MAP()

void CBWE8View::OnUpdateFileOpen(CCmdUI* pCmdUI)
{
//always enable the menu item
pCmdUI->Enable(TRUE);
}
and also added this to MyView.h
afx_msg void OnUpdateFileOpen(CCmdUI* pCmdUI);

but this doesn't help as the OnUpdateFileOpen() only gets called if MyView is active. Should I put the above code somewhere else? Or what am i doing wrong?
Olivier Levrey 29-Mar-11 9:25am    
Well I think this will work only for the active view as you already observed... I suggest you to use the second option: open the document class and call UpdateAllViews to refresh the views content.
Jackie Lloyd 29-Mar-11 9:37am    
Yes, I think you are right, the second option is better.
How do i store the data in my CDocument derived class? I was doing this to update view:
pView->SetWindowText(lpszData)
Olivier Levrey 29-Mar-11 10:00am    
I updated my answer to make it more readable...
Jackie Lloyd 29-Mar-11 12:39pm    
I did get it to work, so very many thanks. Although i am not sure if i should have had to read the contents of the file into m_lpszDisplayData and call CMyView::SetWindowText(m_lpszDisplayData) in order to display it (it does work tho). Should the calls to SetPathName() and then UpdateAllViews(), as shown below do this without having to do SetWindowText?

BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
.............
m_lpszDisplayData = (LPCTSTR)s;//member of CMyDoc
SetPathName(lpszPathName);
UpdateAllViews(NULL); //should this update view
return TRUE;
}




void CMyView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
//get the data from the document class
CMyDoc* pDoc = (CMyDoc*)GetDocument();

m_bInitialUpdate;
if(!m_bInitialUpdate)
{
//gets CMyDoc::m_lpszDisplayData
SetWindowText(pDoc->GetDisplayData());//is this necessary?
}
//SetWindowText(pDoc->GetViewTitle());
m_bInitialUpdate = false;
}

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900