gpt4 book ai didi

delphi - 如何使用WinSpool API设置纸张尺寸?

转载 作者:行者123 更新时间:2023-12-03 15:45:32 25 4
gpt4 key购买 nike

我无法使用 XPS API,因为该程序必须能够在 Windows XP 上进行打印。

我正在尝试使用 WinSpool 将纸张尺寸从 Letter 设置为 A4。

这是我的测试代码:

var
H : THandle;
I : TBytes;
Info : PPrinterInfo2;
NeededSize : DWORD;
DevMode : PDeviceMode;
PD : TPrinterDefaults;
begin
PD.pDatatype := nil;
PD.pDevMode := nil;
PD.DesiredAccess := PRINTER_ACCESS_ADMINISTER;
if not OpenPrinter('Brother HL-5350DN series Printer', H, @PD) then begin
raise Exception.Create('OpenPrinter error: ' + SysErrorMessage(GetLastError));
end;
try
Assert(not GetPrinter(H, 2, nil, 0, @NeededSize));
SetLength(I, NeededSize);
Info := @I[0];
if not GetPrinter(H, 2, Info, NeededSize, @NeededSize) then begin
raise Exception.Create('GetPrinter error: ' + SysErrorMessage(GetLastError));
end;
DevMode := Info.pDevMode;
DevMode.dmFields := DevMode.dmFields or DM_PAPERSIZE;
DevMode.dmPaperSize := DMPAPER_A4;
Info.pSecurityDescriptor := nil; // According to MSDN it has to be niled if we're not going to change it.

if not SetPrinter(H, 2, Info, 0) then begin
raise Exception.Create('SetPrinter error: ' + SysErrorMessage(GetLastError));
end;
finally
ClosePrinter(H);
end;
TPrintDialog.Create(Self).Execute; // This is just so I can check the paper size
end;

我有两个与访问权限相关的问题。

如果我设置PD.DesiredAccessPRINTER_ACCESS_ADMINISTER GetPrinter调用失败,估计是UAC的原因。

如果我将其设置为 PRINTER_ACCESS_USE GetPrinter调用成功并且 Info 结构良好,但是对 SetPrinter 的调用失败。

有趣的是,当我忽略 SetPrinter 的结果时打印对话框将 A4 报告为打印机尺寸,即使 SetPrinter失败。

我这样做是否完全错误,将正确设置的 PDeviceMode 传递给 OpenPrinter 就足够了? (我实际上是在写完这个问题后想到的:-)

关于 VCL 的另一个问题:

如果我使用Printers单位我如何知道缓冲区必须有多大才能作为参数传递给 TPrinter.GetPrinter方法?

背景:

系统是:Windows 7 Professional 64-Bit English,语言环境为英语。

我正在尝试在网络打印机 (Brother HL-5350DN) 上打印到 A4 纸。

我已将控制面板中的所有打印机设置设置为 A4 纸张,但我正在编写的 Delphi 2009 程序仍然获取 US Letter 的纸张尺寸。

换句话说:Delphi 程序不尊重打印机后台处理程序的默认设置。

如果我首先运行 TPrinterDialog 并从那里手动选择正确的纸张尺寸(在高级打印机设置中),一切都会很好。

该程序必须在没有任何 UI 的情况下运行,因此我必须以编程方式解决此问题,或者最好该程序应该遵循默认的 Windows 打印机后台处理程序设置。

也许我错过了一些重要的设置?

最佳答案

试试这个它对我有用

uses WinSpool,Windows,System;

procedure SetPrinterInfo(APrinterName: PChar);
var

HPrinter : THandle;
InfoSize,
BytesNeeded: Cardinal;
DevMode : PDeviceMode;
PI2: PPrinterInfo2;
PrinterDefaults: TPrinterDefaults;

begin
with PrinterDefaults do
begin
DesiredAccess := PRINTER_ACCESS_USE;
pDatatype := nil;
pDevMode := nil;
end;
if OpenPrinter(APrinterName, HPrinter, @PrinterDefaults) then
try
SetLastError(0);
//Determine the number of bytes to allocate for the PRINTER_INFO_2 construct...
if not GetPrinter(HPrinter, 2, nil, 0, @BytesNeeded) then
begin
//Allocate memory space for the PRINTER_INFO_2 pointer (PrinterInfo2)...
PI2 := AllocMem(BytesNeeded);
try
InfoSize := SizeOf(TPrinterInfo2);
if GetPrinter(HPrinter, 2, PI2, BytesNeeded, @BytesNeeded) then
begin
DevMode := PI2.pDevMode;
DevMode.dmFields := DevMode.dmFields or DM_PAPERSIZE;
DevMode.dmPaperSize := DMPAPER_A4;
PI2.pSecurityDescriptor := nil;
// Apply settings to the printer
if DocumentProperties(0, hPrinter, APrinterName, PI2.pDevMode^,
PI2.pDevMode^, DM_IN_BUFFER or DM_OUT_BUFFER) = IDOK then
begin
SetPrinter(HPrinter, 2, PI2, 0); // Ignore the result of this call...
end;
end;
finally
FreeMem(PI2, BytesNeeded);
end;
end;
finally
ClosePrinter(HPrinter);
end;
end;

关于delphi - 如何使用WinSpool API设置纸张尺寸?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6890554/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com