Link to home
Start Free TrialLog in
Avatar of myokoy03
myokoy03

asked on

Merging CRichEdit and CView

I am trying to merge the best methods coming from two editor programs.  One editor has the class structure defined as follows:

class A : public CRichEditView

And the other editor has the class defined as follows.

class B : public CView

Both of these classes have cursor movement methods.

The question is how to create a ?class structure? that will allow me to combine the two programs together.

One method I tried that does not work is to rename all instances of Class A to Class B for example, to rename all of

A::ThisMethod();

to functions that correspond to:

B::ThisMethod();

This methodology did not work because many of the window-handling interface to MS-Windows have different parameters in CView as opposed to CRichEdit, and the resulting program, when compiled, does not run.

I thought it would work since A and B have common ancestor classes, but some of the afx_nnnn functions differ in terms of parameter numbers between CRichEdit and CView, and it didn't work.

This might be a fundamental C++ question and may even go to the heart of why C++ is popular in the first place, but can anybody with experience of CRichEdit and CView tell me how to make one program that does the best of the two programs?
Avatar of bertp
bertp

Do you instead mean CEditView and CRichEditView?

CRichEditView is a decendant of CView so CView methods are available from a CRichEditView.  And ofcourse, you can get access to the CRichEditView's member rich edit control and directly access those methods if need to..
Avatar of myokoy03

ASKER

Class B is declared as follows:

class B : public CView

Do you propose that I rewrite the code implemented as part of the CView class to be CRichEditView code?

I tried to do that by globally renaming CView to CRichEditView.  It didn't work, however, and I am too new to C++ to know why not.

Please let me know explicitly what I need to do to convert the set of methods written for the CView class to CRichEditView.

Thanks for all your help!
well, in the general case, methods which work in a CView class should work in a CRichEditView class since CRichEditView inherits functionality from CView..  

CRichEdit controls have a lot of functionality; my *instinct* is that it is likely that most of the CView editor's implemented functionality is probably natively supported in the CRichEditView class..  Could you give me some information about the functions you tried to move from CView to CRichEditView?
Does that mean I can just combine the 2 programs and it would work without changing CView to CRichEditView?  Or do I need to change all occurrences of CView to CRichEditView?  That is what I tried to do....
Here are the resuls on Find in Files...

Searching for 'CView'...
1.cpp(42):IMPLEMENT_DYNCREATE(CSV, CView)
1.cpp(46):BEGIN_MESSAGE_MAP(CSV, CView)
1.cpp(103):   ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
1.cpp(104):   ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
1.cpp(105):   ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
1.cpp(153):   AFX_ZERO_INIT_OBJECT(CView);
1.cpp(181):   return CView::PreCreateWindow(cs);
1.cpp(927):         return CView::GetFont();
1.cpp(992):   CView::OnInitialUpdate();
1.cpp(1033):   CView::OnPrepareDC(pDC, pInfo);
1.cpp(1344):   CView::OnDestroy();
1.cpp(1369):   CView::OnSize(nType, cx, cy);
1.cpp(1480):   CView::OnVScroll(nSBCode, nPos, pScrollBar);
1.cpp(1561):   CView::OnHScroll(nSBCode, nPos, pScrollBar);
1.cpp(1634):   return CView::OnSetCursor(pWnd, nHitTest, message);
1.cpp(1769):   CView::OnSetFocus(pOldWnd);
1.cpp(1876):   CView::OnKillFocus(pNewWnd);
1.cpp(1892):   CView::OnSysColorChange();
1.cpp(2039):   if (CView::OnCreate(lpCreateStruct) == RESERVED)
1.cpp(2069):   return CView::PreTranslateMessage(pMsg);
1.h(54):class EOLEDIT_CLASS_DECL CSV : public CView
2.cpp(416):   CView::OnLButtonDown(nFlags, point);
2.cpp(518):   CView::OnMouseMove(nFlags, point);
2.cpp(626):   CView::OnLButtonUp(nFlags, point);
2.cpp(721):   CView::OnTimer(nIDEvent);
2.cpp(802):   CView::OnLButtonDblClk(nFlags, point);
2.cpp(871):   CView::OnRButtonDown(nFlags, point);
27 occurrence(s) have been found.
Some problems when I change CView to CRichEditView:

1.  The GetClipboardData() method has too few parameters now.

2.  The return from AfxRegisterWndClass() is not NULL now, and this is caught in PreCreateWindow().
Concerning GetClipboardData():
Maybe the CView editor was using the SDK GetClipBoardData() function.  You can (but not necessarily should ;-)) call this from within the CRichEditView by using the scope operator;  ::GetClipBoardData().

There might be a way to use mutiple inheritance to inherit the capabilities from both editors but I would guess that route would be more trouble than it is worth...if it is even possible using MFC objects...

I would be inclined to study and understand how both programs are implemented so that I could judiciously choose which methods from each programm to include or reimplement....

 Sorry I can't give you a better answer; maybe someone with a bit more insight into your problem will chime-in


Good Luck!
Bert


I commented out that code and now the program cannot run to completion because every time OnFileNew is called, it has a dialog box "Failed to create empty document", and the debugger says "Can't register window class named Afx 40000:`50b07aeb".

Then when traced into the library, in c:\...\Vc98\Mfc\Src\Winmdi.cpp the program aborts in the following function:

BOOL CMDIChildWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
            CWnd* pParentWnd, CCreateContext* pContext)
{
      // only do this once
      ASSERT_VALID_IDR(nIDResource);
      ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);
      ASSERT(m_hMenuShared == NULL);      // only do once

      m_nIDHelp = nIDResource;    // ID for help context (+HID_BASE_RESOURCE)

      // parent must be MDI Frame (or NULL for default)
      ASSERT(pParentWnd == NULL || pParentWnd->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)));
      // will be a child of MDIClient
      ASSERT(!(dwDefaultStyle & WS_POPUP));
      dwDefaultStyle |= WS_CHILD;

      // if available - get MDI child menus from doc template
      ASSERT(m_hMenuShared == NULL);      // only do once
      CMultiDocTemplate* pTemplate;
      if (pContext != NULL &&
            (pTemplate = (CMultiDocTemplate*)pContext->m_pNewDocTemplate) != NULL)
      {
            ASSERT_KINDOF(CMultiDocTemplate, pTemplate);
            // get shared menu from doc template
            m_hMenuShared = pTemplate->m_hMenuShared;
            m_hAccelTable = pTemplate->m_hAccelTable;
      }
      else
      {
            TRACE0("Warning: no shared menu/acceltable for MDI Child window.\n");
                  // if this happens, programmer must load these manually
      }

      CString strFullString, strTitle;
      if (strFullString.LoadString(nIDResource))
            AfxExtractSubString(strTitle, strFullString, 0);    // first sub-string

      ASSERT(m_hWnd == NULL);
      if (!Create(GetIconWndClass(dwDefaultStyle, nIDResource),
        strTitle, dwDefaultStyle, rectDefault,
        (CMDIFrameWnd*)pParentWnd, pContext))
      {
***HERE*** (Call to Create(GetIconWndClass)) fails.
            return FALSE;   // will self destruct on failure normally
      }

      // it worked !
      return TRUE;
}
Forgive me for stating the obivious, but *if* the Create() that fails is depending on the windows class that was not registered, then we should expect the Create() function to fail.
 
 It might be easier reimplementing the desired functionality with a CRichEditView..I have used the CRichEditView for a couple of quick and dirty applications. Functions for loading and saving documents, moving the cursor and replacing selected text were nearly painless... here is link to a site with lots of step-by-step instruction on customizing rich text controls and views; http://www.codeguru.com/richedit/index.shtml

HTH
Bert
 

 

"Forgive me for stating the obivious, but *if* the Create() that fails is depending on the windows class that was not registered, then we should expect the Create() function to fail."

Forgive me for asking the obvious, but, how do you register the windows class and why?
ASKER CERTIFIED SOLUTION
Avatar of bertp
bertp

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Adjusted points from 50 to 100
I threw away the code after my Monday, April 10 2000 - 08:21PM PDT comment...

1.  I took your advice on the GetClipboardData() method, and the program compiles without errors now.  Thanks, it really works...

2.  The return from AfxRegisterWndClass() is still not NULL:

    cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW |
        CS_SAVEBITS | CS_VREDRAW,
        AfxGetApp()->LoadStandardCursor(IDC_ARROW),
        (HBRUSH) (COLOR_WINDOW + 1),
        AfxGetApp()->LoadStandardIcon(IDI_WINLOGO));
   cs.lpszClass = 0;  //kludge

I zero it out in the last statement and now the program runs without crashing.  So it means my AfxRegisterWndClass() needs to return NULL.  Right now, I type in the richedit box and the cursor is funny.... it moves too far to the right and keeps moving to the right.  And if I move the mouse to the right of the richedit box, it starts to redraw in a haphazard way.  Then if I type short phrases followed by carriage returns, the phrases all get concatenated into one line at the top of the rich edit box.  If I click the mouse on the end of the "now imaginary" lines, the mouse will position the cursor somewhere near the end of the text, and then pressing the left arrow will make the cursor move back, in a stepladder function, through these "invisible" text characters, as if the cursor actually followed them even though the richedit box did not update the box.

Finally, pressing CTRL-HOME and CTRL-END places the cursor not at character location 1 of the rich edit box.  (The editor code I have, though, has a margin where text marks go and this margin does not show up yet.

Mike


Bertp's willingness to go for completion in this case are greatly appreciated.

Bertp's comments have taken *most* of the mystery out of my undertaking and have simplified things for me greatly.

Thanks to Experts-Exchange and Bertp....

Mike