CRichEditView/CRichEditDoc Bug Work-Around

The Problem

This article details a bug found with using a CRichEditDoc in conjunction with several views and was inspired by Dark Mage in one of his posts. He was attempting to use a CRichEditView in a splitter window in an “explorer” type of the application.

My theory is that this bug affects anyone who is attempting to use multiple views (with at least one of them being derived from CRichEditView) and a CRichEditDoc-derived document class.

The problem is that when any view other than the CRichEditView is activated and the Edit menu is selected, an Assert is thrown! When you select the Edit menu, the system routes the CommandUI updates before the menu is displayed. The MFC framework then calls the document to update the command for the name of the OLE object embedded in the document and the Verb submenu accessed from this object command. (The Verb submenu contains all the verb commands available for the object.) This in turn results in the calling of the GetPrimarySelectedItem function to retrieve the currently selected OLE item in the specified view. Here’s the crux of the problem. The CRichEditDoc just takes for granted that the only view it is dealing with is a CRichEditView-derived view (which is not necessarily true!).

Fortunately, the GetPrimarySelectedItem function is virtual, and it can be overridden. However, because this function is not on the available list of virtual functions in Class Wizard, you must “manually” insert the function into your code.

The Solution

In your document class’ include file, declare (insert) the following member function override.

virtual COleClientItem* GetPrimarySelectedItem(CView* pView);

Now, in your implementation file, insert the following:

COleClientItem* CYourRichEditDoc::GetPrimarySelectedItem(CView *pView)
{
  if(!pView->IsKindOf(RUNTIME_CLASS(CRichEditView)))
    // CRichEditDoc's implementation asserts here
    // we just stop processing since the active view is not
    // a CRichEditView class
    return NULL;

  return ((CRichEditView*)pView)->GetSelectedItem();
}

Summary

This fixes the bug. I have tested this fix for MDI, SDI, for multiple views and swappable views embedded in a dialog and so far it works in all those scenarios. If you find any problem related to the above, please send me e-mail. I am trying to find out whether this is a known bug (feature) and have contacted Microsoft. Hopefully, I will get an answer to this soon.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read