Steps to Reproduce Behavior
- Using Visual C++ 6.0, create a new MFC AppWizard (exe0 project named MdiAdxPrb.
- Select Multiple documents in step 1, and click Next twice.
- Select Container, check Active document container, then click Finish.
- Compile and run the project.
- From the Insert menu drop down box, choose Object, and insert a Microsoft Excel Worksheet.
- From the File menu, select New.
- From the Insert menu drop down box, choose Object again and insert another Microsoft Excel Worksheet.
- Note that if you choose a menu option from the newly-merged Microsoft Excel menus, such as Format|Cells, it responds appropriately.
- Now, click from this MDI child window back to the first one, and try selecting the same menu item.
The result is that either the menu does not work, or it causes a crash.
Steps to Work Around Behavior
- Using the first three steps from the section above, build an MDI ActiveX Document container.
- Open MdiAdxPrbView.h and add the following member variable and function declaration to the top of the CMdiAdxPrbView class:
int m_viewID; // view id...
LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
- Open MdiAdxPrbView.cpp, and add the following global variables just before the CMdiAdxPrbView constructor:
int g_nextViewID = 1;
int g_activeViewID = 0;
- In the CMdiAdxPrbView constructor, add the following lines of code:
m_viewID = g_nextViewID;
g_nextViewID++;
g_activeViewID = m_viewID;
- In MdiAdxPrbView.cpp, add the following line to your CMdiAdxPrbView message map:
ON_MESSAGE(WM_APP+1, OnMyMessage)
- Hit the CTRL+W keys to bring up the ClassWizard, and add a handler for OnActivateView in your CMdiAdxPrbView class.
- Add the following lines of code to the end of the implementation in OnActivateView():
if (bActivate && m_pSelection) {
if (m_viewID != g_activeViewID) {
g_activeViewID = m_viewID;
PostMessage(WM_APP+1);
}
}
- Add the following function to the end of your MdiAdxPrbView.cpp file:
LRESULT CMdiAdxPrbView::OnMyMessage(WPARAM wParam, LPARAM lParam) {
if (m_pSelection) {
m_pSelection->Deactivate();
m_pSelection->Activate(OLEIVERB_UIACTIVATE, this);
}
return 0;
}
- Compile and Run.
The code basically overrides OnActivateView() to be notified whenever a view is activated, and de-activates and re-activates any active server in that view if it has not already been activated. You have to post a message from OnActivateView() because the calls De-activate and Activate you want to make are not allowed in a synchronous context.