Entwickler-Ecke

Sonstiges (Delphi) - Printer.Title wird nicht angenommen


jasocul - Fr 08.02.13 14:28
Titel: Printer.Title wird nicht angenommen
Ich habe gerade ein Brett vor dem Kopf, glaube ich.

Ich habe eine kleine Komponente für einen Screenshot der aktuellen Form gebastelt (TForm.Print reicht nicht).
Natürlich möchte ich auch Printer.Title füllen. Die Zuweisung wird auch angenommen, aber im Drucker-Spool nicht angezeigt.

Nehme ich die entsprechende Unit direkt ins Projekt mit auf, dann funktioniert es allerdings.

Delphi-Quelltext
1:
2:
3:
4:
   Printer.Title := 'Screenshot:'// Wird nicht übernommen !!!???
   Printer.BeginDoc;
   Printer.Canvas.StretchDraw(r, bmp);
   printer.EndDoc;

Alle anderen Zuweisungen, wie z.B. Orientation werden angenommen.

Hat jemand eine Idee, wo mein Fehler sein kann?


Jakane - Fr 08.02.13 14:41

Ich bin mir nicht ganz sicher, aber könnte es sein das der Titel von deinem anderen Bild überdruckt wird?
Von der Reihenfolge her hat dien Bild nämlich eine höhere Ebene als der Titel.


jasocul - Fr 08.02.13 14:45

Der Titel wird nicht gedruckt, sondern erscheint beim Drucker in der Liste der Dokumente, die in der Warteschlange stehen.


jasocul - Mo 11.02.13 09:22

*PUSH*
Niemand eine Idee?


Nersgatt - Mo 11.02.13 09:25

Einfach mal ein Schuss ins Blaue: Mal versucht, das Printer.Title erst nach .BeginDoc aufzurufen?


Mathematiker - Mo 11.02.13 10:08

Hallo,
ähnliche Merkwürdigkeiten hatte ich bisher nur bei einem Netzwerkdrucker.
Für eine Hilfe müsstest Du wahrscheinlich mehr Quelltext zeigen. Insbesondere wäre der Prozedurkopf der Druckroutine wichtig. Meine Vermutung ist, dass printer eine falsche/doppelte Belegung hat.

Beste Grüße
Mathematiker


jasocul - Mo 11.02.13 11:31

@Nersgatt:
Die Idee hatte ich auch schon. Aber das ist eigentlich falsch. Getestet habe ich es natürlich trotzdem :lol: Ohne Erfolg.

Hier mal der Source (Ist mitten in der Entwicklung):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
unit DFBScreenshot;

interface

uses
  Vcl.Forms, Printers, System.Classes, vcl.Controls;

type
  TOrientation = (orLandscape, orPortrait, orAutomatic, orPrinterSettings);
  TPrintCentered = (pcHorizontal, pcVertical);
  TPrintCenteredSet = Set of TPrintCentered;
  TStretch = (scNone, scHorizontal, scVertical, scAutomatic);

  TDFBScreenshot = class(TComponent)
  private
    { Private-Deklarationen }
    FBorderInMM : Word;
    FCentered : TPrintCenteredSet;
    FOrientation : TOrientation;
    FStretching : TStretch;
    FWithPrintDialog : Boolean;
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    Constructor Create(AOwner : TComponent); override;
    Destructor Destroy; Override;
    procedure MakeScreenshot;
  published
    { Published-Deklarationen }
    property BorderInMM : Word read FBorderInMM write FBorderInMM default 10;
    property Centered : TPrintCenteredSet read FCentered write FCentered default [pcHorizontal, pcVertical];
    property Orientation : TOrientation read FOrientation write FOrientation default orAutomatic;
    property Stretching : TStretch read FStretching write FStretching default scAutomatic;
    property WithPrintDialog : Boolean read FWithPrintDialog write FWithPrintDialog default True;
             // Diese Eigenschaft ist zur Zeit noch ohne Funktion
  end;

implementation

uses
  Winapi.Windows,
  Vcl.Graphics,
  Dialogs;

Constructor TDFBScreenshot.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  FBorderInMM := 10;
  FCentered := [pcHorizontal, pcVertical];
  FOrientation := orAutomatic;
  FStretching := scAutomatic;
  FWithPrintDialog := True;
end;

Destructor TDFBScreenshot.Destroy;
begin
  inherited Destroy;
end;

Procedure TDFBScreenshot.MakeScreenshot;
var
  OldPO : TPrinterOrientation;
  bmp : Vcl.Graphics.TBitmap;
  dc: THandle;
  r : TRect;
  PixPerInchX : Integer;
  PixPerInchY : Integer;
  ScaleFactor : Real;
