Rich edit and CString

I have a CRichEditCtrl in my dialog box.  I need to be able to exchange data between the rich edit control and the CString.  Now, normally this can be accomplished with something like this:

  if (IsWindow (GetDlgItem (IDC_RICHEDIT_DATA)->m_hWnd))
  { if (pDX->m_bSaveAndValidate == 0) // set
    { m_RichEditCtrl.SetWindowText (m_Data); }
    else // get
    { m_RichEditCtrl.GetWindowText (m_Data); }
  }

This code would of course be placed in the DoDataExchange function.

However, I am dealing with large amounts of data--greater than 100k.  This method no longer works.

Please post code that will exchange data between a CString and a rich edit control even when the rich edit control has a lot of text in it.  If the code works, I will give you an A.  Thanks!
joeshmoAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

cybsashaCommented:
Did you try do this :
UpdateData(FALSE);
and get m_data;
UpdateData(TRUE);
set m_data;
0
mikeblasCommented:
cybsasha's comment won't help you: UpdateData() calls DDX_Text(), which just does a GetText(). And that'll fail with such large content in the control, too.

You need to use the Stream() member to stream data into a CMemFile, then pull the CMemFile into a CString. This operation is massively expensive, though. Why do you want to do it? Can't you operate on the data as the CRichEdit control owns it?

..B ekiM


0
mikeblasCommented:
I think that's enough to warrant marking an answer.

..B ekiM
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

joeshmoAuthor Commented:
Thanks for your help Mike.

I would like to implement the streaming approach, despite the clunkiness of it.

I've written the code for it, but it gives me an "Illegal Instruction" error.  I'll post the code, and hopefully you'll be able to help me out.

The illegal operation message appears on the line:

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

while the dialog box is being created and initialized.

Here's the code:

// Callback functions:
static DWORD CALLBACK CallBackOut (DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{ CMemFile* pFile = (CMemFile *) dwCookie;

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

  return 0;
}

static DWORD CALLBACK CallBackIn (DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{ CMemFile* pFile = (CMemFile *) dwCookie;

  *pcb = pFile->Read (pbBuff, cb); // fails here while dialog box is being created.

  return 0;
}

// Code in the data exchange function:
  if (IsWindow (GetDlgItem (IDC_RICHEDIT_DATA)->m_hWnd))
  { EDITSTREAM st;
    CMemFile *memfile;

    if (pDX->m_bSaveAndValidate == 0) // set
    { memfile = new CMemFile ();
      st.dwCookie = (DWORD) &memfile;
      st.pfnCallback = CallBackIn;

      m_RichEditCtrl.StreamIn (SF_TEXT, st);

      BYTE *array = memfile->Detach ();
      m_Data = array;

      delete memfile;
    }
    else // get
    { memfile = new CMemFile ();
      st.dwCookie = (DWORD) &memfile;
      st.pfnCallback = CallBackOut;

      m_RichEditCtrl.StreamOut (SF_TEXT, st);

      BYTE *array = memfile->Detach ();
      m_Data = array;

      delete memfile;
    }
  }

Because your approach is clearly on the right track, I'll give you the points now (A grade), plus 50 more for your additional help.  Thanks!
0
joeshmoAuthor Commented:
Since my last post, I've found another alternative way of doing things.  Unfortunately, I'm having a problem with this method as well.  Here is the code:

// The code in the DoDataExchange function.

  if (IsWindow (GetDlgItem (IDC_RICHEDIT_DATA)->m_hWnd))
  { if (pDX->m_bSaveAndValidate == 0) // set
    { // Read the text in
      CString temp;
      // RTF formatting.  Must be here.
      temp = "{\\rtf1\\ansi\\deff0\\deftab720{\\fonttbl{\\f0\\froman "
             "Times New Roman;}}\n{\\colortbl\\red0\\green0\\blue0;}\n"
             "\\deflang1033\\pard\\tx360\\tx720\\tx1080\\tx1440\\tx1800"
             "\\tx2160\\tx2520\\tx2880\\tx3240\\tx3600\\tx3960\\tx4320"
             "\\tx4680\\tx5040\\tx5400\\tx5760\\tx6120"
             "\\tx6480\\plain\\f3\\fs20 " + m_Data + "\n\\par }";

      EDITSTREAM es;
      es.dwError = 0;
      es.pfnCallback = CallBackIn;
      es.dwCookie = (DWORD) &temp;

      m_RichEditCtrl.StreamIn (SF_RTF, es);  // Do it.
    }
    else
    { // Stream out here.
      EDITSTREAM es;
      es.dwError = 0;
      es.pfnCallback = CallBackOut;          // Set the callback
      es.dwCookie = (DWORD) &m_Data;         // so m_Data receives the string

      m_RichEditCtrl.StreamOut (SF_RTF, es); // Call CRichEditCtrl::StreamOut to get the string.
    }
  }

// The callback functions:
/*
  Callback function to stream an RTF string into the rich edit control.
*/
static DWORD CALLBACK CallBackIn (DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
  // We insert the rich text here.

/*
  This function taken from CodeGuru.com
  http://www.codeguru.com / richedit / rtf_string_streamin.shtml
  Zafir Anjum
*/

  CString *pstr = (CString *) dwCookie;

  if (pstr->GetLength() < cb)
  { *pcb = pstr->GetLength();
    memcpy(pbBuff, (LPCSTR) *pstr, *pcb);
    pstr->Empty();
  }
  else
  { *pcb = cb;
    memcpy(pbBuff, (LPCSTR) *pstr, *pcb);
    *pstr = pstr->Right(pstr->GetLength() - cb);
  }

  return 0;
}

/*
  Callback function to stream the RTF string out of the rich edit control.
*/
static DWORD CALLBACK CallBackOut (DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{ // Address of our string var is in psEntry
  CString *psEntry = (CString*) dwCookie;

  CString tmpEntry = "";
  tmpEntry = (CString) pbBuff;

  // And write it!!!
  *psEntry += tmpEntry.Left (cb);

  return 0;
}


This code only works properly with the SF_RTF flag.  It does NOT work with the SF_TEXT flag, which is what I want.  I don't understand why it doesn't work with the SF_TEXt flag.  Perhaps you can help me with this problem instead?

Either way, please help me with one of these two problems, as either solution will get me to where I want to go.  Thanks!
0
joeshmoAuthor Commented:
Since I've got points to burn, I'll just assume you're not interested in helping further.

Thanks anyway.
0
mikeblasCommented:
Sorry; I tried to follow-up with this question (and the other Q's where you refreshed the issue with more info) but I just didn't have time to trace through your code.

..B ekiM
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.