Solved

C++/MFC: Adding text to CRichEditView?

Posted on 2001-06-12
5
1,745 Views
Last Modified: 2013-11-20
I am completely new to MFC programming ... having written several 100's of applications in Delphi; the method for creating MFC applications under Visual C++ 5.0 is confusing me.

I'm trying to write a simple application which uses a RichEdit control to display status from another thread.
I want to use a the CRichEditView to allow me to display the status in color... then save it to a RTF file so I can be examined later.

I've only been at the MFC programming for a few hours; but I'm not sure how to best proceed.

I have a menu (for testing) which executes the following function:
void CMainFrame::OnTestSendstring()
{
     CRichMFCView* ActiveView;
     //CRichMFCView* GetActiveView()
     ActiveView = (CRichMFCView*) GetActiveView();

     
     //ActiveView.StreamIn();
}

Obviously I'm not sure what I'm doing... but the ide is a click on the Test menu and Send String option and the end result is a string appears in the current active view.

I was thinking the StreamIn() member function would do this for me... but it seems like overkill.

Seems like this should be a super simple thing to do.

If i were writing this in Delphi, I'd be done already.
0
Comment
Question by:zitt
  • 3
5 Comments
 
LVL 2

Expert Comment

by:GloriousRain
Comment Utility
Hi zitt,
If you want to put a text in the current active view, you have to override OnDraw function of CRichMFCView and use CDC::TextOut to do.
ex:
void CRichMFCView::OnDraw(CDC* pDC)
{
     CRichMFCDoc* pDoc = GetDocument();
     ASSERT_VALID(pDoc);
        pDC->TextOut(0,0, "Your text");
}

To override OnDraw function right click in CRichMFCView in workspace view->select Add virtual function..->one popup window appears->select Add Handler for OnDraw in "New Virtual Functions" list  
0
 
LVL 2

Accepted Solution

by:
GloriousRain earned 50 total points
Comment Utility
CRichEditCtrl::StreamIn, CRichEditCtrl::StreamOut use to
write/read the contents of CRichEditCtrl object to/from the specified output stream
Example of StreamIn
<MSDN>
Example

// My callback procedure that writes the rich edit control contents
// to a file.
static DWORD CALLBACK
MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
   CFile* pFile = (CFile*) dwCookie;

   *pcb = pFile->Read(pbBuff, cb);

   return 0;
}

// The example code.
   // The pointer to my rich edit control.
   extern CRichEditCtrl* pmyRichEditCtrl;
   // The file from which to load the contents of the rich edit control.
   CFile cFile(TEXT("myfile.rtf"), CFile::modeRead);
   EDITSTREAM es;

   es.dwCookie = (DWORD) &cFile;
   es.pfnCallback = MyStreamInCallback;
   pmyRichEditCtrl->StreamIn(SF_RTF, es);

<MSDN>

Example of StreamOut
<MSDN>
Example

// My callback procedure that reads the rich edit control contents
// from a file.
static DWORD CALLBACK
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
   CFile* pFile = (CFile*) dwCookie;

   pFile->Write(pbBuff, cb);
   *pcb = cb;

   return 0;
}

// The example code.
   // The pointer to my rich edit control.
   extern CRichEditCtrl* pmyRichEditCtrl;
   // The file to store the contents of the rich edit control.
   CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
   EDITSTREAM es;

   es.dwCookie = (DWORD) &cFile;
   es.pfnCallback = MyStreamOutCallback;
   pmyRichEditCtrl->StreamOut(SF_RTF, es);
<MSDN>
0
 

Author Comment

by:zitt
Comment Utility
GloriousRain,

OK. I like your second example; however, can you help me figure out how I get the current view from outside the scope? I will need to send data to the view using a scope outside of all of these classes.

Let's say I have 4 RichEditView's open... How do I ensure I'm sending to the current active view?

Further, do I have to use a CFile? I will be sending text to 1 of 4 windows using a simple TCHAR buffer. I don't want to create a text file to send data to the control.

John
0
 
LVL 2

Expert Comment

by:GloriousRain
Comment Utility
"how I get the current view from
outside the scope? I will need to send data to the view using a scope outside of all of these classes.

Let's say I have 4 RichEditView's open... How do I ensure I'm sending to the current active view?"
->
I'd like to show you a general solution about this

<MSDN>
HOWTO: Get Current CDocument or CView from Anywhere
---------------------
SUMMARY
In a Microsoft Foundation Classes (MFC) Windows-based application, it is often useful to be able to get a pointer to the currently active document or view from anywhere in the program. For example, being able to access the current document from a dialog box is sometimes useful. This article discusses the simplest methods for doing so, using the relationships between MFC objects, and basic MFC architecture.

