Newsgroup: it.comp.lang.delphi
Titolo: Selezionare la stampante predefinita

Salve a tutti.
Qualcuno sà come settare la stampante predefinita da un programma delphi?
grazie, ciao!
Paolo.

printer.printers è quello che devi utilizzare. Includi in uses printers
il printer.printerindex devi settarlo a -1

Ciao, paolo.
Anch'io ho avuto, come penso molti, un bel po' di grane con la 'stampante di
default', soprattutto utilizzando quickreport.
Per tagliare la testa al toro, ho preso la relativa documentazione ufficiale
Microsoft (MSDN) e l'ho portata in pascal.
Qui sotto trovi due funzioni, DPGetDefaultPrinter e DPSetDefaultPrinter.
La prima torna il nome della stampante corrente, la seconda lo imposta.
Il nome *deve* essere uno di quelli che windows ha registrati come
stampanti.
Ti allego il testo di un piccolo programma e relativa form che fà quanto
detto.
Spero sia utile.
Ciao.
---TestPrinters.dpr---
program TestPrinters;
uses
  Forms,
  _TestPrinters in '_TestPrinters.pas' {TestPrintersFm};
{$R *.RES}
begin
  Application.Initialize;
  Application.CreateForm(TTestPrintersFm, TestPrintersFm);
  Application.Run;
end.
---_testPrinters.pas-------------------------------------
//==========================================================================
====
// (C) 2001 - Multiware snc - Pesaro (Andrea Belli)
//==========================================================================
====
unit _TestPrinters;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Printers, WinSpool;
type
  TTestPrintersFm = class(TForm)
    Button1: TButton;
    Button3: TButton;
    cbPrinters: TComboBox;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    currentPrinter,
    defaultPrinter :string;
  end;
//--------------------------------------------------------------------------
----
// Funzioni accessorie
//--------------------------------------------------------------------------
----
function DPGetDefaultPrinter :string;
function DPSetDefaultPrinter(printerName :string) : boolean;
//--------------------------------------------------------------------------
----
const
 MAX_BUFFER  = 1024;
//--------------------------------------------------------------------------
----
var
  TestPrintersFm: TTestPrintersFm;
//--------------------------------------------------------------------------
----
implementation
//--------------------------------------------------------------------------
----
{$R *.DFM}
//==========================================================================
====
procedure TTestPrintersFm.FormCreate(Sender: TObject);
//==========================================================================
====
begin
 // Fill del combo
 cbPrinters.Items.Assign(Printer.Printers);
   // Visualizzo la stampante corrente
   Button3Click(Self);
end;
//==========================================================================
====
procedure TTestPrintersFm.Button1Click(Sender: TObject);
//==========================================================================
====
begin
 if not DPSetDefaultPrinter(cbPrinters.Text) then
    ShowMessage('Stampante non valida');
end;
//==========================================================================
====
procedure TTestPrintersFm.Button3Click(Sender: TObject);
//==========================================================================
====
begin
   cbPrinters.Text := DPGetDefaultPrinter;
end;
//==========================================================================
====
// Traduzione in pascal di ciò che mamma Microsoft dice di fare per
selezionare
// o impostare la stampante di default a seconda della versione di Windows.
//==========================================================================
====
// DPGetDefaultPrinter
//
// Parameters:
//   pPrinterName: Buffer alloc'd by caller to hold printer name.
//   pdwBufferSize: On input, ptr to size of pPrinterName.
//          On output, min required size of pPrinterName.
//
// NOTE: You must include enough space for the NULL terminator!
//
// Returns: TRUE for success, FALSE for failure.
//==========================================================================
====
function DPGetDefaultPrinter : string;
//==========================================================================
====
var
 idx   :integer;
 bFlag   :boolean;
 osv   :OSVERSIONINFO;
 cBuffer  :array[0..MAX_BUFFER] of char;
 ppi2   :pPrinterInfo2A;
 dwNeeded  :DWORD;
 dwReturned :DWORD;
