Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   EnumPrinters schlägt fehl (https://www.delphipraxis.net/70860-enumprinters-schlaegt-fehl.html)

Luckie 5. Jun 2006 23:43


EnumPrinters schlägt fehl
 
Ich versuche so alle lokalen Drucker zu bekommen:
Delphi-Quellcode:
procedure GetPrinters;
var
  dwNeeded         : DWORD;
  dwReturn         : DWORD;
  pinfo4            : PPrinterInfo4;
  pWork            : PPrinterInfo4;
  i                : Integer;
  s                : string;
begin
  dwNeeded := 0;
  dwReturn := 0;
  EnumPrinters(PRINTER_ENUM_LOCAL, nil, 4, nil, 0, dwNeeded, dwReturn);
  GetMem(pinfo4, dwNeeded);
  try
    if EnumPrinters(PRINTER_ENUM_LOCAL, nil, 4, PByte(pinfo4), sizeof(pinfo4), dwNeeded, dwReturn) then
    begin
      pWork := pinfo4;
      for i := 0 to dwReturn - 1 do
      begin
        s := string(pWork.pPrinterName);
        MessageBox(hApp, PChar(s), '', 0);
        Inc(pWork, sizeof(pWork));
      end;
    end
    else
      MessageBox(hApp, PChar(SysErrorMessage(GetLastError)), '', 0);
  finally
    FreeMem(pinfo4);
  end;
end;
Aber leider schlägt EnumPrinters mit der Fehlermeldung:
Zitat:

Der an einen Systemaufruf übergebene Datenbereich ist zu klein
fehl. Was ich irgendwie nicht so ganz verstehe. :gruebel:

Anstatt sizeof(pinfo4) muss es natürlich dwNeeded heißen:
Delphi-Quellcode:
procedure GetPrinters;
var
  dwNeeded         : DWORD;
  dwReturn         : DWORD;
  pinfo4            : PPrinterInfo4;
  pWork            : PPrinterInfo4;
  i                : Integer;
  s                : string;
begin
  dwNeeded := 0;
  dwReturn := 0;
  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;
      for i := 0 to dwReturn - 1 do
      begin
        s := string(pWork.pPrinterName);
        MessageBox(hApp, PChar(s), '', 0);
        Inc(pWork);
      end;
    end
    else
      MessageBox(hApp, PChar(SysErrorMessage(GetLastError)), '', 0);
  finally
    FreeMem(pinfo4);
  end;
end;

Christian Seehase 6. Jun 2006 13:28

Re: EnumPrinters schlägt fehl
 
Moin Michael,

also wenn ich Deinen Code per Copy&Paste in ein frisches Projekt eintrage, die Unit Winspool hinzufüge und dann mal hApp durch 0 austausche (sonst sehe ich die Messagebox nicht ;-)) funktioniert das.

Kannst Du noch ein paar Angaben zum System machen?

Luckie 6. Jun 2006 13:31

Re: EnumPrinters schlägt fehl
 
Oh, es ist wohl nicht deutlich geworden: Die zweite Funktion funktiobniert. Es lag daran, dass ich die falsche Größe übergheben hatte.

Olli 6. Jun 2006 14:13

Re: EnumPrinters schlägt fehl
 
Ähem, ist die Frage damit geklärt? Es wird nämlich aus der Frage nicht richtig deutlich was du meinst und aus deiner Rückantwort an Christian nicht, ob sie beantwortet ist :shock:

Mackhack 6. Jun 2006 14:45

Re: EnumPrinters schlägt fehl
 
Warum sehe ich denn nix wenn ich mir das in einem Memo anzeigen lassen will welche Printer hier drauf installiert sind mit

Delphi-Quellcode:
  Memo1.Lines.Add(GetPrinters);
Wenn ich mit einem BP arbeite sehe ich in s aber die Printer.

Luckie 6. Jun 2006 16:08

Re: EnumPrinters schlägt fehl
 
Sie IST beantwortet.

@Mackhack: Die Prozedur war noch nicht fertig. Wenn du, wie Christian hApp durch null ersetzte, siehst du immer eine Messagebox mit dem gefundenen Drucker. Hier der fertige Code:

Delphi-Quellcode:
TPrinterCallback = function(Printername: string): Boolean; stdcall;

// ...
// ...
// ...

function PrinterCallback(PrinterName: string): Boolean; stdcall;
begin
  SendDlgItemMessage(hApp, IDC_CB_PRINTERS, CB_ADDSTRING, 0, Integer(@Printername[1]));
  result := True;
end;

procedure GetPrinters(Callback: TPrinterCallback);
var
  dwNeeded         : DWORD;
  dwReturn         : DWORD;
  pinfo4            : PPrinterInfo4;
  pWork            : PPrinterInfo4;
  i                : Integer;
  s                : string;
begin
  dwNeeded := 0;
  dwReturn := 0;
  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;
      for i := 0 to dwReturn - 1 do
      begin
        s := string(pWork.pPrinterName);
        if not Callback(s) then
          break;
        Inc(pWork);
      end;
    end
    else
      MessageBox(hApp, PChar(SysErrorMessage(GetLastError)), '', 0);
  finally
    FreeMem(pinfo4);
  end;
end;
Da ich das ganze ohne VCL läuft, ich daher keine StringListen zur Verfügung habe und ich auch das ganze nicht in eine Klasse gekapselt habe und somit keine Ereignisse habe, nutze ich die Funktionalität einer Callback Funktion. Du musst also entsprechend die Callback Funktion anpassen, wenn du es so nutzen willst. Ich würde es aber so umschreiben, dass entweder eine Stringliste mit den Druckern zurückgegeben wird oder aber es in eine Klasse kapseln und bei jedem Drucker ein Ereigniss auslösen oder so.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz