2010-04-08 98 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