begin
 Result := 'no printer found';
 // What version of Windows are you running?
 osv.dwOSVersionInfoSize := sizeof(OSVERSIONINFO);
 GetVersionEx(osv);
 // If Windows 95 or 98, use EnumPrinters...
 if (osv.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS) then begin
  // The first EnumPrinters() tells you how big our buffer should
  // be in order to hold ALL of PRINTER_INFO_2. Note that this will
  // usually return FALSE. This only means that the buffer (the 4th
  // parameter) was not filled in. You don't want it filled in here...
  EnumPrinters(PRINTER_ENUM_DEFAULT, nil, 2, nil, 0, dwNeeded, dwReturned);
  if (dwNeeded > 0) then begin
   // Allocate enough space for PRINTER_INFO_2...
   GetMem(ppi2, dwNeeded);
   // The second EnumPrinters() will fill in all the current information...
   bFlag := EnumPrinters(PRINTER_ENUM_DEFAULT, nil, 2, ppi2, dwNeeded,
dwNeeded, dwReturned);
   if (not bFlag) then
          FreeMem(ppi2)
         else begin
    // Copy printer name into passed-in buffer...
    Result := StrPas(ppi2.pPrinterName);
   end;
   FreeMem(ppi2);
      end;
   end
   else
  // If Windows NT, use the GetDefaultPrinter API for Windows 2000,
  // or GetProfileString for version 4.0 and earlier...
  if (osv.dwPlatformId = VER_PLATFORM_WIN32_NT) then begin
   // Retrieve the default string from Win.ini (the registry).
   // String will be in form "printername,drivername,portname".
   if GetProfileString('windows', 'device', ',,,', cBuffer, MAX_BUFFER) > 0
then begin
    // Printer name precedes first "," character...
            idx := Pos(',', StrPas(cBuffer));
    // Copy printer name into passed-in buffer...
    Result := Copy(StrPas(cBuffer), 1, idx-1);
   end;
      end;
end;
//==========================================================================
====
// DPSetDefaultPrinter
//
// Parameters:
//   pPrinterName: Valid name of existing printer to make default.
//
// Returns: TRUE for success, FALSE for failure.
//==========================================================================
====
function DPSetDefaultPrinter(printerName :string) : boolean;
var
 bFlag   :boolean;
 osv   :OSVERSIONINFO;
 dwNeeded,
   wResult  :DWORD;
 hPrinter  :THandle;
 ppi2   :pPrinterInfo2A;
 Buffer  :string;
begin
 Result := False;
 if length(trim(printerName))>0 then begin
  // What version of Windows are you running?
  osv.dwOSVersionInfoSize := sizeof(OSVERSIONINFO);
  GetVersionEx(osv);
  // If Windows 95 or 98, use SetPrinter...
  if (osv.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS) then begin
   // Open this printer so you can get information about it...
   bFlag := OpenPrinter(pchar(printerName), hPrinter, nil);
   if bFlag or (hPrinter<>0) then begin
    // The first GetPrinter() tells you how big our buffer should
    // be in order to hold ALL of PRINTER_INFO_2. Note that this will
    // usually return FALSE. This only means that the buffer (the 3rd
    // parameter) was not filled in. You don't want it filled in here...
    GetPrinter(hPrinter, 2, nil, 0, @dwNeeded);
    if (dwNeeded = 0) then
         ClosePrinter(hPrinter)
            else begin
     // Allocate enough space for PRINTER_INFO_2...
               GetMem(ppi2, dwNeeded);
     if not Assigned(ppi2) then
          ClosePrinter(hPrinter)
               else begin
      // The second GetPrinter() will fill in all the current information
      // so that all you need to do is modify what you're interested in...
      bFlag := GetPrinter(hPrinter, 2, ppi2, dwNeeded, @dwNeeded);
      if (not bFlag) then begin
       ClosePrinter(hPrinter);
       FreeMem(ppi2);
                  end
                  else begin
       // Set default printer attribute for this printer...
       ppi2.Attributes := ppi2.Attributes or PRINTER_ATTRIBUTE_DEFAULT;
       bFlag := SetPrinter(hPrinter, 2, ppi2, 0);
       if not bFlag then begin
        ClosePrinter(hPrinter);
        FreeMem(ppi2);
                     end
                     else begin
        // Tell all open applications that this change occurred.
        // Allow each application 1 second to handle this message.
        Result := boolean(SendMessageTimeout(
                         HWND_BROADCAST,
                           WM_SETTINGCHANGE,
                           0,
         0,
                           SMTO_NORMAL,
                           1000,
                           wResult
                        )
                        );
                     end;
                  end;
               end;
            end;
         end;
      end
    else
         // If Windows NT, use WriteProfileString
         if (osv.dwPlatformId = VER_PLATFORM_WIN32_NT) then begin
            // Open this printer so you can get information about it...
            bFlag := OpenPrinter(pchar(printerName), hPrinter, nil);
            if bFlag or (hPrinter<>0) then begin
               // The first GetPrinter() tells you how big our buffer should
               // be in order to hold ALL of PRINTER_INFO_2. Note that this
will
               // usually return FALSE. This only means that the buffer (the
3rd
               // parameter) was not filled in. You don't want it filled in
here...
               GetPrinter(hPrinter, 2, nil, 0, @dwNeeded);
               if (dwNeeded = 0) then
                  ClosePrinter(hPrinter)
               else begin
                  // Allocate enough space for PRINTER_INFO_2...
                  GetMem(ppi2, dwNeeded);
                  if not Assigned(ppi2) then
                     ClosePrinter(hPrinter)
                  else begin
                     // The second GetPrinter() fills in all the current
                     // information...
                     bFlag := GetPrinter(hPrinter, 2, ppi2, dwNeeded,
@dwNeeded);
                     if (not bFlag) or (ppi2.pDriverName='') or
(ppi2.pPortName='') then begin
                        ClosePrinter(hPrinter);
                        FreeMem(ppi2);
                     end
                     else begin
                        // Build string in form
"printername,drivername,portname"...
                        Buffer :=
printerName+','+ppi2.pDrivername+','+ppi2.pPortName;
                        // Set the default printer in Win.ini and
registry...
                        if not WriteProfileString('windows', 'device',
pchar(Buffer)) then begin
                           ClosePrinter(hPrinter);
                           FreeMem(ppi2);
                        end
                        else begin
                           // Tell all open applications that this change
occurred.
                           // Allow each app 1 second to handle this
message.
                           Result := boolean(
                              SendMessageTimeout(
                                 HWND_BROADCAST,
                                 WM_SETTINGCHANGE,
                                 0,
                                 0,
                                 SMTO_NORMAL,
                                 1000,
                                 wResult
                              )
                           );
                           ClosePrinter(hPrinter);
                           FreeMem(ppi2);
                        end;
                     end;
                  end;
               end;
            end;
         end;
      end;
end;
//==========================================================================
====
end.
---_TestPrinters.dfm---------------------
object TestPrintersFm: TTestPrintersFm
  Left = 412
  Top = 254
  BorderStyle = bsDialog
  Caption = 'TestPrintersFm'
  ClientHeight = 35
  ClientWidth = 413
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 84
    Top = 4
    Width = 75
    Height = 25
    Caption = 'Set'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Button3: TButton
    Left = 4
    Top = 4
    Width = 75
    Height = 25
    Caption = 'Get'
    TabOrder = 1
    OnClick = Button3Click
  end
  object cbPrinters: TComboBox
    Left = 164
    Top = 7
    Width = 246
    Height = 21
    ItemHeight = 13
    TabOrder = 2
  end
end

xche non la posti a msx che la mette sulle faq?
Inoltre, su quali versioni di WinSozz funziona?
Bye
AS
"Se è Microsoft non funziona"
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 Inoltre, su quali versioni di WinSozz funziona?
Articolo di riferimento :
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q246772
Non č molto che sguazzo per il ng, ma da quel che ho capito {msg} č una
specie di moderatore ?
Dimmi di piů sul come faccio a postare un msg direttamente a lui, che poi lo
faccio.
Grazie
In merito alle due funzioni, io le ho utilizzate su NT4, 2000, 98, XP ed ME,
con una (o due) eccezioni :
1)  Ok su NT,2000&XP. Su 9x/ME, il nomi delle stampanti ritornato dalla
Printer.Printers di delphi (almeno della 6) ha in piů, oltre al nome, la
porta su cui č installata.
Per cui, la stessa stampante installata su XP e su ME risulta essere :
Xp : "HP DeskJet 890C"
Me : "HP DeskJet 890C on LPT1:"
Qui il problema č di Delphi, non di windows (ahimč...)
Probabilmente utilizzando sempre la WinAPI EnumPrinters si dovrebbe riuscire
ad avere un elenco 'corretto' dei nomi delle stampanti installate, solo che
ora non ho il tempo di verificarlo.
2) La mia traduzione differisce da quella MS relativamente al metodo
utilizzato in caso di WinNT4 o superiore; Infatti ho visto che utilizzando
il metodo di NT4 č tutto ok anche su 2000 e XP, ed ho sacrificato l'elegante
utilizzo della GetDefaultPrinter (2000 o >) per qualche riga in meno da
tradurre.
Ciao.

Ringrazio tutti per l'interessamento... proverò subito le soluzioni che mi
avete fornito e vi farò sapere se è andato tutto ok e su quali SO.
Ciao,
Paolo.