Examples Delphi

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