Lance Leonard'; $attrinfo = ""; // 0=All, 1=New, 2=Intermediate, 3=Expert, 4=Developers Only $audience = "2"; $versions = "Applies to: Paradox 5.0 and later"; $postdate = "5 May 2001"; // 0=Hides areainfo block, 1=About, 2=Paradox, 3=Delphi, 4=Assorted, 5=Webtricks $pagearea = 2; $navlinks = 'Paradox:'; $metakeys = "paradox, corel, borland, formatted memo, rich text, rtf, conversion, converting, objectpal, object pal, form, uiobject, field object, example, how-to, faq, sample, demonstration, demo"; $metadesc = "Shows one way to cleanly convert formatted memos to rich text RTF."; ?>

Question: How do I convert formatted memos to rich text format (RTF)?

Answer:If you're using Paradox 8.0 or later, assign the formatted memo to a Memo variable and then call its writeToRTFFile method, as shown in the following example:

method pushButton(var eventInfo Event)
var
   m  Memo
endVar

const
   FILENAME = "c:\\memotext.rtf"
endConst

   if memoText.Value <> "" then
      m = memoText.Value
      m.writeToRTFFile( FILENAME )
      execute( "c:\\windows\\notepad " + FILENAME )
   endIf

endmethod

If you're using an older version of Paradox, you need to be a little more tricky. Older versions of Paradox can only convert formatted memos using interactive tricks involving the Clipboard. The following example illustrates this using two text boxes on a form:

uses USER32
   LockWindowUpdate( wHandle CLONG ) CWORD
endUses

method pushButton(var eventInfo Event)
var
   b  Binary
   a  Array[] String
   m  Memo
   thisForm  Form
   r  Logical
endVar

   If memoText.Value <> "" then

;      thisForm.attach()
;      r = Logical( lockWindowUpdate( thisForm.windowHandle() ) )

      memoText.moveTo()
      memoText.action( editEnterMemoView )
      memoText.action( selectSelectAll )
      memoText.action( editCopySelection )

      b.readFromClipboard( "Rich Text Format" )
      b.writeToClipboard( "CF_TEXT" )

      ansiText.moveTo()
      ansiText.action( editEnterMemoView )
      ansiText.action( selectSelectAll )
      ansiText.action( editPaste )

      self.moveTo()
;      r = Logical( lockWindowUpdate( 0 ) )
   endIf

endmethod

The above code sample relies on the original implementation of formatted memos. Specifically, if you copy a formatted memo to Clipboard while MemoView is active, Paradox configures the Clipboard so you can easily paste formatted text into programs supporting the RTF format, such as Microsoft Word, Corel WordPerfect, WordPad, and so forth. This code leverages that support by controlling the Clipboard's contents using specific Clipboard formats supported by formatted memos.

Put another way, the programmers who originally designed Paradox's formatted memo support realized that you might need to place that data into other programs. They made certain formatted memos supported common (at the time) data exchange formats, such as RTF and plain text.

This code simply leverages that by mimicking the steps you might perform to do the same task interactively.

You may notice the above sample contains a Windows API call that's currently commented out. When using this code to convert large memos, the screen may "flicker." This happens because you're automating an interactive process. The API call can prevent that flicker from appearing. However, you must use this with care.

When passed a window handle, lockWindowUpdate() prevents that window from being repainted. If you do not deactivate lockWindowUpdate() (e.g. you forget to uncomment the second call near the end of the code), your form will appear to have hung when it hasn't. In other words, your form continues to receive and process events, but the results of those events will not appear on screen because the form is not repainted. Use lockWindowUpdate() with extreme care.

The following shows a more ideal way to use lockWindowUpdate()

uses USER32
   LockWindowUpdate( wHandle CLONG ) CWORD
endUses

method pushButton(var eventInfo Event)
var
   thisForm  Form
endVar

   thisForm.attach()
   lockWindowUpdate( thisForm.windowHandle() )
   try
      doSomething()
   onFail
      lockWindowUpdate( 0 )
      errorShow( "Oops", "Use [>>] for details..." )
   endTry
   lockWindowUpdate( 0 )

endmethod

To see these code samples in action, download the sample file.