如何在 TpagesetupDlg 中用打印机信息而不是 Delphi 中的默认值填充记录?



我拼命寻找如何在不调用对话框的情况下向 StartDoc()StartPage() 等 API 函数提供非默认打印机信息。

发现我必须用适当的值(尤其是devNames结构(填充TPageSetupDlgTPrintDlg,但我不知道该怎么做。

编辑

编写了这段有效的代码,但它不会像我想要的那样改变横向的方向。可能我没有正确填充开发模式结构。

procedure TForm1.ButtonXClick(Sender: TObject);
type
    TdevNames = record
        wDriverOffset : WORD;
        wDeviceOffset : WORD;
        wOutputOffset : WORD;
        wDefault : WORD;
    end;
    TdevMode = record
        dmDeviceName : array[0..CCHDEVICENAME-1] of char;
        dmSpecVersion : WORD;
        dmDriverVersion: WORD;
        dmSize: WORD;
        dmDriverExtra: WORD;
        dmFields : DWORD;
        dmOrientation : short;
        dmPaperSize : short;
        dmPaperLength : short;
        dmPaperWidth : short;
        dmScale : short;
        dmCopies : short;
        dmDefaultSource : short;
        dmPrintQuality : short;
        dmColor : short;
        dmDuplex : short;
        dmYResolution : short;
        dmTTOption : short;
        dmCollate : short;
        dmFormName : array[0..CCHFORMNAME-1] of char;
        dmLogPixels : WORD;
        dmBitsPerPel : DWORD;
        dmPelsWidth : DWORD;
        dmPelsHeight : DWORD;
        dmNup : DWORD;
       dmDisplayFrequency : DWORD;
    end;
var
    DocInfo: TDocInfo;
    devNames : TdevNames;
    aDC : hDC;
    devMode : TdevMode;
    str1, str2 : string;
const
    DOC_NAME = 'Stack Overflow';
    FILE_NAME = 'test.xps';
    MAX_PATH = 260;
begin
        devMode := default(TdevMode);
        devMode.dmSize := sizeof(TDEVMODE);
        devMode.dmPaper.dmOrientation := DMORIENT_LANDSCAPE;
        devMode.dmFields := DM_ORIENTATION;
        aDC := createDC('',pchar('Microsoft XPS Document Writer'),@devMode,0);
        DocInfo := Default(TDocInfo);
        DocInfo.cbSize := SizeOf(DocInfo);
        GetMem(DocInfo.lpszDocName, 32);
        GetMem(DocInfo.lpszOutput, MAX_PATH);
        lStrCpynW(DocInfo.lpszDocName, DOC_NAME, Length(DOC_NAME) * sizeof(char));
        lStrCpynW(DocInfo.lpszOutput, FILE_NAME, Length(FILE_NAME) * sizeof(char));
        StartDoc(aDC, DocInfo);
        StartPage(aDC);
    str1 := 'page 1';
    str2 := 'page 2';
        TextOut(aDC, 100, 100, pchar(str1), length(str1));
        EndPage(aDC);
        StartPage(aDC);
        TextOut(aDC, 100, 100, pchar(str2), length(str2));
        EndPage(aDC);
        EndDoc(aDC);
        FreeMem(DocInfo.lpszDocName, 32);
        FreeMem(DocInfo.lpszOutput, MAX_PATH);
        shellExecute(application.Handle,'open',FILE_NAME,'','',SW_MAXIMIZE);
        deleteDC(aDC);
end;

不应手动声明TDevNamesTDevMode记录类型。 分别使用 Delphi Winapi.CommDlgWinapi.Windows 单位中的现有声明。

您也不正确地调用CreateDC()。 事实上,您的代码甚至不应该编译,因为您要在预期PChar的地方传递PDEVMODE,并在预期PDEVMODE的地方传递Integer

您还应该检查 API 调用是否存在错误。

尝试更多类似的东西:

uses
  ..., Winapi.Windows, Winapi.CommDlg;
procedure TForm1.ButtonXClick(Sender: TObject);
var
  lDocInfo: DOCINFO;
  lDevMode: DEVMODE;
  lDC: hDC;
  str: string;
const
  DOC_NAME = 'Stack Overflow';
  FILE_NAME = 'test.xps';
begin
  lDevMode := default(DEVMODE);
  lDevMode.dmSize := sizeof(lDevMode);
  lDevMode.dmFields := DM_ORIENTATION;
  lDevMode.dmOrientation := DMORIENT_LANDSCAPE;
  lDC := CreateDC(nil, 'Microsoft XPS Document Writer', nil, @lDevMode);
  if lDC = 0 then
    raise Exception.Create('Unable to open printer');
  try
    lDocInfo := Default(DOCINFO);
    lDocInfo.cbSize := SizeOf(lDocInfo);
    lDocInfo.lpszDocName := DOC_NAME;
    lDocInfo.lpszOutput := FILE_NAME;
    if StartDoc(lDC, lDocInfo) <= 0 then
      raise Exception.Create('Unable to start print document');
    try
      if StartPage(lDC) <= 0 then
        raise Exception.Create('Unable to start a new print page');
      str := 'page 1';
      TextOut(lDC, 100, 100, PChar(str), Length(str));
      EndPage(lDC);
      if StartPage(lDC) <= 0 then
        raise Exception.Create('Unable to start a new print page');
      str := 'page 2';
      TextOut(lDC, 100, 100, PChar(str), Length(str));
      EndPage(lDC);
      EndDoc(lDC);
    except
      AbortDoc(lDC);
      raise;
    end;
  finally
    DeleteDC(lDC);
  end;
  if ShellExecute(Handle, 'open', FILE_NAME, nil, nil, SW_MAXIMIZE) < 32 then
    raise Exception.Create('Unable to open printed file');
end;

如果仍然无法横向打印,则问题出在 XPS 驱动程序本身,而不是代码。

最新更新