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.



About the Author

John Z. Czopowik VC++ MVP

Microsoft VC++ MVP

Comments

  • a question

    Posted by Legacy on 10/26/2003 12:00am

    Originally posted by: lotus

    how to work with two CRichEditView-Drivied view and tow CRichEditDoc-Drivied Doc?

    Reply
  • Using 2 CRichEditViews with 1 CRichEditDoc

    Posted by Legacy on 01/17/2002 12:00am

    Originally posted by: Dand

    I'm attempting to use a splitter type application that has 2 CRichEditViews pointing to the same CRichEditDoc. This was all fine and well until I tried embedding objects in one or both of the views. The problem seems to be similar to the above bug except that this fix does not address the case where more then one of the multiple views happens to be another CRichEditView.

    From looking at the code, it appears that CRichDocument::GetView() makes a similiar assumption in that the first view it finds of type CRichEditView is the correct one which in fact is not true in this case. I see from the documentation that you are only supposed to use one CRichEditDoc per CRichEditView (apparently, for this reason). But, perhaps someone has a solution or suggestion.

    Thanks,
    Dan

    Reply
  • Help with PrintPreview

    Posted by Legacy on 04/09/2001 12:00am

    Originally posted by: Maria

    I build an application that displays a text file and provides the various print options.
    I have overridden the basic Printing function but within these overridden functions the MFC provided functions are called
    EX.BOOL CPrintView::OnPreparePrinting(CPrintInfo* pInfo)
    {

    // CRichEditCtrl
    SetMargins(CRect(720,720,720,720));
    CSize csPaper = GetPaperSize();
    csPaper.cx=26000;
    SetPaperSize(csPaper);
    //Get the Filename
    char Name[40];
    GetName(Name);
    m_DocTitle=(CString)Name;

    // return CView::OnPreparePrinting(pInfo);
    // default preparation
    return DoPreparePrinting(pInfo);
    }
    However the Print preview doesn't utilize the entire page and comes different to what the actual print out shows
    I have written similar code using CEdit View and it works perfectly.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • The latest release of SugarCRM's flagship product gives users new tools to build extraordinary customer relationships. Read an in-depth analysis of SugarCRM's enhanced ability to help companies execute their customer-facing initiatives from Ovum, a leading technology research firm.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds