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->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