Click here to Skip to main content
15,886,026 members
Articles / Desktop Programming / MFC

Setting the Default Printer Programmatically in an MFC Application

Rate me:
Please Sign up or sign in to vote.
4.84/5 (20 votes)
11 Jun 2002CPOL2 min read 241.6K   4.1K   50   43
How to change the default printer in MFC and save/restore this setting to/from the registry

Overview

In a standard MFC application, the system wide default printer will be setup as default each time your application starts. This is done during your CWinApp objects initialization, when it calls the function CWinApp::UpdatePrinterSelection(). This sets up the m_hDevMode and m_hDevNames global handles (as in global memory handles used with GlobalLock/Unlock) which CWinApp uses to manage the selected printer.

I have provided a wrapper class for enumPrinters, which is used to gather information on the locally installed printers which is needed when switching printers. It can also set the printers when called by a function in your CWinApp derived class and passing through m_hDevMode and m_hDevNames as references, so they can be changed.

When switching printers programmatically, you need to know:

  • The printer's name, e.g., HP Laserjet 4L
  • The port the printer is installed on, e.g., LPT1:
  • The spooler that will dump the printout to the printer, usually winspool

Details

The class CEnumPrinters encapsulates the required functionality needed to query for the locally setup printers. This list can then be read/used to select new printers and set them as the new default printer to be used by the application.

Example list of printers

Restoring the Selected Printer

You can save the selected printer to the registry and restore it also. To do this, you need to place calls to CEnumPrinters::SavePrinterSelection() and CEnumPrinters::RestorePrinterSelection() in your application's ExitInstance and InitInstance procedures.

The information saved is:

  • The printer name
  • The spooling device
  • The port name
  • The page orientation (portrait or landscape)

Class Interface

The following functions are used in the class:

  • int GetPrinterCount() ;
  • CString GetPrinterName(int index) ;
  • CString GetPrinterLocation(int index) ;
  • CString GetPrinterShareName(int index) ;
  • CString GetPrinterPortName(int index) ;
  • void ReadLocalPrinters() ;

The above functions enumerate the list of locally installed printers - automatically called in class constructor.

  • bool SetNewPrinter(HANDLE& hDevMode, HANDLE& hDevNames, const CString& PrinterName, const CString& PrinterSpooler, const CString& PrinterPort) ;

Use the function above when switching to a printer by Name, driver, port

  • bool SetNewPrinter(HANDLE& hDevMode, HANDLE& hDevNames, int index) ;

Use the function above when switching to a printer in the local list by index

  • bool SetPrintOrientation(HANDLE &hDevMode, int mode) ;

Use the above function to switch between portrait and landscape page orientations.

  • bool SavePrinterSelection(HANDLE &hDevMode, HANDLE& hDevNames) ;
  • bool RestorePrinterSelection(HANDLE &hDevMode, HANDLE& hDevNames) ;

These procedures save/restore the selected printer from the registry (key PrinterConfig)

Future Enhancements or Coding Projects

  • Add functionality to query network printers
  • Add functionality to add a new printer

Enjoy!

Revision History

  • 12th June, 2002 - Initial revision

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Sirius Analytical Instruments
United Kingdom United Kingdom
A research and development programmer working for a pharmaceutical instrument company for the past 17 years.

I am one of those lucky people who enjoys his work and spends more time than he should either doing work or reseaching new stuff. I can also be found on playing DDO on the Cannith server (Send a tell to "Maetrim" who is my current main)

I am also a keep fit fanatic, doing cross country running and am seriously into [url]http://www.ryushinkan.co.uk/[/url] Karate at this time of my life, training from 4-6 times a week and recently achieved my 1st Dan after 6 years.

Comments and Discussions

 
Questionset pagesize? Pin
wxzhao12-Dec-02 16:20
wxzhao12-Dec-02 16:20 
GeneralEnumJobs cannot see multiple copies in Word2000 Pin
Rasho13-Oct-02 21:47
Rasho13-Oct-02 21:47 
Generalservant of printers Pin
Xjenny_62-Oct-02 1:31
Xjenny_62-Oct-02 1:31 
GeneralAddional functionality Pin
Roger Allen30-May-02 0:26
Roger Allen30-May-02 0:26 
QuestionNetworked Printers? Pin
Paresh Solanki8-May-02 0:35
Paresh Solanki8-May-02 0:35 
AnswerRe: Networked Printers? Pin
Paresh Solanki8-May-02 0:37
Paresh Solanki8-May-02 0:37 
GeneralRe: Networked Printers? Pin
Roger Allen8-May-02 0:56
Roger Allen8-May-02 0:56 
AnswerRe: Networked Printers? Pin
Roger Allen8-May-02 0:55
Roger Allen8-May-02 0:55 
I did do some work on this. You can do it by adding a function to CEnumPrinters which takes the name of the computer on the network that you want to check. It will be almost exactly the same as the function ReaLocalPrinters. Somthing like:

void CEnumPrinters::ReadRemotePrinters(CString computer)
{
	// theres a flag you can set here for remote printers, but I dont have my MSDN at the moment
	// so I cannot say what it is. :(
	DWORD		Flags = PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL; | PRINTER_ENUM_REMOTE?
	DWORD		cbBuf;
	DWORD		pcReturned ;
	DWORD		index;
	DWORD		Level = 2;
	TCHAR		Name[500] ;
	LPPRINTER_INFO_2 pPrinterEnum = NULL ;

	memset(Name, 0, sizeof(TCHAR) * 500) ;
	// copy "computer" into Name here as a TCHAR string (A2W macro?)
	::EnumPrinters(Flags, Name, Level, NULL, 0, &cbBuf, &pcReturned) ;


Somehting like the above. I didn;t really have the time to get this all working in a network mode.

Hope this helps out.


Roger Allen
Sonork 100.10016

If I had a quote, it would be a very good one.
AnswerRe: Networked Printers? Pin
Christopher Stratmann20-Feb-06 9:24
Christopher Stratmann20-Feb-06 9:24 
GeneralWin9x registry key Pin
alex.barylski6-May-02 15:20
alex.barylski6-May-02 15:20 
GeneralRe: Win9x registry key Pin
Roger Allen7-May-02 0:09
Roger Allen7-May-02 0:09 
GeneralSetDefaultPrinter Pin
jerry0davis3-May-02 3:16
jerry0davis3-May-02 3:16 
GeneralRe: SetDefaultPrinter Pin
Roger Allen3-May-02 3:32
Roger Allen3-May-02 3:32 
GeneralRe: SetDefaultPrinter Pin
jerry0davis3-May-02 3:36
jerry0davis3-May-02 3:36 
GeneralRe: SetDefaultPrinter Pin
Nish Nishant3-May-02 3:38
sitebuilderNish Nishant3-May-02 3:38 
GeneralRe: SetDefaultPrinter Pin
28-May-02 9:13
suss28-May-02 9:13 
GeneralRe: SetDefaultPrinter Pin
jerry0davis1-Nov-02 0:56
jerry0davis1-Nov-02 0:56 
GeneralRe: SetDefaultPrinter Pin
tingquan26-Mar-03 18:28
tingquan26-Mar-03 18:28 
GeneralRe: SetDefaultPrinter Pin
jerry0davis26-Mar-03 21:54
jerry0davis26-Mar-03 21:54 
GeneralNice piece of code Pin
KarstenK3-May-02 1:25
mveKarstenK3-May-02 1:25 
GeneralRe: Nice piece of code Pin
Roger Allen3-May-02 2:26
Roger Allen3-May-02 2:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.