RTF_to_EMF.pb
Code: Select all
;===========================================================
;How to Store the Contents of an RTF Control in an EMF File
;===========================================================
; javabean (March, 2010)
;-----------------------------------------------------------
; tested on PureBasic 4.40 (x86-Windows), Windows XP_SP3
;-----------------------------------------------------------
;Code translated from a C++ example, based on:
;http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/e1930c3b-b5c1-4de6-a541-d4981594d033
;http://support.microsoft.com/?scid=kb%3Ben-us%3B253262&x=7&y=15
;-----------------------------------------------------------
; This code is provided 'as is', without any expressed or
; implied warranty. In no event will the author be held liable
; for any damages arising from the use of this code.
;===========================================================
; RTF_to_EMF.pb
;-----------------------------------------------------------
; Use this include file for streaming-in the rtf
; and to make use of the OLE Interface
; see http://www.purebasic.fr/english/viewtopic.php?t=20691
XIncludeFile "OLEedit.pbi"
; returns a printer DC - uses Printer Common Dialog
Procedure GetPrinterDC()
pdlg.PRINTDLG
pdlg\lStructSize = SizeOf(PRINTDLG)
pdlg\Flags = #PD_RETURNDC; #PD_RETURNDEFAULT
PrintDlg_(@pdlg)
ProcedureReturn pdlg\hDC
EndProcedure
; Get the length, in characters, of the text in the control
Procedure GetRTFTextLength(hWndRTF.l)
gtlex.GETTEXTLENGTHEX
gtlex\flags = #GTL_PRECISE
gtlex\codepage = #CP_ACP
ret = SendMessage_(hWndRTF, #EM_GETTEXTLENGTHEX, @gtlex, 0 )
ProcedureReturn ret
EndProcedure
;RTFToEMF - Tell the control to draw itself on the EMF
; Parameters:
; hRefDC is used to create the EMF
; MetaFileName$ is the file name of the new EMF (can be NULL)
; prcMeta is the RECT used to in CreateEnhMetaFile(), in 0.01mm
; units (should not be NULL)
; hWndRTF is the RTF control of interest
; nStart is the starting character location
; *pEnd is a pointer to an int which receives the position of
; the next character to print after this page (can be NULL)
Procedure.l RTFToEMF(hRefDC.l, MetaFileName$, *prcMeta.RECT, hWndRTF.l, nStart.l, *pEnd)
fr.FORMATRANGE
; Create the EMF
hMetaDC = CreateEnhMetaFile_(hRefDC, @MetaFileName$, *prcMeta.RECT, #Null )
If hMetaDC = 0
ProcedureReturn 0
EndIf
;Set up the page (convert 0.01mm to twips)
fr\rcPage\top = *prcMeta\left *1440/2540
fr\rcPage\left = *prcMeta\top *1440/2540
fr\rcPage\right = *prcMeta\right *1440/2540
fr\rcPage\bottom = *prcMeta\bottom*1440/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, #True, @fr);
If *pEnd <> 0
;pEnd = nTextPrinted
PokeL(*pEnd, nTextPrinted)
ProcedureReturn CloseEnhMetaFile_(hMetaDC)
EndIf
EndProcedure
;DumpRTFToPagedEMFs - demonstrates using RTFToEMF() to create an EMF
; for each page in an RTF control
; Parameters:
; hWndRTFControl - handle to the RTF control
; EMFFileTitleBase$ - base filename for EMF files, number is appended
Procedure DumpRTFToPagedEMFs(hWndRTFControl.l, EMFFileTitleBase$)
rcMeta.RECT
; 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
SetRect_(@rcMeta, 0, 0, GetDeviceCaps_(hRefDC, #HORZSIZE)*100, GetDeviceCaps_(hRefDC, #VERTSIZE)*100 )
; Loop While we've not reached the end of the text in the control
nStart = 0
nPage = 0
While nStart<nRTFTextLength
; construct a file name for this page
MetaName$ = EMFFileTitleBase$+Str(nPage)+".EMF"
; call function above to draw this portion of the RTF on the EMF
hEMF = RTFToEMF(hRefDC, MetaName$, @rcMeta, hWndRTFControl, nStart, @nStart )
; clean up
DeleteEnhMetaFile_(hEMF)
nPage+1
Wend
EndProcedure
If OpenWindow(0, 0, 0, 600, 600, "RTF Control", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
hWndRTF = EditorGadget(0, 8, 8, 584, 550)
SendMessage_(hWndRTF, #EM_SETTEXTMODE, #TM_RICHTEXT, 0)
;Set up the COM interface for the editor gadget.
RichEdit_SetInterface(GadgetID(0))
ButtonGadget(1,250,565,100,30,"Dump to RTF")
LoadRTF(0, "C:\RTF_file.rtf", #SF_RTF, 1) ; Adjust path and filename of the rtf to stream in
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
quit=1
Case #PB_Event_Gadget
Select EventGadget()
Case 1
DumpRTFToPagedEMFs(hWndRTF, "C:\EMF_file_") ; Adjust path and basefilename
EndSelect
EndSelect
Until quit=1
EndIf
End