Bin ziemlich eingerostet und eigentlich damals auch nicht weit gekommen ...

Nun möchte ich gerne einen "Arbeitsblattgenerator" für einfache Rechenaufgaben basteln.
(Zahlenraum bis 20 beginnend bei Aufgaben zum Erfassen (Abzählen, Vergleichen) von Mengen.
Die Aufgaben sollen über Zufallsgenerator erzeugt werden.
Dazu hätte ich gerne eine Preview, damit man vor dem Ausdruck schauen kann, ob einem die generierten Aufgaben sinnvoll erscheinen.
Ich habe nun einige Tage gegoogled und im Forum gelesen bin aber noch nicht fündig geworden.
Lazreport, NicePreview, KControls, Preview (aus der Delphiarea) und PowerPDF - als alternativen Weg - habe ich mir angeschaut, aber noch nicht alles als laufendes Package oder Unit konvertieren oder direkt nutzen können.
Eigentlich würde mir die Basis im gepostet Source-Code reichen.
(Quelle: Borland Delphi 3 für Profis - ein bisschen auf Lazarus angepasst.)
Da würde ich mir zutrauen den Rest prozedural dazu zu pfuschen.
Leider ist da ein Fehler drin, den ich nicht finden kann.
Beim Start des Programmes (siehe unten), wird die Zeichenfläche zunächst grau angezeigt.
Wenn man dann das Fenster in der Breite aufzieht, flackert es und mit ein bisschen Glück sieht man dann auf weißer Fläche den Probetext und eine Testlinie ...
Ich nutze Lazarus 1.0.4 auf einem Win 8, 32Bit-System.
Vielleicht kann mir hier jemand einen Tipp geben.
(Ansonsten muss ich euch mit Fragen zu den oben erwähnte Komponenten nerven.

Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, PrintersDlgs, Forms, Controls, Graphics, Dialogs,
LCLIntf, LCLType, Printers, ExtCtrls, Buttons, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Shape1: TShape;
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
blatt: TCanvas;
dc: HDC;
druckbreite, druckhoehe: integer;
panelx: TWinControl;
wanze: integer;
implementation
{$R *.lfm}
{ TForm1 }
procedure blattanpassen;
var
prnxy,
formxy : single;
dx, dy, x, y : integer;
blattbreite,
blatthoehe : integer;
scale : single;
xofs,yofs : integer;
MMproPixelX,
MMproPixelY : real;
begin
// Bestimmen der Blattabmessungen (in Millimeter)
MMproPixelX := 25.4 / printer.XDPI; // GetDeviceCaps( printer.handle, LOGPIXELSX);
MMproPixelY := 25.4 / printer.YDPI; // GetDeviceCaps( printer.handle, LOGPIXELSY);
blattbreite := Round(printer.PaperSize.Width * MMproPixelX); // Round(GetDeviceCaps(printer.handle,PHYSICALWIDTH) * MMproPIXELX);
blatthoehe := Round(printer.PaperSize.Height * MMproPixelY); // Round(GetDeviceCaps(printer.handle,PHYSICALHEIGHT) * MMproPIXELY);
// Bestimmen des Offsets für den bedruckbaren Bereich
xofs := Round(printer.PaperSize.PaperRect.WorkRect.Left * MMproPixelX); // Round(GetDeviceCaps(printer.handle,PHYSICALOFFSETX) * MMproPIXELX);
yofs := Round(printer.PaperSize.PaperRect.WorkRect.Top * MMproPixelX); // Round(GetDeviceCaps(printer.handle,PHYSICALOFFSETY) * MMproPIXELY);
// Bestimmung der Seitenabmessungen in Millimetern
druckbreite := Round(printer.PageWidth * MMproPixelX); // GetDeviceCaps(printer.handle, horzsize);
druckhoehe := Round(printer.PageHeight * MMproPixelY); // GetDeviceCaps(printer.handle, vertsize);
// ?? (Scrollbar)Ränder als Vorgabe?
y := 35;
x := 10;
// Das Höhen-/Seitenverhältnis des Formulars ermitteln
formxy := (form1.clientWidth - x) / (Form1.clientHeight - y);
// Das gleiche für den Drucker
prnxy := blattbreite / blatthoehe;
// Maximale Anzeigengröße abhängig von Blattbreite oder Blatthöhe
if formxy < prnxy then
begin {Breite dominiert}
dx := form1.clientWidth - 20;
dy := round(dx / prnxy);
y := round((Form1.ClientHeight / 2 + 8) - (dy / 2));
end else
begin {Höhe dominiert}
dy := form1.clientHeight - y - 10;
dx := round(dy * prnxy);
x := round((form1.ClientWidth / 2) - (dx / 2));
end;
// "Blatt" skalieren
form1.shape1.setbounds(x,y,dx,dy);
scale := dy / blatthoehe;
panelx.setbounds(x+Round(xofs*scale),y+Round(yofs*scale),
Round(druckbreite*scale),Round(druckhoehe*scale));
// Skalierfaktoren über API-Funktionen
SetMapMode(blatt.handle, mm_anisotropic);
SetViewPortExtEX(blatt.handle, dx, dy, nil); // Skalierung
SetWindowExtEX(blatt.handle,druckbreite * 10,-druckhoehe * 10,nil);
SetBKmode(blatt.handle, TRANSPARENT);
blatt.Brush.Style := bssolid;
blatt.Brush.Color := clwhite;
blatt.Pen.Color := clblack;
// Das "Blatt" wird weiß "gestrichen"
blatt.fillRect(bounds(0,0,druckbreite*10,-druckhoehe*10));
// Test-Ausgaben
end;
procedure ausgabe(ziel : TCanvas);
var
breite,hoehe : integer;
begin
with ziel do begin
breite := druckbreite*10;
hoehe:=druckhoehe*10;
moveto(0,-10);LineTo(breite,-10);
// in 1/10 Millimeter
font.Height:=50;
font.Name:='Arial';
textOut(breite div 2, -(hoehe div 2),'Hallo Welt!');
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
panelx := TWinControl.Create(self);
panelx.parent := Form1;
blatt := TCanvas.Create;
blatt.handle := GetDC(panelx.handle);
setmapmode(blatt.handle,mm_anisotropic);
end;
procedure TForm1.FormResize(Sender: TObject);
begin
blattanpassen;
ausgabe(blatt);
end;
end.