MFC, VC++ 6.0, RichEdit -> CString w/ lots of text

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.  The documentation suggests streaming the data.  MikeBlas helped me find this solution.

Unfortunately, the new code isn't working.  Here is a copy of it:

  if (IsWindow (GetDlgItem (IDC_RICHEDIT_DATA)->m_hWnd))
  { EDITSTREAM st;
    CMemFile *memfile;

    if (pDX->m_bSaveAndValidate == 0) // set
    { memfile = new CMemFile ();

      m_Count = m_Data.GetLength ();
      if (m_Count > 0)
      { char *buffer;
        buffer = new char [1000000];
        strcpy (buffer, (const char *) m_Data.operator LPCTSTR ());
        memfile->Write (buffer, m_Count);
        delete [] buffer;
      }

      st.dwCookie = (DWORD) memfile;
      st.pfnCallback = CallBackIn;

      m_RichEditCtrl.StreamIn (SF_TEXT, st);

      delete memfile;
    }
    else // get
    { memfile = new CMemFile ();

      st.dwCookie = (DWORD) memfile;
      st.pfnCallback = CallBackOut;

      m_Count = m_RichEditCtrl.StreamOut (SF_TEXT, st);
      if (m_Count > 0)
      { char *buffer;
        buffer = new char [1000000];
        memfile->Read (buffer, 1000000);
        m_Data = buffer;
        delete [] buffer;
      }

      delete memfile;
    }
  }

The code either doesn't work, or it crashes the program (no illegal operations/gp faults etc, it simply freezes).

Can someone out there help me with this problem that I have been struggling with since before Christmas?  200 points if and only if you can help me get it working!  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.

GGRUNDYCommented:
Hi,
I suggest you try putting the callback
functionality into a separate thread.

I had a similar problem of freezing
when coping the contents of one RichEdit
control to another via a pipe. (I can
send the code if you wish). I suspect
that OLE hooks the message pump to
get a few house keeping things done
and if you never get back to pump your
messages you never get your OLE done either.
Cheers
0
mikeblasCommented:
Where are you executing this new code, joeshmo?

..B ekiM
0
CrashBoomBangCommented:
m_Count does not include a null terminator so when You do

strcpy (buffer, (const char *) m_Data.operator LPCTSTR ());
memfile->Write (buffer, m_Count);
    and then
memfile->Read (buffer, 1000000);
m_Data = buffer;

string stays undeterminted. In this case program should freeze on m_Data = buffer
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

joeshmoAuthor Commented:
GGRUNDY, thanks for the idea.  I'll come back to that if the other solutions don't work.  I think, however, that the problem is with my code.

Mike, this code is in the "void CMyDlg::DoDataExchange(CDataExchange* pDX)" member function.

CrashBoomBang, thanks for the input.  I understand what you are telling me, but this doesn't seem to fix the problem.  Here is the new code.  Perhaps I am interpreting your solution improperly?

  if (IsWindow (GetDlgItem (IDC_RICHEDIT_DATA)->m_hWnd))
  { EDITSTREAM st;
    CMemFile *memfile;

    if (pDX->m_bSaveAndValidate == 0) // set
    { memfile = new CMemFile ();

      m_Count = m_Data.GetLength () + 1; // + 1 for null

      { char *buffer;
        buffer = new char [1000000];
        strcpy (buffer, (const char *) m_Data.operator LPCTSTR ());
        memfile->Write (buffer, m_Count);
        delete [] buffer;
      }

      st.dwCookie = (DWORD) memfile;
      st.pfnCallback = CallBackIn;

      m_RichEditCtrl.StreamIn (SF_TEXT, st);

      delete memfile;
    }
    else // get
    { memfile = new CMemFile ();

      st.dwCookie = (DWORD) memfile;
      st.pfnCallback = CallBackOut;

      m_Count = m_RichEditCtrl.StreamOut (SF_TEXT, st);

      { char *buffer;
        buffer = new char [1000000];
        memfile->Read (buffer, 1000000);
        m_Data = "test";
        delete [] buffer;
      }

      delete memfile;
    }
  }


Also, here are the 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);

  return 0;
}


Thanks for the help everyone!
0
joeshmoAuthor Commented:
To reiterate: CrashBoomBang, if you can get me a working solution by posting the exact code or something similar, I will give the 200 points + A grade.

This is really frustrating me because of the apparent simplicity of the problem and the length of time it is taking to get an effective solution.

Thanks for your help everyone!
0
joeshmoAuthor Commented:
Please, can anyone answer this?  At least let me know if the code appears to be correct, then I will know the problem lies elsewhere.
0
CrashBoomBangCommented:
Using yours code I can't get same error (but I try it on BC5 - I just haven't VC6). But I found one thing - CMemFile needs rewind after write operation. Else read operation got nothing to read.
I fix it as you can see below:
....... set
    strcpy (buffer, (const char *) m_Data.operator LPCTSTR ());
    memfile->Write (buffer, m_Count);
    memfile->SeekToBegin();
....... end
....... get
     buffer = new char [1000000];
     memfile->SeekToBegin();
     memfile->Read (buffer, 1000000);
....... end
Of course it is not look as fatal error.

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
joeshmoAuthor Commented:
Fantastic!  With a few other tweaks, I got the problem solved.  Since your code was indeed necessary to solve the problem, I'm going to award you with the points and an A.

Thanks CrashBoomBang!
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
Microsoft Development

From novice to tech pro — start learning today.