Programmierung

Druckvorschau selbstgemacht!

Das CtxDocEdit dient zur Anzeige und Bearbeitung von verschiedenen Dokument-Formaten, wie bereits im Artikel Textverarbeitung leichtgemacht vorgestellt wurde. Nun gibt es für das CtxDocEdit neben der Druckfunktion keine mitgelieferte Druckvorschau. In diesem Artikel möchte ich Ihnen die Möglichkeiten zeigen, eine eigene Druckvorschau mithilfe von CONZEPT 16 zu realisieren.

Der Dialog

In diesem Beispiel wird eine Toolbar zum Aufruf der Druckfunktion, sowie zur Einstellung des Zooms verwendet. Neben der Toolbar ist eine Statusbar vorhanden, die der Navigation zwischen den Seiten und der Anzeige von Seiteninformationen dient. Zu guter Letzt fehlt noch das CtxDocEdit, in dem der Text angezeigt wird. In der Druckvorschau liegen zwei CtxDocEdit-Objekte übereinander. Das Hintere beinhaltet den gesamten Text, von dem immer eine ausgewählte Seite im vorderen CtxDocEdit angezeigt wird.

Druckvorschau

Die Programmierung

Bei dem Aufruf der Druckvorschau wird der Prozedur der Deskriptor eines CtxDocEdits übergeben. Bevor die Vorschau geladen und geöffnet werden kann, muss der gesamte Text mithilfe des übergeben Deskriptors zwischengespeichert werden. Hierbei empfiehlt sich WinDocSaveName(), da wichtige Einstellungen, wie die Formatierung, mitgespeichert werden, außerdem ist man nicht an die 4096 Zeichen-Begrenzung des Alpha-Datentyps gebunden.

// Den kompletten Text des Quell-CtxDocEdit in eine externe, temporäre Datei speichern
sub SaveAllTextToFile
(
  aCtxSrc               : handle;                // Quell-Ctx
)

  local
  {
    tErr                : int;                   // Fehlercode
  }

{
  tErr # aCtxSrc->WinDocSaveName(_WinStreamNameFile, _WinDocSaveDoc, sTmpFile);
  if (tErr != _ErrOk)
    ErrBox(__FUNC__ + ' : Fehler beim Erstellen der temporären Datei. (' + CnvAI(tErr) + ')');
}

Die Seitenbreite und die Ausrichtung müssen selbstständig vom CtxDocEdit ausgelesen und gespeichert werden. (Nähere Informationen zu den Eigenschaften des CtxDocEdits stehen in der Dokumentation)

pPageWidth # aCtxDocEditSrc->cpiPageWidth; // Breite der Seite
pLayout # aCtxDocEditSrc->cpiPageOrientation; // Ausrichtung

Nun kann die Druckvorschau geöffnet werden. Durch WinDocLoadName() wird der gesamte Text in das verborgene CtxDocEdit geladen. Mithilfe der selbstgeschriebenen Funktion GetCtxText(aPage), der man die gewünschte Seite übergibt, wird im verborgenen CtxDocEdit die entsprechende Seite markiert und mittels WinDocSaveName() und WinDocLoadName() in das sichtbare CtxDocEdit kopiert.

// Schreibt den Text der Übergeben Seite vom Ctx-Ghost ins Ctx-Preview
sub GetCtxText
(
  aPage                 : int;                   // auszuwählende Seite
)
: logic;

  local
  {
    tErr                : int;                   // Fehlercode
  }

{
  // Löscht aktuell angezeigten Text
  pCtxDocEditPreview->DeleteCtxText();

  //  aPage im Ctx-Ghost markieren
  pCtxDocEditGhost->SelectPage(aPage);
  //  Markierte Seite in externe Datei speichern
  tErr # pCtxDocEditGhost->WinDocSaveName(_WinStreamNameFile, _WinDocSaveDoc | _WinDocSaveMark, sTmpFile);
  if (tErr != 0)
    ErrBox(__FUNC__ + ' : Fehler beim Erstellen der temporären Datei. (' + CnvAI(tErr) + ')');
  else
  {
    // Text vom Binären Objekt ins Ctx-Preview laden
    tErr # pCtxDocEditPreview->WinDocLoadName(_WinStreamNameFile, _WinDocLoadDoc, sTmpFile);
    if (tErr != 0)
      ErrBox(__FUNC__ + ' : Fehler beim Lesen der temporären Datei. (' + CnvAI(tErr) + ')');
  }
}

Die Funktion SelectPage() wird von GetCtxText() aufgerufen, um eine übergebene Seite zu markieren und sieht wie folgt aus:

// Markiert die angegebene Seite im Ctx-DocEdit aus
sub SelectPage
(
  aCtx                  : handle;                // Ctx-DocEdit, in dem die Seite ausgewählt wird
  aPage                 : int;                   // Seite die ausgewählt werden soll
)

  local
  {
    tPosObj             : handle;                // Eigenschaft des Ctx-DocEdit (TXTextControl.CurrentInputPosition)
    tCurPages           : int;                   // Anzahl der Seiten
    tStartPos           : int;                   // Start der Markierung
    tEndPos             : int;                   // Ende der Markierung
  }

{
  tCurPages # aCtx->cpiCurrentPages;             // Anzahl der Seiten auslesen

  tPosObj # aCtx->cphCurrentInputPosition;       // Zeiger auf Array

  tPosObj->cpiItem(0) # aPage;                   // auf aPage wechseln
  tPosObj->cpiItem(1) # 1;                       // Zeile wird auf 1 gesetzt
  tPosObj->cpiItem(2) # 0;                       // Spalte auf 0 --> Cursor an den Anfang der 1. Zeile setzen

  aCtx->cphCurrentInputPosition # tPosObj;       // Änderungen auf Ctx-DocEdit anwenden

  tStartPos # aCtx->cpiSelStart;                 // Markierung beginnt am Anfang der 1. Zeile der Seite

  // aPage ist nicht die letzte Seite
  if (aPage != tCurPages)
  {
    tPosObj->cpiItem(0) # aPage + 1;             // Auf die erste Zeile der nächsten Seite wechseln
    tPosObj->cpiItem(1) # 1;
    tPosObj->cpiItem(2) # 0;

    aCtx->cphCurrentInputPosition # tPosObj;
    tEndPos                       # (aCtx->cpiSelStart) - 1;    // Position des letzten Zeichens der zu markierenden Seite errechnen
  }
  // aPage ist die letzte Seite
  else
  {
    aCtx->cpiSelStart # -1;                      // mit -1 bis zum Ende des Dokuments markieren
    tEndPos # aCtx->cpiSelStart;
  }

  aCtx->cpiSelStart  # tStartPos;
  aCtx->cpiSelLength # tEndPos - tStartPos;

  aCtx->WinFocusSet();                           // wenn Focus nicht gesetzt wird, wird nicht markiert
}

Die Funktion SelectPage() setzt in der Eigenschaft wpViewMode der CtxDocEdit den Modus _WinViewModePage voraus.

Um die Selektion des Textes wirksam zu machen, wird ein WinFocusSet() benötigt.

Damit die Änderungen des Zoomfaktors sichtbar werden, muss der Frame aktualisiert werden. Hierzu kann die Methode TXTextControl.Refresh des CtxDocEdit aufgerufen werden. Im Beispiel findet dies im EvtCtxEvent() statt.

// Event wird bei PosChange und Zoom im Ctx-Preview ausgelöst
sub EvtCtxEvent
(
  aEvt                 : event;                  // Ereignis
  aEventID             : int;                    // Ereignis-Nummer
  aComArguments        : handle;                 // COM-Argument-Objekt
)
: logic;
{
  switch (aEventID)
  {
    // Refresh des Frames zur Aktualisierung des Zooms
    case txEvtZoomed :
    {
      aEvt:Obj->ComCall('Refresh');

      // ...
    }

    // ...
  }

  return(true);
}

Die oben verwendeten Codeausschnitte werden Ihnen hier als fertiges Modul in einer
Datenbank (Stand 5.7.02) zum Download angeboten.

Download

CONZEPT 16-Beispiel: Druckvorschau DruckvorschauDB.zip (69.98 KB)
Sie müssen angemeldet sein, um die Datei herunterladen zu können.

1 Kommentar

1 Kommentar zu “Druckvorschau selbstgemacht!”

  1. Wir Drucken den gesamten Textinhalt als Vorschau, einzelne Seiten können so über die Vorschau ausgewählt werden.
    Die vorgestellt Lösung für einzelne Seiten werden wir sicherlich noch einbinden.
    Der haken ist, das wir in einem (Mdi-)Fenster drei Textvarianten unterstützen, welches durch ein Flag vom Aufrufer gesteuert wrid. Ist keine AktivX Unterstützung an einem Arbeitsplatz Installiert, wird auto. der Rtf-Modus angenommen, dort gibt es keine Seiteneinstellung bzw. die letzte Bearbeitung über AktivX ist dann im Rtf Fomat nicht mitgeführt. Die dritte Variante ist die Unterstützung von reinen ASCII Texten. Das Fenster enthält dafür die entsprechenden Objekte für die passende Verwaltung.

Kommentar abgeben