begin
  // In Arbeit
  // Falls ein Print-Dialog benutzt, muss ein ProcessMessages erfolgen. Es kann
  // sonst sein, dass der Dialog noch vor dem Handle-Objekt (z.B. Fenster) steht.
  // In dem Fall würde dann das Dialog-Fenster mitgedruckt werden, weil es noch
  // vor dem Canvas steht.
  Application.ProcessMessages;
  bmp := Vcl.Graphics.TBitmap.Create;
  try
    if Assigned(bmp) then
    begin
      GetWindowRect(TForm(Owner).Handle, r);
      dc := GetWindowDC(TForm(Owner).Handle);

      OldPO := Printer.Orientation;
      case FOrientation of
        orLandscape : begin
          Printer.Orientation := poLandscape;
        end;
        orPortrait : begin
          Printer.Orientation := poPortrait;
        end;
        orAutomatic : begin
          if r.Width > r.Height then
          begin
            Printer.Orientation := poLandscape;
          end
          else
          begin
            Printer.Orientation := poPortrait;
          end;
        end;
        orPrinterSettings : begin
          // Do Nothing
        end;
      end;

      try
        With bmp do
        begin
          Width := r.Width;
          Height:= r.Height;
          BitBlt(Canvas.Handle,
                 0,
                 0,
                 r.Width,
                 r.Height,
                 dc,
                 0,
                 0,
                 SrcCopy);
        end;

        PixPerInchX := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
        PixPerInchY := GetDeviceCaps(Printer.Handle, LOGPIXELSY);

        // !!! ACHTUNG! Reihenfolge von Stretching und Rand sind wichtig !!!
        // Stretch-Größe optimieren
        case FStretching of
          scHorizontal : begin
            ScaleFactor := Printer.PageWidth / r.Width;
          end;
          scVertical : begin
            ScaleFactor := Printer.PageHeight / r.Height;
          end;
          scAutomatic : begin
            if (Printer.PageHeight / r.Height) > (Printer.PageWidth / r.Width) then
            begin
              ScaleFactor := Printer.PageWidth / r.Width;
            end
            else
            begin
              ScaleFactor := Printer.PageHeight / r.Height;
            end;
          end;
          else begin
            ScaleFactor := 1.0;
          end;
        end;

        r.Height := Trunc(r.Height * ScaleFactor);
        r.Width := Trunc(r.Width * ScaleFactor);

        // Rand-Einstellung unter Berücksichtigung des druckerabhängigen Randes
        r.Top := Trunc(PixPerInchY * BorderInMM / 25.4) - GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
        r.Height := r.Height - (2 * r.Top);
        r.Left := Trunc(PixPerInchX * BorderInMM / 25.4) - GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
        r.Width := r.Width - (2 * r.Left);

        // Ausrichtung zentriert?
        if pcHorizontal in FCentered then
        begin
          r.Left := (Printer.PageWidth - r.Width) div 2;
          r.Right := Printer.PageWidth - r.Left;
        end;
        if pcVertical in FCentered then
        begin
          r.Top := (Printer.PageHeight - r.Height) div 2;
          r.Bottom := Printer.PageHeight - r.Top;
        end;

        Printer.Title := 'Screenshot'// Wird nicht übernommen !!!???
        Application.ProcessMessages;
        Printer.BeginDoc;
        Printer.Canvas.StretchDraw(r, bmp);
        printer.EndDoc;
      finally
        Printer.Orientation := OldPO;
        ReleaseDC(TForm(Owner).Handle, dc);
      end;
    end;
  finally
    bmp.Free;
  end;
end;

end.


jasocul - Mo 11.02.13 12:10

Aaaaaaaaaaaaaaaaaaaaaargh :autsch: :autsch: :autsch: :autsch: :autsch:

Wenn man Release- und Debug-Versionen hat, sollte man schon richtig compilieren.

Thema erledigt. Sorry.


Mathematiker - Mo 11.02.13 12:11

Hallo,
ich habe Deinen Text ausprobiert (mit kleinen Änderungen, da mein Delphi 5 kein width/height bei trect mag), und es funktioniert problemlos.
Der Titel wird korrekt eingetragen.

Hast Du es schon einmal bei einem anderen Drucker kontrolliert. Es scheint so, als wäre das Problem nicht in Deinem Programm sondern vielmehr bei der Druckerverwaltung/-steuerung.

Beste Grüße
Mathematiker

Nachtrag: Mist! Ein paar Sekunden zu spät!