• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 679
  • Last Modified:

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!
0
joeshmo
Asked:
joeshmo
1 Solution
 
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
2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

 
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
 
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

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now