unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Printers, StdCtrls, WinSpool;type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    Printer:TPrinter;
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
begin
  for i:=0 to Printer.Printers.Count-1 do
  begin
    ListBox1.Items.Add(Printer.Printers[i]);
  end;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(Printer);
end;procedure TForm1.Button2Click(Sender: TObject);
var
   ADevice,ADriver,APort:array [0..254] of char;
   ADeviceHandle:THandle;
   i:Integer;
begin
    ADeviceHandle:=0;
    if (ListBox1.ItemIndex>=0) then
    begin
       i:=ListBox1.ItemIndex;
       Printer.PrinterIndex:=ListBox1.ItemIndex;
    end;
    Printer.GetPrinter(ADevice,ADriver,APort,ADeviceHandle);
    if(ADeviceHandle<>0) then
    begin
      pDMode:=GlobalLock(ADeviceHandle);
      if(pDMode<>nil) then
      begin
        pDMode^.dmPaperSize:=DMPAPER_A4;
        pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERSIZE;
        pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERLENGTH;
        pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERWIDTH;
        ResetDC(Printer.Handle,pDMode^);
        GlobalUnlock(ADeviceHandle);
      end;
      Printer.BeginDoc;                                  
      Printer.Canvas.Font.Name := 'Times New Roman';
      Printer.Canvas.Font.Size := 9;
      Printer.Canvas.TextOut(60,60,'Hello World!');
      Printer.EndDoc;
    end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
  Printer:=TPrinter.Create;
end;end.
程序中第一个按钮是将本机所有的打印机显示出来,点击选择一个打印机后,再点button2进行打印测试。
在执行中,选择的是一个网络激光打印机,点击打印,在执行到Printer.Canvas.TextOut(60,60,'Hello World!');就报错,
Project Project.exe raised exception class EAccessViolation with message 'Access violation at address 00423ED4 in moudle 'Project.exe'....实在是看不出程序哪里有错。我试着选过一个台网络打印机,是针式的打印机,设置其DeviceMode,
pDMode^.dmPaperSize:=256;
pDMode^.dmPaperLength:=1400;
pDMode^.dmPaperWidth:=2400;
pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERSIZE;
pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERLENGTH;
pDMode^.dmFields:=pDMode^.dmFields or DM_PAPERWIDTH;试着打印,又可以打出来。但重新选择那台网络激光打印机,又是报Access violation错误 。还请高手指点,为何会这样!网络连通的,我直接选择网络激光打印机的属性中的测试页可以正常打出,但是在程序中我试着打印hello world不行。谢谢!

解决方案 »

  1.   

        if (ListBox1.ItemIndex>=0) then
        begin
           i:=ListBox1.ItemIndex;
           Printer.PrinterIndex:=ListBox1.ItemIndex;
        end;
    你这句话是切换不到你选择的打印机  PrtInfo2: PPrinterInfo2;
      .......
      Printer.SetPrinter(pchar(Printer.Printers[Printer.PrinterIndex]), PrtInfo2.pDriverName,         PrtInfo2.pPortName, 0);  这样能切换到你选择打印机上 至于你说的 
    Printer.Canvas.TextOut(60,60,'Hello World!'); 报错 
    实在想不出是什么问题,还有为什么这两句能够运行通过呢: Printer.Canvas.Font.Name := 'Times New Roman';
    Printer.Canvas.Font.Size := 9;//能设置但不能打印????还请高手前来
      

  2.   

    俺自己用ComboBox试了一下,感觉思路应该是可行的。
    而且,连接到网络上的惠普激光打印机,测试通过。
    不过,俺的测试是直接用Form.Print和Print.BeginDoc/EndDoc进行的,没有进行相关的页面设置。
    建议您检查一下打印机的手册,您所设置的参数是否可以被接受。