PrinterSettings - Changing, Storing and Loading Printer Settings

Description

Several years ago I had to implement the ability to change the printer and it's settings from within a programm. The output had to be distributed to 3 or more printers. The settings had to be stored to disk to be able to be loaded. It was desired to conform to the MFC Framework.

How to use

Declare the class CPrinterSettings in a CDocument derived class or wherever you find it useful.

#include "PrinterSettings.h"

class CPrnsetupDlg : public CDialog
{
public:
	CPrinterSettings m_prn_setting1;
	CPrinterSettings m_prn_setting2;

To get a copy of the original MFC printer settings call CopyDefaultMfcPrinter().

	// Get MFC's default printer
	m_prn_setting1.CopyDefaultMfcPrinter();
	m_prn_setting2.CopyDefaultMfcPrinter();

To let the user change the settings e.g. paper orientation or printer resolution call PrinterSetup( CWnd* pWnd ).

	m_prn_setting1.PrinterSetup(this);

To cause MFC to use your settings call SetThisPrinter().

	// make m_prn_setting1 the MFC standard printer
	m_prn_setting1.SetThisPrinter();

	// later you may call RestorePrinter() to
	// restore earlier settings.

To load or save your settings call Save(LPCTSTR filename ) or Load(LPCTSTR filename ).


	// Save our settings to file
	m_prn_setting1.Save( "testfilename");
	
	...
	... 

	// load settings, store them in m_prn_settings1
	m_prn_setting1.Load( "testfilename" ));
		


Downloads

Download demo project - 17 Kb

The name of the project is "prnsetup.dsw" (build with VC 6 )

Download source - 5 Kb

The source files are named: PrinterSettings.h and PrinterSettings.cpp

History



Comments

  • More concessions with herveleger, more move upon!

    Posted by Mrleftcoqiq on 04/19/2013 09:32pm

    maidentoms store christian louboutin shoes picayune shavertoms outlet online aviditytoms shoes cheap toms shoes cheap stablecheap toms sale undefiledtoms store rep

    Reply
  • Here is how to print to a network printer

    Posted by Legacy on 02/12/2004 12:00am

    Originally posted by: Jocelyn Gennesseaux

    I couldn't print to a network printer using SetPrinterDevice so I made few changes and now it works.
    
    

    So replace SetPrinterDevice as follow and don't forget to call SetThisPrinter() after it.


    BOOL CPrinterSettings::SetPrinterDevice(LPCTSTR pszDeviceName) const
    {
    // Open printer
    HANDLE hPrinter;
    if (OpenPrinter((char*)pszDeviceName, &hPrinter, NULL) == FALSE)
    return FALSE;

    // obtain PRINTER_INFO_2 structure and close printer
    DWORD dwBytesReturned, dwBytesNeeded;
    GetPrinter(hPrinter, 2, NULL, 0, &dwBytesNeeded);
    PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAlloc(GPTR, dwBytesNeeded);
    if (GetPrinter(hPrinter, 2, (LPBYTE)p2, dwBytesNeeded, &dwBytesReturned) == 0)
    {
    GlobalFree(p2);
    ClosePrinter(hPrinter);
    return FALSE;
    }
    ClosePrinter(hPrinter);

    // Allocate a global handle for DEVMODE
    HGLOBAL hDevMode = GlobalReAlloc(m_hDevMode, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtra, GHND);
    ASSERT(hDevMode);
    DEVMODE* pDevMode = (DEVMODE*)GlobalLock(hDevMode);
    ASSERT(pDevMode);

    // copy DEVMODE data from PRINTER_INFO_2::pDevMode
    memcpy(pDevMode, p2->pDevMode, sizeof(*p2->pDevMode) + p2->pDevMode->dmDriverExtra);
    GlobalUnlock(hDevMode);

    // Compute size of DEVNAMES structure from PRINTER_INFO_2's data
    DWORD drvNameLen = lstrlen(p2->pDriverName)+1; // driver name
    DWORD ptrNameLen = lstrlen(p2->pPrinterName)+1; // printer name
    DWORD porNameLen = lstrlen(p2->pPortName)+1; // port name

    // Allocate a global handle big enough to hold DEVNAMES.
    HGLOBAL hDevNames = GlobalReAlloc(m_hDevNames, sizeof(DEVNAMES) + (drvNameLen + ptrNameLen + porNameLen)*sizeof(TCHAR), GHND);
    ASSERT(hDevNames);
    DEVNAMES* pDevNames = (DEVNAMES*)GlobalLock(hDevNames);
    ASSERT(pDevNames);

    // Copy the DEVNAMES information from PRINTER_INFO_2
    // tcOffset = TCHAR Offset into structure
    int tcOffset = sizeof(DEVNAMES)/sizeof(TCHAR);
    ASSERT(sizeof(DEVNAMES) == tcOffset*sizeof(TCHAR));

    pDevNames->wDriverOffset = tcOffset;
    memcpy((LPTSTR)pDevNames + tcOffset, p2->pDriverName, drvNameLen*sizeof(TCHAR));
    tcOffset += drvNameLen;

    pDevNames->wDeviceOffset = tcOffset;
    memcpy((LPTSTR)pDevNames + tcOffset, p2->pPrinterName, ptrNameLen*sizeof(TCHAR));
    tcOffset += ptrNameLen;

    pDevNames->wOutputOffset = tcOffset;
    memcpy((LPTSTR)pDevNames + tcOffset, p2->pPortName, porNameLen*sizeof(TCHAR));
    pDevNames->wDefault = 0;

    GlobalUnlock(hDevNames);
    GlobalFree(p2);

    // Notification: settings changed
    SendMessage(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,(LPARAM)pszDeviceName);

    return TRUE;
    }

    Reply
  • Long Printer Names - THANKS

    Posted by Legacy on 12/10/2003 12:00am

    Originally posted by: Deyvi Pilosof

    This source was great, saved me lots of time.
    
    

    If you need more than 30 chars for the printer names, you should make the following modification


    CString CPrinterSettings::DevmodePrinterName()
    {
    if(!m_hDevNames) {
    m_strPrinterName = "";
    } else {
    LPDEVNAMES lpDev = (LPDEVNAMES)GlobalLock(m_hDevNames);
    m_strPrinterName=(LPCTSTR)lpDev + lpDev->wDeviceOffset;
    GlobalUnlock(m_hDevNames);
    }
    return m_strPrinterName;
    }

    Reply
  • Load a setups across different OS's

    Posted by Legacy on 10/24/2003 12:00am

    Originally posted by: Jens Froslev-Nielsen

    Hi Here,
    I've having a problem with loading print setups saved from W2K in XP and visa-verse. In my case I've a EPSON 2100 and the dmPrintQuality param is not loaded correctly across the OS's. Saving/Loading from the same! OS seems to work ok.
    Does anyone has a (quick and dirty??) solution? .
    Currently I've two saved to setup's MyPrintEPSON2100-XP and
    MyPrintEPSON2100-W2K.

    Thx - Jens

    Reply
  • Modifying printer default setting in dialog based application

    Posted by Legacy on 08/02/2003 12:00am

    Originally posted by: Rick

    Many thanks to the earlier posters. The following is an example of what worked in a dialog based application where I wanted to use the CPrintDialog DoModal function where a user could change printer options but where I wanted to printer dialog box to open with certain defaults already in place ( such as for printing out an envelope ). This was in a function in the Dlg class, not the App class.
    When the print dialog box opens the defaults are set to #10 envelope and landscape orientation typical for most envelopes. The user still can change to something else ( another sized envelope if needed ).

    void CCPhoneDlg::OnCopyEnvelopes()
    {
    CDC dcPrint;
    PRINTDLG pDdlg;
    DEVMODE *mode = NULL;
    CPrintDialog dlgPrint(FALSE, PD_ALLPAGES,this);

    if(AfxGetApp()->GetPrinterDeviceDefaults(&pDdlg))
    {
    mode = (DEVMODE *) GlobalLock(pDdlg.hDevMode);
    mode->dmOrientation = DMORIENT_LANDSCAPE;
    mode->dmPaperSize = DMPAPER_ENV_10;
    GlobalUnlock(pDdlg.hDevMode);
    }

    dlgPrint.m_pd.hDevMode = mode;
    // Note above line worked,
    // dlgPrint.ResetDC(mode) did not work
    if(dlgPrint.DoModal() == IDOK)
    {
    dcPrint.Attach(dlgPrint.GetPrinterDC());
    DOCINFO myPrintJob;
    myPrintJob.cbSize = sizeof(myPrintJob);
    myPrintJob.lpszDocName = "MyPrintJob";
    myPrintJob.lpszOutput = NULL;
    myPrintJob.fwType = NULL;

    ...continue with print job......

    Reply
  • http://www.ucancode.net

    Posted by Legacy on 08/01/2003 12:00am

    Originally posted by: MFC Diagramming,Flow Class Library with Full Source Code!

    Great!

    Reply
  • How can my application see all system's printing operation?

    Posted by Legacy on 04/07/2003 12:00am

    Originally posted by: hnim

    I have to build an application that manages all operations of a desktop such as count number operations that are sucessful/fail or canceled...But i don't know where to begin: which hooks i have to use,how to use it...
    i need help...
    Thanks

    Reply
  • Pl help me ... to Control the Printer using a programme (VB)

    Posted by Legacy on 03/03/2003 12:00am

    Originally posted by: Isuru Binduhewa

    Pl can anybody help me...
    I need to restrict getting printouts. Such that I need to set a password on any printing job (Ms Word, Notepad, Adobe, etc.) and control the no of printouts allowed.(In VB or c++)

    If some one can help me on this would greately appreciated

    Reply
  • I want to change the size of the page in print preview

    Posted by Legacy on 07/31/2002 12:00am

    Originally posted by: Ashutosh

    i am using the class CView for printing. So, i want to set the page size of(800x480) pixels which will show in print preview. since when i saw print preview it showing things on approx half of the page. So, anyone can help me.
    thanks in advance.
    ashutosh

    Reply
  • HTML printing problem

    Posted by Legacy on 04/24/2002 12:00am

    Originally posted by: Bahar

    Y doesnt the following code work.
    
    I'm trying to print a html file.Though the file is seen in the print queue no output is seen in the prinout.
    Plz help.
    thanks in advance
    Bahar

    CPrintDialog dlg(FALSE, PD_NOPAGENUMS | PD_NOSELECTION | PD_USEDEVMODECOPIES | PD_DISABLEPRINTTOFILE|PD_RETURNDC );
    // Get the default printer.
    dlg.DoModal();


    DEVMODE* dm = (DEVMODE*)::GlobalLock(dlg.m_pd.hDevMode);

    HDC hdc = dlg.CreatePrinterDC();

    CDC dc;
    dc.Attach( hdc );
    if ( dc )
    {


    DOCINFO docinfo;
    memset(&docinfo, 0, sizeof(docinfo));

    docinfo.cbSize = sizeof(docinfo);
    docinfo.lpszDocName =htmlDocumentName ;

    dc.StartPage();

    dc.StartDoc(&docinfo);


    //CGdiObject* pOldFont = dc.SelectStockObject(SYSTEM_FONT);
    //dc.TextOut(50, 50, _T("Hello World!"), 12);
    //dc.SelectObject(pOldFont);
    TR_PRINT(_T("Orientation %d "),dm->dmOrientation);

    dc.EndPage();
    dc.EndDoc();

    }
    dc.Detach();

    CDC::FromHandle(hdc)->DeleteDC();

    ::GlobalUnlock(dlg.m_pd.hDevMode);

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

  • Targeted attacks and advanced threats are customized to infiltrate your unique IT infrastructure, evade conventional defenses, and remain hidden while stealing your corporate data. To detect these criminal intrusions, analysts and security experts agree that organizations should deploy advanced threat protection as part of an expanded security monitoring strategy. For this comparative analysis of breach detection systems, product analysis reports and comparative analysis reports are used to create the security …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds