Author: Jonas Bilinkevicius
I want to change the print orientation and use printer.newpage to make just one job
to print several pages.
Answer:
1 2 procedure TForm1.Button2Click(Sender: TObject);
3 var4 Device: array[0..255] of char;
5 Driver: array[0..255] of char;
6 Port: array[0..255] of char;
7 hDeviceMode: THandle;
8 pDevMode: PDeviceMode;
9 begin10 with Printer do11 begin12 BeginDoc;
13 try14 Canvas.font.size := 20;
15 Canvas.font.name := 'Arial';
16 Canvas.TextOut(50, 50, 'This is portrait');
17 GetPrinter(Device, Driver, Port, hDeviceMode);
18 pDevMode := GlobalLock(hDevicemode);
19 with pDevMode^ do20 begin21 dmFields := dmFields or DM_ORIENTATION;
22 dmOrientation := DMORIENT_LANDSCAPE;
23 end;
24 {Cannot use NewPage here since the ResetDc will only work between 25 EndPage and StartPage.26 As a consequence the Printer.PageCount is not updated.}27 Windows.EndPage(Printer.Handle);
28 if ResetDC(canvas.Handle, pDevMode^) = 0 then29 ShowMessage('ResetDC failed, ' + SysErrorMessage(GetLastError));
30 GlobalUnlock(hDeviceMode);
31 Windows.StartPage(Printer.Handle);
32 Printer.Canvas.Refresh;
33 Canvas.font.size := 20;
34 Canvas.font.name := 'Arial';
35 Canvas.TextOut(50, 50, 'This is landscape');
36 finally37 EndDoc;
38 end;
39 end;
40 end;
The orientation change requires a call to the API function ResetDC, and this function only succeeds if it is called after EndPage and before StartPage. Since the TPrinter.NewPage method does both you cannot use it. The above works but the internal page count of the Printer object is not updated, you have to maintain your own if you need to display it in the printed pages.