How to programmatically print to a non-default printer in MFC

Source: Internet
Author: User

http://cache.baiducontent.com/c?m= 9f65cb4a8c8507ed4fece763105790245b09c0252bd7a74a2485d315d2390f07506694ea7a7d0d5d83d87f6305ac4957f7b86c65377571eb8f8dd50a8 bb485582a9f5631671df65663d50edcba5154cb37e12efeae69f0caf625e7aec5a5de4320c944040a9780fb4d7467&p= C4759a46d7c002fb09be9b7c5b5390&newp=b471c54ad5c242fe19f3cb2d02148c231610db2151ddd4122e958d17&user= baidu&fm=sc&query=%b7%c7%c4%ac%c8%cf%b4%f2%d3%a1%bb%fa&qid=f3d87aaa0004b57b&p1=2

Article ID: 166129- View products that this article applies to.

View machine translation of the Microsoft Support page for machine translation Disclaimer Note: Microsoft Visual C + + +.net (2002) supports the. NET Framework and unmanaged native Windows code models that are provided by these two managed code models. Some or all of the information in this article applies to managed Visual C + + code and may only be applied by using the. NET Framework. Expand All | Close all this content overview in developing an MFC application, which is sometimes used to programmatically print to a network printer or to a secondary printer non-default printer(without the Print dialog box). The DEVMODE and DEVNAMES structures are required to perform this operation. This article shows a way to set up the use of GetPrinter () to invoke these data structures, and provides examples of how to use them.

Note: Some of the code in this article cannot be applied to Windows 95 and Windows 98 because GetPrinter may not be available for network printers. Back to the top | Provide feedback for more information during normal print operations in an MFC application, the Print dialog box will display the dialog box to select the printer to print to. The default printer that is displayed in the Print dialog box is the default printer that is specified in the operating system. MFC stores the protected data members of the application in the default printer Cwinapp::m_hdevmode and Cwinapp::m_hdevnames. Because MFC initializes these variables to NULL, MFC's print architecture defaults to the default operating system for the first time that the printer performs a print operation. The operating system default printer DEVMODE and DEVNAMES are then copied to the M_hdevmode and M_hdevnames data members in the MFC application.

Sometimes, you may want to print to a printer other than the default printer, without requiring the user to specify it in the Print dialog box. Secondary printer or network printer (assuming that your operating system has drivers installed), you can use the non-default printer

Whether you need to use non-default printerOn a permanent basis or with only one print job, you will need the DEVMODE and DEVNAMES structure to create a printer on the DC. The GetPrinter () printer_info_2 structure contains all the information needed to populate the DEVMODE and DEVNAMES structures.

Create a DEVMODE and DEVNAMES structure The following code example demonstrates how to use GetPrinter () to create DEVMODE and DEVNAMES structures based on the printer name. The code is the global function that returns the data structure through its parameters.
#include <winspool.h>//returns a DEVMODE and DEVNAMES for the printer name Specifiedbool getprinterdevice (LPTSTR PS    Zprintername, hglobal* phdevnames, hglobal* phdevmode) {//If NULL is passed and then assume we're setting app object ' s    DEVMODE and DevNames if (Phdevmode = = NULL | | phdevnames = = NULL) return FALSE;    Open printer HANDLE hprinter;    if (OpenPrinter (Pszprintername, &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 = GlobalAlloc (ghnd, sizeof (*P2-&GT;PDEvmode) + P2->pdevmode->dmdriverextra);    ASSERT (Hdevmode);    devmode* pDevMode = (devmode*) globallock (Hdevmode);    ASSERT (pDevMode); Copy DEVMODE data from printer_info_2::p DEVMODE memcpy (pDevMode, P2->pdevmode, sizeof (*p2->pdevmode) + P    2->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 the hold DEVNAMES. Hglobal hdevnames = GlobalAlloc (ghnd, sizeof (DEVNAMES) + (Drvnamelen + Ptrnamelen + pornamelen) *sizeof (TCHAR    ));    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);    Free printer_info_2//Set the new Hdevmode and hdevnames *phdevmode = Hdevmode;    *phdevnames = hDevNames; return TRUE;}


As a quick reference, here is a brief description of the DEVNAMES declaration with each field:
commdlg.h//The first three members is character offsets from the beginning of the//structure pointing to the SPECIF IC stringtypedef struct Tagdevnames {   WORD wdriveroffset;  File name of driver (without extension)   WORD Wdeviceoffset;  Device name   WORD woutputoffset;  Device name of physical output medium   WORD wdefault;       DN_DEFAULTPRN if default printer chosen} DEVNAMES;


Set the application's default printer to set the default printer, you need to set the M_hdevnames and M_hdevmode data members (it is protected) to the CWINAPP member function through the application's derived object, Getprinterdevice (). You can implement the following function and call it when you need to change the default printer.
void Cmainframe::onactionsetnondefaultprinter () {    hglobal hdevmode = NULL;    Hglobal hdevnames = NULL;    if (Getprinterdevice (_t ("\\\\red-prn-25\\priv0006"), &hdevnames, &hdevmode))        AfxGetApp () Selectprinter (hDevNames, hdevmode);    else        AfxMessageBox (_t ("Failed to select Custom Printer"));}


To bypass the Print dialog box by using the application's default printer to bypass the Print dialog box, OnPreparePrinting needs to be overridden so that the M_BDIRECT flag can be set to TRUE. Then call DoPreparePrinting to set the value of M_pd.hdevmode m_ppd pInfo and pinfo-> m_ppd-> m_pd.hdevnames the data member to the corresponding Application object and create the DC On the printer.
BOOL cnondefprinterview::onprepareprinting (cprintinfo* pInfo) {    Pinfo->m_bdirect = true;//True if bypassing Print Dialog    return doprepareprinting (PInfo);}


Use when bypassing the Print dialog box non-default printerTo skip the Print dialog box and use the non-default printer, you need the M_PD M_PPD pInfo data member to set up and create the printer on the DC yourself. Here is the code that will accomplish this:
BOOL cnondefprinterview::onprepareprinting (cprintinfo* pInfo) {    //set to Non-default printer without changing Default app printer    hglobal hdevmode;    Hglobal hDevNames;    if (! Getprinterdevice (_t ("\\\\red-prn-25\\priv0006"), &hdevnames, &hdevmode))        AfxMessageBox (_T (" Getprinterdevice called failed\n "));    Pinfo->m_ppd->m_pd.hdevmode = Hdevmode;    Pinfo->m_ppd->m_pd.hdevnames = hDevNames;    PINFO->M_PPD->CREATEPRINTERDC ();    return TRUE;}

This example shows the use of the Getprinterdevice function. For more detailed information, see above. Back to the top | Provide feedback

How to programmatically print to a non-default printer in MFC

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.