Seite 1 von 1

RTF zu EMF konvertieren

Verfasst: 23.03.2010 21:28
von javabean
Ich hab' einen C++ Code nach PureBasic übersetzt. Damit ist es möglich einen RTF-Inhalt in EMF Dateien zu speichern:

RTF_to_EMF.pb

Code: Alles auswählen

;===========================================================
;Inhalt eines RTF Controls in EMF Dateien speichern
;===========================================================
; javabean (März, 2010)
;-----------------------------------------------------------
; getestet auf PureBasic 4.40 (x86-Windows), Windows XP_SP3
;-----------------------------------------------------------
;Code nach PureBasic übersetzt, basierend auf:
;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
;-----------------------------------------------------------

; Include Datei wird benötigt, um die RTF-Datei in das RTF Control zu streamen
; und um das OLE Interface des RTF Controls nutzen zu können
; siehe: http://www.purebasic.fr/english/viewtopic.php?t=20691
XIncludeFile "OLEedit.pbi"

; gibt einen 'printer DC' zurück - benutzt 'Printer Common Dialog'
Procedure GetPrinterDC()
  pdlg.PRINTDLG
 
  pdlg\lStructSize  = SizeOf(PRINTDLG)
  pdlg\Flags        = #PD_RETURNDC; #PD_RETURNDEFAULT
  PrintDlg_(@pdlg)
  ProcedureReturn pdlg\hDC
EndProcedure

; Länge (in Zeichen) des Texts im RTF control ermitteln
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 - Veranlasst das RTF control sich selbst auf ein EMF zu zeichnen
;   Parameter:
;       hRefDC wird benötigt, um das EMF zu erzeugen
;       MetaFileName$ ist der Dateiname des erzeugten EMF
;       prcMeta ist die RECT Struktur für die CreateEnhMetaFile()-Funktion in 0.01mm
;               Einheiten
;       hWndRTF ist das Handle des RTF controls
;       nStart Position des ersten Zeichens
;       *pEnd Pointer zu einer Variable (Long) in der die Position des nächsten zu druckenden Zeichens (nach dieser Seite)
;               gespeichert wird

Procedure.l RTFToEMF(hRefDC.l, MetaFileName$, *prcMeta.RECT, hWndRTF.l, nStart.l, *pEnd)
  fr.FORMATRANGE
 
; DasEMF erzeugen
  hMetaDC = CreateEnhMetaFile_(hRefDC, @MetaFileName$, *prcMeta.RECT, #Null )
 
  If hMetaDC = 0
    ProcedureReturn 0
  EndIf
 
  ;Seite einrichten (konvertiert 0.01mm zu 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

  ;Keine Ränder rundherum
  fr\rc = fr\rcPage

  ;Zu druckenden Textbereich (nStart bis Dokumentenende)
  fr\chrg\cpMin = nStart
  fr\chrg\cpMax = -1
  fr\hdcTarget  = hMetaDC
  fr\hdc        = fr\hdcTarget
 
  ;Veranlasst das RTF Control sich selbst auf unseren (meta)DC zu zeichnen
  nTextPrinted = SendMessage_(hWndRTF, #EM_FORMATRANGE, #True, @fr);
  If *pEnd <> 0
    ;pEnd = nTextPrinted
    PokeL(*pEnd, nTextPrinted)
    ProcedureReturn CloseEnhMetaFile_(hMetaDC)
  EndIf
EndProcedure

;DumpRTFToPagedEMFs - Demonstration von RTFtoEMF() um eine EMF Datei für jede
;                     Seite des RTF Controls zu erzeugen
;   Parameters:
;     hWndRTFControl - Handle zum RTF Control
;     EMFFileTitleBase$ - Basisname der RTF Dateien; die Seitenzahl wird an den Namen angehängt

Procedure DumpRTFToPagedEMFs(hWndRTFControl.l, EMFFileTitleBase$)
  rcMeta.RECT

; Zuerst ermitteln wieviele Zeichen der Text im RTF umfasst
  nRTFTextLength = GetRTFTextLength(hWndRTFControl)
 
; Referenz-DC (basierend auf einem Drucker) ermitteln
  hRefDC = GetPrinterDC()

; meta RECT Struktur (0.01mm Einheiten) einrichten
  SetRect_(@rcMeta, 0, 0, GetDeviceCaps_(hRefDC, #HORZSIZE)*100, GetDeviceCaps_(hRefDC, #VERTSIZE)*100 )
 
; Solange die Schleife durchlaufen bis das Textende im RTF Control erreicht wird
  nStart = 0
  nPage  = 0
  While nStart<nRTFTextLength
    ; Einen Dateinamen für die Seite generieren
    MetaName$ = EMFFileTitleBase$+Str(nPage)+".EMF"
;   obige Funktion aufrufen, um diesen Textteil des RTF auf das EMF zu zeichnen
    hEMF = RTFToEMF(hRefDC, MetaName$, @rcMeta, hWndRTFControl, nStart, @nStart )
;   aufräumen
    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)
    ;Das COM Interface für das RTF Control einrichten
    RichEdit_SetInterface(GadgetID(0))
  ButtonGadget(1,250,565,100,30,"Dump to RTF")
 
  LoadRTF(0, "C:\RTF_file.rtf", #SF_RTF, 1) ; Dateinamen (und -pfad) anpassen
   
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        quit=1
   
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            DumpRTFToPagedEMFs(hWndRTF, "C:\Emf_file_")  ; Dateinamen (und -pfad) anpassen
        EndSelect
    EndSelect
  Until quit=1
EndIf
End
Das Include File 'OLEedit.pbi' stammt von hier: http://www.purebasic.fr/english/viewtopic.php?t=20691