2010-04-08 94 views
2

我使用这个程序列出一台机器上安装的本地打印机:列表本地打印机

var 
    p: pointer; 
    hpi: _PRINTER_INFO_2A; 
    hGlobal: cardinal; 
    dwNeeded, dwReturned: DWORD; 
    bFlag: boolean; 
    i: dword; 
begin 
    p := nil; 
    EnumPrinters(PRINTER_ENUM_LOCAL, nil, 2, p, 0, dwNeeded, dwReturned); 
    if (dwNeeded = 0) then exit; 
    GetMem(p,dwNeeded); 
    if (p = nil) then exit; 
    bFlag := EnumPrinters(PRINTER_ENUM_LOCAL, nil, 2, p, dwneeded, dwNeeded, dwReturned); 
    if (not bFlag) then exit; 
    CbLblPrinterPath.Properties.Items.Clear; 
    for i := 0 to dwReturned - 1 do 
    begin 
    CbLblPrinterPath.Properties.Items.Add(TPrinterInfos(p^)[i].pPrinterName); 
    end; 
    FreeMem(p); 

TPrinterInfos(p^)[i].pPrinterName返回打印机名称“P”。我有一台PdfCreator作为打印机安装。

TPrinterInfos_PRINTER_INFO_2A的数组。

我该如何解决这个问题?

回答

3

好的,第一件事第一......因为你标记了这个德尔福2010年,我假设你有这个问题与D2010。

您的问题开始于您使用_PRINTER_INFO_2A,这是函数EnumPrinters的Ansi版本使用的结构。自引入unicode以来,“EnumPrinters”函数映射到该函数的unicode版本,因此您应该使用_PRINTER_INFO_2W。 (或者显式调用EnumPrintersA)。如果您使用EnumPrinters(不带A/W),则应使用_PRINTER_INFO_2(不含A/W)。这样,如果有一天UTF32版本成为新标准,它将不太可能中断。

+0

谢谢你,那是我需要的。 – vladimir 2010-04-09 15:43:42

2

由于您使用Unicode德尔福版本,你应该使用_PRINTER_INFO_2W结构,而不是_PRINTER_INFO_2A

2

您可以通过简单地使用打印机变量提供的列表中获得本地打印机的列表。简单如

uses Printers; 
... 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
    Memo1.Lines.Assign(Printer.Printers); 
end; 

我会使用这种方法,除非你有特定的理由做你在做什么。

+1

Printer.Printers不仅仅给本地打印机。 – 2010-04-08 17:02:05

+0

并且该列表从不更新(只读一次) – Remko 2010-04-08 19:34:32

+0

@Remko可以执行以下语句来刷新打印机列表: Printer.Refresh; – 10100111001 2015-11-11 14:49:06