Ermitteln der verfügbaren Drucker und des Standarddruckers


Damit wir überhaupt drucken können, müssen wir herausfinden, welche Drucker uns eigentlich zur Verfügung stehen. Dazu bietet uns das API die Funktion EnumPrinters. Da wir uns erst einmal nur für die lokal verfügbaren Drucker interessieren, setzen wir nur das Flag PRINTER_ENUM_LOCAL. Die restlichen Parameter betreffen dann noch den Informationslevel, die Struktur, die die Daten aufnimmt, und deren Größe. Im Beispielprogramm erfolgt der Aufruf der Funktion zweimal: einmal, um die Größe der Datenmenge zu bestimmen, das zweite Mal dann für den eigentlichen Datenabruf:

EnumPrinters(PRINTER_ENUM_LOCAL, nil, 4, nil, 0, dwNeeded, dwReturn);
GetMem(pinfo4, dwNeeded);
try
  if EnumPrinters(PRINTER_ENUM_LOCAL, nil, 4, pinfo4, dwNeeded, dwNeeded, dwReturn) then
  begin
    pWork := pinfo4;

usw.

Meine Funktion "GetPrinters", die als Wrapper für "EnumPrinters" fungiert, ist so aufgebaut, dass die Struktur (quasi die ermittelten Daten) für jeden gefundenen Drucker in einer Schleife durchlaufen wird, und dass im Schleifenrumpf eine Callback-Funktion mit dem Druckernamen aufgerufen wird.

Anzumerken ist noch folgendes: Unter Windows 98/ME gibt es noch das Flag PRINTER_ENUM_DEFAULT, mit dem der Standarddrucker ermittelt werden kann. Unter Windows NT und höher gibt es das nicht mehr. Hier muss man eine weitere API-Funktion namens GetDefaultPrinter bemühen. Ich linke diese Funktion in meinem Beispielprogramm statisch

function GetDefaultPrinterA(prnName: LPTSTR; var bufSize: DWORD): BOOL; stdcall;
  external 'winspool.drv' name'GetDefaultPrinterA';
{ ...}
len := sizeof(Buffer) + 1; if GetDefaultPrinterA(Buffer, len) then begin SetDlgItemText(hWnd, IDC_CB_PRINTERS, Buffer); end;

Und da es auch den von mir benutzten Informationslevel 4 unter Windows 9x nicht gibt, ist das Beispielprogramm leider erst ab Windows NT und höher lauffähig.