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

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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
How to fix display issue, screen flickering issue when I plug in power cord to the machine. Before I start explaining the solution lets check out once the issue how it looks like after I connect the power cord. most of you also have faced this…
This video tutorial shows you the steps to go through to set up what I believe to be the best email app on the android platform to read Exchange mail.  Get the app on your phone: The first step is to make sure you have the Samsung Email app on your …

624 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