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?
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?
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!
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?
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?
ASKER
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....
ASKER
Here are the resuls on Find in Files...
Searching for 'CView'...
1.cpp(42):IMPLEMENT_DYNCRE ATE(CSV, CView)
1.cpp(46):BEGIN_MESSAGE_MA P(CSV, CView)
1.cpp(103): ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
1.cpp(104): ON_COMMAND(ID_FILE_PRINT_D IRECT, CView::OnFilePrint)
1.cpp(105): ON_COMMAND(ID_FILE_PRINT_P REVIEW, 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(lpCreateS truct) == RESERVED)
1.cpp(2069): return CView::PreTranslateMessage (pMsg);
1.h(54):class EOLEDIT_CLASS_DECL CSV : public CView
2.cpp(416): CView::OnLButtonDown(nFlag s, 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(nFl ags, point);
2.cpp(871): CView::OnRButtonDown(nFlag s, point);
27 occurrence(s) have been found.
Searching for 'CView'...
1.cpp(42):IMPLEMENT_DYNCRE
1.cpp(46):BEGIN_MESSAGE_MA
1.cpp(103): ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
1.cpp(104): ON_COMMAND(ID_FILE_PRINT_D
1.cpp(105): ON_COMMAND(ID_FILE_PRINT_P
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(lpCreateS
1.cpp(2069): return CView::PreTranslateMessage
1.h(54):class EOLEDIT_CLASS_DECL CSV : public CView
2.cpp(416): CView::OnLButtonDown(nFlag
2.cpp(518): CView::OnMouseMove(nFlags,
2.cpp(626): CView::OnLButtonUp(nFlags,
2.cpp(721): CView::OnTimer(nIDEvent);
2.cpp(802): CView::OnLButtonDblClk(nFl
2.cpp(871): CView::OnRButtonDown(nFlag
27 occurrence(s) have been found.
ASKER
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().
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
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
ASKER
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(UI NT nIDResource, DWORD dwDefaultStyle,
CWnd* pParentWnd, CCreateContext* pContext)
{
// only do this once
ASSERT_VALID_IDR(nIDResour ce);
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(RUNTI ME_CLASS(C MDIFrameWn d)));
// 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*)pConte xt->m_pNew DocTemplat e) != NULL)
{
ASSERT_KINDOF(CMultiDocTem plate, 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( nIDResourc e))
AfxExtractSubString(strTit le, strFullString, 0); // first sub-string
ASSERT(m_hWnd == NULL);
if (!Create(GetIconWndClass(d wDefaultSt yle, 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;
}
Then when traced into the library, in c:\...\Vc98\Mfc\Src\Winmdi
BOOL CMDIChildWnd::LoadFrame(UI
CWnd* pParentWnd, CCreateContext* pContext)
{
// only do this once
ASSERT_VALID_IDR(nIDResour
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(RUNTI
// 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*)pConte
{
ASSERT_KINDOF(CMultiDocTem
// 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(
AfxExtractSubString(strTit
ASSERT(m_hWnd == NULL);
if (!Create(GetIconWndClass(d
strTitle, dwDefaultStyle, rectDefault,
(CMDIFrameWnd*)pParentWnd,
{
***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
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
ASKER
"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?
Forgive me for asking the obvious, but, how do you register the windows class and why?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Adjusted points from 50 to 100
ASKER
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_DBL CLKS | CS_HREDRAW |
CS_SAVEBITS | CS_VREDRAW,
AfxGetApp()->LoadStandardC ursor(IDC_ ARROW),
(HBRUSH) (COLOR_WINDOW + 1),
AfxGetApp()->LoadStandardI con(IDI_WI NLOGO));
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
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_DBL
CS_SAVEBITS | CS_VREDRAW,
AfxGetApp()->LoadStandardC
(HBRUSH) (COLOR_WINDOW + 1),
AfxGetApp()->LoadStandardI
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
ASKER
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
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
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..