Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

How do I determine a printer's port?

Posted on 2011-05-10
3
Medium Priority
?
822 Views
Last Modified: 2013-11-23
I've been trying to acertain the port of a the default printer using Printers.Printer.GetPrinter() and the resulting port is not accurate, causing all sorts of issues when I try to use it.

My code is:

Procedure GetDefaultPrinterProperties;
var
  hMode   : THandle;
  pName   : PChar;
  pDriver : PChar;
  pPort   : PChar;
  sName   : string;
  sDriver : string;
  sPort   : string;
  pMode : PDevMode;
begin
  if Printer.Printers.Count = 0 then
    exit;

  pName := StrAlloc(255);
  pDriver := StrAlloc(255);
  pPort := StrAlloc(255);
  Printers.Printer.GetPrinter(pName, pDriver, pPort, hMode);
  pMode := GlobalLock(hMode);

  sPort := String(pPort);
  if Length(sPort) = 0 then
    begin
      GetProfileString('Devices', pName, '', pPort, MAX_PATH);
      sPort := String(pPort);
      i := Pos(',',sPort);
      sPort := Copy(sPort, i + 1, Length(sPort));
      i := Pos('winspool,',sPort);
      if i > 0 then
        sPort := Copy(sPort, i+9, Length(sPort));
    end;

  GlobalUnlock(hMode);
  StrDispose(pName);
  StrDispose(pDriver);
  StrDispose(pPort);
end;

I do get the pName, but the pPort and pDriver is always blank.  If I try to use GetProfileString('Devices', pName, '', pPort, MAX_PATH), it give me the wrong port.

I've been searching the web for days....

Thanks for your assistance,

Jacob
0
Comment
Question by:Jacob78
  • 2
3 Comments
 
LVL 23

Accepted Solution

by:
Ferruccio Accalai earned 2000 total points
ID: 35736414
Try this way using winspool

uses Winspool;

Function GetDefaultPrinterInfo: String;
var
  Buffer, PrinterInfo: PAnsiChar;
  I, Count, Flags, NumInfo: Cardinal;
  Level: Byte;
  DefaultPrinter: array [0..79] of Char;
  st, shared, value: String;
begin
  Result := '';
  try
    getprofilestring('windows', 'device', '', DefaultPrinter, SizeOf(DefaultPrinter) - 1);
    I := 0;
    while DefaultPrinter[I] <> ',' do
    begin
      st := st+DefaultPrinter[I];
      inc(I);
    end;
    Flags := PRINTER_ENUM_CONNECTIONS or PRINTER_ENUM_LOCAL;
    Level := 2;
    Count := 0;
    EnumPrinters(Flags, nil, Level, nil, 0, Count, NumInfo);
    if Count = 0 then
      Exit;
    GetMem(Buffer, Count);
    try
      if not EnumPrinters(Flags, nil, Level, PByte(Buffer), Count, Count, NumInfo) then
        Exit;
      PrinterInfo := Buffer;
      for I := 0 to NumInfo - 1 do
      begin
        value := '';
        shared := '';
        with PPrinterInfo2(PrinterInfo)^ do
        begin
          if pPrinterName <> nil then
            If Format('%s', [pPrinterName])= st then
            begin
              if pdriverName <> nil then
                value := Format('Driver: %s - ', [pdriverName]);
              if pPrinterName <> nil then
                value := Format('%sPrinter: %s - ', [value, pPrinterName]);
              if pServerName <> nil then
                shared := Format('%s\%s', [pServerName, pShareName])
              else if pPortName <> nil then
                shared := Format('%s', [pPortName]);
              if shared <>'' then
                value := Format('%sPort: %s', [value, shared]);
              Result := value;
              break;
            end;
          inc(PrinterInfo, SizeOf(TPrinterInfo2));
        end;
      end;
    finally
      FreeMem(Buffer, Count);
    end;
  except
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(GetDefaultPrinterInfo);
end;

Open in new window

0
 
LVL 6

Author Closing Comment

by:Jacob78
ID: 35736924
Thanks,

The code seems to work perfectly...  

A couple of questions:

1)  How could I extrapolate this code to obtain the PaperSize and PaperSource?
2)  Rather than use the code:

   getprofilestring('windows', 'device', '', DefaultPrinter, SizeOf(DefaultPrinter) - 1);
    I := 0;
    while DefaultPrinter[I] <> ',' do
    begin
      st := st+DefaultPrinter[I];
      inc(I);
    end;

Is there a downside to using the Printer.Printers[Printer.PrinterIndex] to get the Device Name of the Default printer...    This way I can get use the code to obtain information from the Default printer on load and then for any subsequent selected printer..?

Thanks again
0
 
LVL 23

Expert Comment

by:Ferruccio Accalai
ID: 35737421
Even if you use  Printer.GetPrinter(pName... you have to extract the right name from pName to use it with Winspool like GetProfileString, so it is redundant

Anyway you could combine Printer.GetPrinter and winspool.DeviceCapabilities






0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question