Hi Tim;
To save the contents of the rtf being edited using the TRichEdit() class, you could use the GetText() method which returns the rtf. Here is sample code using pure harbour.
aEval( ::aRtfs, { |e,n| iif( e:IsModify(), ( Â ;
   iif( ::hSSCEDLL <> Nil,         ;
     (SSCE_CheckCtrlDlg( ::oDlg:hWnd, e:hWnd, .f. ),;
     SSCE_CheckCtrlBackgroundClear( e:hWnd, SSCE_OPTION, RGB( 254, 1, 1 ) ) ), ),;
   iif( e:odbf:isAdd, (e:odbf:isadd := .f., e:odbf:append() ), ) ,;
   iif( !empty( e:GetText() ),       ;
     ( e:SaveToRtfFile( e:cFileName ),    ;
      e:odbf:VarText := MemoRead( e:cFileName ) ), ;
      e:odbf:VarText := "" ),       ;
   ;
      e:odbf:VarDate := date(),     ;
      e:odbf:VarTime := time(),     ;
      e:odbf:Save() ,          ;
      ::ExtractUsersIds( e ),       ;
      ::ExtractCASS( e ),        ;
      ::ExtractCptsIcds( e ) ), ),    ;
   ::SaveCaseInfo() } )
On the sample code above, ::aRtfs is an array of TRichText() objects. Never mind the SSEC_… calls as these are calls into a spell checker. Notice e:SaveToRtfFile(). It creates an rtf physical file that you may keep, delete, or re-read into a memo field. In this case e:VarText is a memo field and it does just that, saves the .rtf into a memo field in a .fpt memo file.
In case it helps in a different way, I have long changed that method in preference of sql statements. Here is the same using SQL against .dbf/ftp tables:
  cSql := "\n"+;
   "MERGE $1$ ON (PathNo = '$2$')             \n"+;
   "WHEN NOT MATCHED THEN INSERT ( [PathNo], [text],   \n"+;
   "         [time], [date], [user] )       \n"+;
   "         VALUES( '$2$', :memoData,      \n"+;
   "         CAST( curtime() AS SQL_CHAR ),    \n"+;
   "         CAST( now() AS SQL_DATE ),      \n"+;
   "         user() )               \n"+;
   "WHEN MATCHED THEN UPDATE SET [TEXT] = :memoData,   \n"+;
   "         [time] = CAST( curtime() AS SQL_CHAR),\n"+;
   "         [date] = CAST( now() AS SQL_DATE ), \n"+;
   "         [user] = User()           \n"
  FOR EACH oRtf IN ::aRtfs
   cText := iif( !EMPTY( oRtf:GetText() ), oRtf:SaveAsRTF(), "" )
   IF oRtf:oDbf:isadd .AND. EMPTY( cText ) ; LOOP  ;ENDIF
   IF ::hSSCEDLL <> Nil
     SSCE_CheckCtrlDlg( ::oDlg:hWnd, oRtf:hWnd, .f. )
     SSCE_CheckCtrlBackgroundClear( oRtf:hWnd, SSCE_OPTION, RGB( 254, 1, 1 ) )
   ENDIF
   //Must re-read transcription after spell checker has ran.
   cText := iif( !EMPTY( oRtf:GetText() ), oRtf:SaveAsRTF(), "" )
   IF !EMPTY( cText )
     oQ := TAdsQuery():New()
     oQ:cSql := cSql
     oQ:aSubstitutes := { oRtf:oDbf:cTableName, ::cPthNo }
     oQ:adsPrepareSql()
     AdsSetString( "memoData", cText )
     oQ:RunAdsPreparedSql()
     oQ:End()       Â
    Â
   ENDIF
  Â
   oRtf:lChanged := .F.
   ::ExtractUsersIds( oRtf )
   ::ExtractCASS( oRtf )
   ::ExtractCptsIcds( oRtf )
  NEXT
  ::SaveCaseInfo()
  ::isChangedSinceLastSave := .F.
Here is a screen shot of the transcription dialogs containing the richtext objects:
Hope that helps;
Reinaldo.