MORE INFORMATION
One of the cases where you might need a pointer to the currently active view or document is in a modal or modeless dialog box. Generally, a dialog box should be created by the view class, because the view is what deals with the application's user interface.

Because the view class is creating the dialog box, it can pass a pointer to itself, or the active document [obtained with the GetActiveDocument() function] to the dialog box. This could be done through the dialog box's constructor or some other member function. For modal dialog boxes, the view could also put data from the dialog box into the document when DoModal() returns.

These methods are generally preferable to relying on generic functions to return pointers to the currently active view or document.

To allow you to get a pointer to the currently active document from anywhere in the program, add a static member function to your CDocument derived class as follows:

Edit the document's header file as follows to add a static member function, GetDoc():


   // Document header file
   class CMyDoc : public CDocument
   {
      ...
      public:
      static CMyDoc * GetDoc();
      ...
   };
For a single document interface (SDI) application, add the following code to your SDI document's implementation file for CMyDoc::GetDoc():

   // SDI document implementation file
   CMyDoc * CMyDoc::GetDoc()
   {
      CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
      return (CMyDoc *) pFrame->GetActiveDocument();
   }
For a multiple document interface (MDI) application, the CMyDoc::GetDoc() code should be the following:

   CMyDoc * CMyDoc::GetDoc()
   {
      CMDIChildWnd * pChild =
          ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();

      if ( !pChild )
          return NULL;

      CDocument * pDoc = pChild->GetActiveDocument();

      if ( !pDoc )
         return NULL;

      // Fail if doc is of wrong kind
      if ( ! pDoc->IsKindOf( RUNTIME_CLASS(CMyDoc) ) )
         return NULL;

      return (CMyDoc *) pDoc;
   }
To allow you to get a pointer to the currently active view from anywhere in the program, add a static member function to your CView derived class as follows:

Edit the view's header file as follows to add a static member function, GetView():

   // View header file
   class CMyView
   {
      ...
      public:
      static CMyView * GetView();
      ...
   };
For an SDI application, add the following code to your SDI view's implementation file for CMyView::GetView():

   // View implementation file
   CMyView * CMyView::GetView()
   {
      CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);

      CView * pView = pFrame->GetActiveView();

      if ( !pView )
         return NULL;

      // Fail if view is of wrong kind
      // (this could occur with splitter windows, or additional
      // views on a single document
      if ( ! pView->IsKindOf( RUNTIME_CLASS(CMyView) ) )
         return NULL;

      return (CMyView *) pView;
   }
For an MDI application, the CMyView::GetView() code should be the following:

   // MDI view implementation file
   CMyView * CMyView::GetView()
   {
      CMDIChildWnd * pChild =
          ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();

      if ( !pChild )
          return NULL;

      CView * pView = pChild->GetActiveView();

      if ( !pView )
         return NULL;

      // Fail if view is of wrong kind
      if ( ! pView->IsKindOf( RUNTIME_CLASS(CMyView) ) )
         return NULL;

      return (CMyView *) pView;
   }
Now, from anywhere in your program, where the document or view header files have been included, you can call:

   CMyDoc::GetDoc();
- Or -

   CMyView::GetView();
to get a pointer to the currently active document or view, respectively. These functions return NULL if there is no active document or view.

Note that a pointer to the application's CDocument or CView derived class is returned, not just a generic CDocument or CView pointer. This allows you to access members specific to your new class. The MDI versions of these functions, and the SDI version of the GetView() function, will use run-time type checking to verify that the document or view is of the correct class.
<MSDN>

"Further, do I have to use a CFile? I will be sending text to 1 of 4 windows using a simple TCHAR buffer.
I don't want to create a text file to send data to the control."
->If you just want to sending simple text to specific view, using SetWindowText, ex:

pmyRichEditCtrl.SetWindowText("Your text");

or folow my fisrt comment.

I am not sure you have to use CFile or not, but remember StreamIn/Out use for input/output stream. Look EDITSTREAM structure:

typedef struct _editstream {
    DWORD_PTR dwCookie;
    DWORD dwError;
    EDITSTREAMCALLBACK pfnCallback;
} EDITSTREAM;

Members
dwCookie:Specifies an application-defined value that the rich edit control passes to the EditStreamCallback callback function specified by the pfnCallback member.

dwError:Indicates the results of the stream-in (read) or stream-out (write) operation. A value of zero indicates no error. A nonzero value can be the return value of the EditStreamCallback function or a code indicating that the control encountered an error.

pfnCallback: Pointer to an EditStreamCallback function, which is an application-defined function that the control calls to transfer data. The control calls the callback function repeatedly, transferring a portion of the data with each call.
0
 
LVL 23

Expert Comment

by:Roshan Davis
Comment Utility
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Answered by : GloriousRain

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Roshan Davis
EE Cleanup Volunteer
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now