Ausdruck eines Grids auf Canvas

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Antworten
RLFSoft
Beiträge: 5
Registriert: Mi 4. Jul 2012, 11:38

Ausdruck eines Grids auf Canvas

Beitrag von RLFSoft »

Hallo :shock:

Ich schreibe ein Programm, das unter MAC OS wie auch unter Windows 7 läuft .. laufen soll.
Dabei habe ich eine Seite mit einem Stringgrid, zusätzlich auch einen Titel.
Unter MacOS funktioniert der Ausdruck gut.
Das selbe Programm druckt jedoch unter Windows ganz klein 2,5 x 1,5 cm in der linken oberen Ecke. Dazu habe ich festgestellt, dass das Printer.Canvas.Width und..Height bei Windows 7 Jeweils 0 zurückgibt. Nicht so bei MAC OS. Was muss ich unter Windows berücksichtigen, dass das/der Grid in der Originalgrösse auch ausgedruckt wird ?

Für Hilfe bin ich sehr dankbar.

Hier der Code:

Code: Alles auswählen

procedure TMainWin.BtnPrintProjectGridClick(Sender: TObject);
const
TOTAL_PAGES = 1;
var
   page, startPage, endPage: integer;
   x,y,i,nWidth,nxPos,nLrand,nRowHeight,nFontPos, nRow , xr: integer;
   cTxt: string;
 
begin
  nLrand:=40; // Lft Margin
 
  PrintDialog.Title:='Business Tree';
  // Set Orientation
  Printer.Orientation := poLandscape;
 
    // Set up print dialog options
    printDialog.MinPage := 1;               // First allowed page number
    printDialog.MaxPage := TOTAL_PAGES;     // Highest allowed page number
    printDialog.ToPage  := TOTAL_PAGES;     // 1 to ToPage page range allowed
    printDialog.Options := [poPageNums];    // Allow page range selection
 
    // If the user has selected a printer (or default), then print!
    if printDialog.Execute then
    begin
 
      // Number of copies to print each page
      Printer.Copies := printDialog.Copies;
 
      // Start printing
      Printer.BeginDoc;
 
      { ShowMessage('PaperSize.Width '+ intToStr( Printer.PaperSize.Width )
      +'Printer.PaperSize.Height = '+intToStr(Printer.PaperSize.Height)
      +' PageHeight = '+IntToStr(printer.PageHeight)
       +' Canvas.Width = '+IntToStr(Printer.Canvas.Width)
       + ' Canvas.Height = '+IntToStr(Printer.Canvas.Height));}

 
      startPage := printDialog.FromPage;
      endPage   := printDialog.ToPage;
 
      // Set up the start page number
      page := startPage;
 
      // Setup Font     
        Printer.Canvas.Font.Size:=ProjectGrid.Font.Size;
 
      // Keep printing while all is OK
      while (not Printer.Aborted) and Printer.Printing do
      begin
 
        // Write out the page number  x = linker Rand y = oberer Rand
        Printer.Canvas.Font.Color := clBlue;
 
       cTxt:= TxtTabProject.Caption;
 
        Printer.Canvas.TextOut(nLrand,20, cTxt);
 
        cTxt:='eröffnet am: '+' '+ProjectDate.Text;
 
        nxPos:=nLrand+nWidth - Printer.Canvas.TextWidth( ctxt );
 
        Printer.Canvas.TextOut(nxPos,20, cTxt);
 
        x:= nLrand;
        y:= 40;
 
        nRow:=0;
        nRowHeight:= ProjectGrid.RowHeights[0];
 
        // Set CenterPosition of Text in Cells
 
        nFontPos:= (nRowHeight - abs(Printer.Canvas.Font.Height)) DIV 2;
 
        For nRow:=0 to ProjectGrid.RowCount-1 do
        begin
          x:= nLrand; // Right Position
          Printer.Canvas.Line(x,y,nWidth+nLrand,y); //Horizontal Line
 
          For i:= 0 to ProjectGrid.ColCount-1 do
          begin
            // Vertical Line per Row
            Printer.Canvas.Line(x,y,x,y+nRowHeight);
 
            // Text after Vertical Line
            cTxt := ProjectGrid.Rows[nRow][i];
 
            if i < 2 then
            begin
                 Printer.Canvas.TextOut(x+2,y+nFontPos, cTxt)
            end
            else  // Rechtsbündiger Text
            begin
                xr:= x+ProjectGrid.ColWidths[i];
                xr:= xr-Printer.Canvas.TextWidth(cTxt)-2;
                Printer.Canvas.TextOut(xr,y+nFontPos, cTxt);
            end;
            x:=x+ProjectGrid.ColWidths[i];
          end;
          // Vertical Line at the End of Grid
          Printer.Canvas.Line(x,y,x,y+nRowHeight);
          y:=y+nRowHeight;
        end;
 
       // Last Horizontal Line
        x:= nLrand;
        Printer.Canvas.Line(x,y,nWidth+nLrand,y);
 
         // Increment the page number
        Inc(page);
 
        // Now start a new page - if not the last
        if (page <= endPage) and (not Printer.Aborted)
            then Printer.NewPage else break;
      end;
 
      // Finish printing, start output
      Printer.EndDoc;
 
    end;
