How To store the contents of a RichEdit in an EMF files

Howto store the contents of a RichEdit in an EMF files

Sometimes, you may want to store the contents of a rich edit control in a metafile. This article outlines an approach that stores this type of control's contents in enhanced metafiles, one page per metafile. The following code demonstrates one method to dump the contents of a rich edit control into EMF files (one per page):

unit RichEditEMFPrint;

interface

uses
  Windows, SysUtils, RichEdit, commdlg, classes, messages, Comctrls;

procedure RichEditToMetaFile(AControl : TRichEdit; AFileName : string);

implementation

// GetPrinterDC()
// returns a printer DC - uses Printer Common Dialog
function GetPrinterDC : HDC;
var
  pdlg : TPRINTDLG;
begin
  FillChar(pdlg, sizeof(TPRINTDLG), 0);
  pdlg.lStructSize := sizeof( TPRINTDLG );
  pdlg.Flags := PD_RETURNDC;
  PrintDlg(pdlg);
  Result := pdlg.hDC;
end;

// Get the length, in characters, of the text in the control
function GetRTFTextLength(hWndRTF : HWND) : integer;
begin
  Result := SendMessage(hWndRTF, WM_GETTEXTLENGTH, 0, 0 );
end;

// RTFToEMF - Tell the control to draw itself on the EMF
// Parameters:
//     hRefDC is used to create the EMF
//     pszMetaFileName is the file name of the new EMF (can be nil)
//     prcMeta is the RECT used to in CreateEnhMetaFile(), in 0.01mm
//          units (should not be nil)
//     hWndRTF is the control of interest
//     nStart is the starting character location
//     pEnd is a integer which receives the position of
//          the next character to print after this page
function RTFToEMF(hRefDC : HDC; pszMetaFileName : LPCTSTR;  prcMeta : TRECT;
                      hWndRTF : HWND; nStart : integer; var pEnd : integer) : HENHMETAFILE;
var
  hMetaDC : HDC;
  fr : FORMATRANGE;
  nTextPrinted : integer;
begin
    // Create the EMF
    hMetaDC := CreateEnhMetaFile( hRefDC, pszMetaFileName, @prcMeta, nil );
    if( hMetaDC = 0 ) then
     begin
        Result := 0;
        Exit;
     end;

    ZeroMemory(@fr, sizeof(fr));
    // Set up the page (convert 0.01mm to twips)
    fr.rcPage.top       := prcMeta.left*1440 div 2540;


    fr.rcPage.left      := prcMeta.top*1440 div 2540;
    fr.rcPage.right     := prcMeta.right*1440 div 2540;
    fr.rcPage.bottom    := prcMeta.bottom*1440 div 2540;
    // Set up no margins all around.
    fr.rc := fr.rcPage;
    // Set up the range of text to print as nStart to end of document
    fr.chrg.cpMin := nStart;
    fr.chrg.cpMax := -1;
    fr.hdcTarget := hMetaDC;
    fr.hdc := fr.hdcTarget;
    // Tell the control to draw itself on our (meta) DC
    nTextPrinted := SendMessage(hWndRTF, EM_FORMATRANGE, 1, integer(@(fr)));
    pEnd := nTextPrinted;
    Result :=  CloseEnhMetaFile( hMetaDC );
end;

// DumpRTFToPagedEMFs - demonstrates using RTFToEMF() to create an EMF
//                      for each page in an RTF control
// Parameters:
//     hWndRTFControl - the control
//     szEMFFileTitleBase - base filename for EMF files, number is appended
procedure DumpRTFToPagedEMFs(hWndRTFControl : HWND; szEMFFileTitleBase : LPTSTR);
var
  szMetaName : string;
  nRTFTextLength, nStart, nPage : integer;
  hRefDC : HDC;
  rcMeta : TRECT;
  hEMF :   HENHMETAFILE;
begin
    // First, determine how many chars are in the RTF
    nRTFTextLength := GetRTFTextLength( hWndRTFControl );
    // Get a reference DC (based on a printer)
    hRefDC := GetPrinterDC();
    // Set up the meta RECT for 0.01mm units
    rcMeta := Classes.Rect( 0, 0, GetDeviceCaps(hRefDC, HORZSIZE)*100,
                            GetDeviceCaps(hRefDC, VERTSIZE)*100 );
    nPage := 0;
    nStart := 0;
    while nStart<nRTFTextLength do
    // Loop while we've not reached the end of the text in the control
    begin
        // construct a file name for this page
        szMetaName := Format('%s%d.EMF', [szEMFFileTitleBase, nPage]);
        // call function above to draw this portion of the RTF on the EMF
        hEMF := RTFToEMF( hRefDC, PChar(szMetaName), rcMeta, hWndRTFControl,
                         nStart, nStart );
        // clean up
        DeleteEnhMetaFile( hEMF );
        inc(nPage);
        if nStart = 0 then
         break;
    end;
end;

procedure RichEditToMetaFile(AControl : TRichEdit; AFileName : string);
begin
   DumpRTFToPagedEMFs(AControl.Handle, PChar(AFileName));
end;

end.

 

Share this article!

Follow us!

Find more helpful articles: