Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


SetPrinter Syntax

Posted on 1999-10-25
Medium Priority
Last Modified: 2012-06-21
I have tried previous answers to my question (SetPrinter Usage) of
setting a default printer for Quickreports. The code tells me that
my application knows the default printer and where it is, but
Quickreport still will not use it. I think my last chance is to try 'SetPrinter'
if anyone can show me how ?

      Thanks Paul.
Question by:pr_wainwright
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Expert Comment

ID: 2155541
LVL 10

Expert Comment

ID: 2155646
Actually, you have two alternatives to set the Windows default printer. One is for WIn95 only (the SetPrinter API) and the other is for all Win platforms (even 3.1, 3.11):

Win95 only:

   SetPrinter(HANDLE hPrinter, DWORD dwLevel, LPBYTE lpbPrinter,
      DWORD dwCommand)

Obtain the hPrinter parameter from OpenPrinter() as a handle that identifies the desired printer. Set the dwLevel parameter to 5, and point lpbPrinter to the PRINTER_INFO_5 structure. Set the dwCommand parameter to 0. Fill out the PRINTER_INFO_5 structure appropriately making sure that the Attributes field has PRINTER_ATTRIBUTE_DEFAULT set.

Note: Unfortunately, Printers.pas does not expose FPrinterHandle which could be used in this call.

For all Windows versions:

In all versions of Windows, the appropriate way to get the default printer is to use GetProfileString, and the appropriate way to set the default printer is to use WriteProfileString. This works whether the default printer information is stored in the WIN.INI file or in the registry.


Notes to Keep in Mind
The Device value you get or set actually contains three elements separated by commas as follows:

      <printer name>,<driver name>,<port>

For example:

      My Printer,HPPCL5MS,lpt1:

When setting the default printer, you must specify valid names for these elements. That is, you must specify a valid printer, driver, and port. If not, programs such as Print Manager may set the printer back to the previous valid printer, and other programs may become very confused. You can use the EnumPrinters API to retrieve the printer name, driver name, and port name of all available printers.
Windows 95 and Windows NT map most .INI file references to the registry. Because of this mapping, GetProfileString and WriteProfileString still function as they do under 16-bit Windows (Microsoft Windows and Windows for Workgroups).
After setting the default printer, notify all other applications of the change by broadcasting the WM_WININICHANGE message.

Sample Code

   // This code uses a sample profile string of "My Printer,HPPCL5MS,lpt1:"
   // To get the default printer for Windows 3.1, Windows 3.11,
   // Windows 95, and Windows NT use:
   GetProfileString('windows', 'device', ',,,', buffer, sizeof(buffer));


   // To set the default printer for Windows 3.1 and Windows 3.11 use:
   WriteProfileString('windows', 'device', 'My Printer,HPPCL5MS,lpt1:');


   // To set the default printer for Windows 95 use:
   WriteProfileString('windows', 'device', 'My Printer,HPPCL5MS,lpt1:');
   Integer(PChar('windows)), SMTO_NORMAL, 1000, nil);


   // To set the default printer for Windows NT use:
   { Note printer driver is usually WINSPOOL under Windows NT }
   WriteProfileString('windows', 'device', 'My Printer,WINSPOOL,lpt1:');
  SMTO_NORMAL, 1000, nil);

There are two circumstances where the code won't work:

If the customer leaves out the SendMessage, no other application will recognize the change in the .INI settings.

If a different 32-bit application does not handle the WIN.INI change message, then it will appear to that application as if the default printer has not been changed. The user will need to exit and re-enter Windows 95 to have the other application recognize the printer change.

This is the preferred method of changing the printer if the code is to be platform independent; this method will work on Windows 3.1, Windows 95 and Windows NT.

Hope this works for you!

Ciao, Mike

Expert Comment

ID: 2155671
I didn't see your previous question, but I'll try a few things here, including, at the end, answering your original question.

The first thing you should try is to (Quote from the help):

"Set QuickRep.PrinterSettings.PrinterIndex to a value corresponding to the printer you want to print to. This value is the same as for the Delphi TPrinter.PrinterIndex. Set to -1 to print to the default printer again."

Now, SetPrinter.  There are two Setprinter functions, the first is an internal TPrinter function, which I'm not going to tell you how to use directly, because you shouldn't.  If you want to see how it is used internally, look in the call to it in TPrinter.SetToDefaultPrinters in Printers.Pas (in your Delphi VCL sources).

The Windows API also has a SetPrinter function, and this one, although I'll show you how to call it, doesn't really do what you want, as it is used for doing one of the following things to a printer:  Getting status info, purging it's queue, pausing it, resuming it, restarting it.  Not selecting it.

The parameters are

SetPrinter(Handle, // gotten by a call to OpenPrinter
               Level ,  // 0 for command, 2-6 (opsys dependant)
                          // for type  of structure to return
             pprinter, // printer info structure, depending on the
                          // value of Level.  6 only under NT, 4 only
                          // 9x.  See the Windows docs for their
                         // contents.  NULL for Level of 0.
             command); // Pause, purge, resume or set-status,
                        // When level  is 0.

As you can see, this is not really what you want.  Although I didn't see your original question, I think my original comment is the correct solution.

Accepted Solution

CameronCole earned 300 total points
ID: 2156469
I hope SetPrinter works for you, but if it doesn't you can expose the TQRPrinter object and set its properties directly.  For some odd reason, QR subclasses the printer object and attempts to set the properties equal to the current printer object.  It misses several (like the bin for example).  We just go in and change theirs directly.

Luck, C.

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Suggested Courses

670 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