end;
Zuletzt geändert von Lori am Mi 4. Jul 2012, 18:58, insgesamt 1-mal geändert.
Grund: Highlighter

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ausdruck eines Grids auf Canvas

Beitrag von theo »

Die Frage ist halt, was bedeutet z.B. nLrand:=40;
40 Druckpunkte, aber wieviele mm das sind, hängt mit der Auflösung des Druckers zusammen.

Versuch mal auf beiden Systemen diesen Code:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
begin
  if PrintDialog.Execute then
  begin
   Printer.BeginDoc;
   For i:=1 to 21 do
   begin
    Printer.Canvas.MoveTo(round(i*Printer.XDPI / 2.54),round(2*Printer.YDPI / 2.54));
    Printer.Canvas.LineTo(round(i*Printer.XDPI / 2.54),round(3*Printer.YDPI / 2.54));
   end;
   Printer.EndDoc;
  end;
end;


Das müsste eig. auf beiden 1 cm hohe Striche im Abstand von 1 cm zeichnen.

RLFSoft
Beiträge: 5
Registriert: Mi 4. Jul 2012, 11:38

Re: Ausdruck eines Grids auf Canvas

Beitrag von RLFSoft »

Herzlichen Dank.
Ich habe das auf MAC OS X 10.7.4 und Auf Windows 7 32 Bit getestet.
Das erwartete Ergebnis ist eingetroffen, es sind 2x beinahe identische Ausdrucke erfolgt.
Beim MAC Waren die Striche Fett und beim Windows sehr fein. In beiden Fällen sind die Abstände und die Breite jeweils 10 mm. :?

Wie ich erfahren habe, müsste ich über API das Windows ansprechen, um die Druckerauflösung zu ermitteln. :x
Offensichtlich gibt es weder in Delphi noch in Lazarus diese Funktion, ohne auf die Betriebssystem-Ebene runter zu gehen.

MAC OS / Unix und Linux spricht die Druckerausgabe standardmässig als Datei an. Bei Windows muss ich recherchieren, wie ich die Auflösung ermitteln kann. :roll:

Falls ich eine komfortable Lösung finde, werde ich mich melden.

Nochmals Danke.

hausi
Beiträge: 132
Registriert: Mi 23. Sep 2009, 08:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Ausdruck eines Grids auf Canvas

Beitrag von hausi »

Beim Windows im Uses WIN ergänzen und schon kannste die Api ansprechen.

Darf ich da eine Gegenfrage stellen: Muss man beim Mac in Uses auch etwas ergänzen?

Hausi

RLFSoft
Beiträge: 5
Registriert: Mi 4. Jul 2012, 11:38

Re: Ausdruck eines Grids auf Canvas

Beitrag von RLFSoft »

Nein, Linux/Mac/Unix behandeln eine Druckausgabe standardmässig als Datei, welche statt auf den Bildschirm, auf den Drucker ausgegeben wird.
Das wurde 1964 erfunden, als Bill Gates noch im stillen Kämmerlein, sprich Garage das MS Dos entwickelt hatte. :roll:

René

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ausdruck eines Grids auf Canvas

Beitrag von theo »

RLFSoft hat geschrieben:Wie ich erfahren habe, müsste ich über API das Windows ansprechen, um die Druckerauflösung zu ermitteln. :x
Offensichtlich gibt es weder in Delphi noch in Lazarus diese Funktion, ohne auf die Betriebssystem-Ebene runter zu gehen.


:?:

Reicht dir Printer.XDPI und Printer.YDPI wie im Beispiel nicht?

RLFSoft
Beiträge: 5
Registriert: Mi 4. Jul 2012, 11:38

Uses Windows und Printer

Beitrag von RLFSoft »

Beim verwenden "Uses Windows" hagelt es Fehler. So wird von CreateDirectory() anstelle eines Strings, ein Array verlangt und ein zweiter Parameter, wenn auch nur Nil. Auch das Abfragen von Systemvariabeln ist nicht mehr mit MAC OS und Linux kompatibel.
Windows 7 erstellt nämlich auch Directories mittels "/" anstelle von Backslash und erkennt unter Windows "USERNAME" etc.
Da ich Daten als XML speichere und wieder lese, kann ich mit wenigen Befehlen (IFDEF WINDOWS) die Line-Feeds etc. kompatibel gestalten.

Hab es wieder herausgenommen und versuche die gute alte Handarbeit. Immerhin bekomme ich die Parameter Printer.PageWidth mit einer sinnvollen Grösse zurück. Daraus kann ich die Druckerauflösung zu ermitteln, wenn ich die Papiergrösse abfragen.

Gruss

René

RLFSoft
Beiträge: 5
Registriert: Mi 4. Jul 2012, 11:38

Re: Printer XDPI

Beitrag von RLFSoft »

Mit Printer XDPI ... vermute ich zum gewünschten Ergebnis zu kommen.
Danke

René

Antworten