How to set "Pages Per Sheet" Programmatically for "N-Up" Printing | Experts Exchange (2024)

This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers. This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper.

If your program provides printed output, you may want to be able to preset some settings for automatic printing so that your user does not need to monkey around in the "Preferences" or "Advanced" settings of the common printing dialog. For instance, in one of my application programs, I let the user select a certain type of wide-format report, and when it came time to print that report, the program would force a small font and preset for Landscape output.

The Pages per Sheet setting, sometimes called N-up printing, lets your user conserve paper by shrinking the page and printing two pages side-by-side. I've found that the text in 2-up printing, though small, is still readable. If your eyes are good (or the text is rendered in a large font), even 4-up printing is usually viable. I often use it for C++ source code printing.
Beyond that, Windows actually lets you select 6-, 9- and 16-up printing. Though the output is usually too small to be readable, this option could be used in a "pre-print" run of a long document... each page on the sheet would act as a sort of thumbnail image to help identify gross formatting problems, "widows and orphans," and other printing artifacts that you would like to avoid before sacrificing several trees to a full-sized run.

Presetting for Landscape Printing
Programmatically setting for Landscape printing is well documented in the Microsoft literature. For instance, see:
How to Change Default Printer Settings in an MFC Application
...and the simpler version:
CWinApp::GetPrinterDeviceDefaults
...for some example code.

If you can get a HANDLE to a default DEVMODE structure, then you can change settings in it. All you need to do is GlobalLock() it to get a pointer, make changes, and then GlobalUnlock() it. The DEVMODE.dmOrientation field controls landscape printing. Set it to DMORIENT_LANDSCAPE and the page will print sideways.

MFC thoughtfully provides an m_hDevMode handle that your CWinApp-derived program can use. It's a private member, but there are several ways to access it; for instance, you can make your "Set_N_Up_Mode()" function a member of your CWinApp-derived object. Or you can use the simple technique in the example code below -- shown as an action in a CView-derived object.

Setting Pages Per Sheet
As this is entirely undocumented, I had to do some investigative work: In a simple MFC SDI application, I brought up the Print Dialog, changed the Pages Per Sheet setting and then used the debugger to look at the DEVMODE structure for changes. Alas, No joy.

But there is a printer-driver private area that directly follows the "formal" devmode record. By displaying that area before and after changing the setting, I discovered the following:

At offset 24 (0x18) after the end of the DEVMODE structure, there is a byte that directly controls this setting. Its valid values are:

 0 = 1-up 1 = 2-up 2 = 4-up 3 = 6-up 4 = 9-up 5 = 16-up

Open in new window

(a fact I later confirmed by digging around in the Printer Driver DDK).

So, you need only punch the right value into the right place, at the right time. You'll want to make the change to the application-global DEVMODE right before printing. I decided to put it in the easily-accessible OnPreparePrinting function of my View class.

BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo) { PRINTDLG rPD; BOOL fRet= AfxGetApp()->GetPrinterDeviceDefaults( &rPD ); LPDEVMODE pDM= (LPDEVMODE)::GlobalLock( rPD.hDevMode ); PBYTE pbDriverData= (PBYTE)(((BYTE *)pDM)+(pDM->dmSize));// right after the end pbDriverData[24]= 2; // set to 4-up (1=2-up, 3=6-up, etc.) ::GlobalUnlock( rPD.hDevMode ); // default handling (as added by the ClassWizard) return( DoPreparePrinting(pInfo) ); }

Open in new window

Notes:

The above uses MFC-specific code, but the general technique can be applied to any programming language. With very few exceptions, all Windows printing goes through the Common Print dialog. If you can figure out how to get to the hDevMode member of the PRINTDLG structure, then the rest should be easy.

Not all printer drivers support N-up printing. You should check:
DEVMODE.dmNup
If it has a value of 1 (DMNUP_SYSTEM) then the driver supports this. If it has a value of 2 (DMNUP_ONEUP) then you should probably not try to modify the data that follows the DEVMODE structure.

The printer driver will typically support an option for drawing a border (thin box) around each page. The default for 1-up is no border, but the default for 2-or-more-up is to add the border. Some additional experimentation led me to this setting as well. You can use code like the following to set or clear the "Draw Borders" checkbox:
if ( pDM->dmDriverExtra > 564 ) { pbDriverData[564]= 0; // 1= no border lines; 0= draw borders }

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
If you liked this article and want to see more from this author, please click the Yes button near the:
Was this article helpful?
label that is just below and to the right of this text. Thanks!
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

How to set "Pages Per Sheet" Programmatically for "N-Up" Printing | Experts Exchange (2024)

References

Top Articles
Solon says revamped NGPA law poised to 'revolutionize procurement process across govt sectors' | BusinessMirror
Does climate change really happen?
Kevin Cox Picks
Amc Near My Location
Restaurer Triple Vitrage
Mountain Dew Bennington Pontoon
Visitor Information | Medical Center
Valley Fair Tickets Costco
Undergraduate Programs | Webster Vienna
Recent Obituaries Patriot Ledger
Seething Storm 5E
Erskine Plus Portal
Truist Drive Through Hours
Becky Hudson Free
Infinite Campus Parent Portal Hall County
Full Range 10 Bar Selection Box
Morgan And Nay Funeral Home Obituaries
Kaitlyn Katsaros Forum
Panolian Batesville Ms Obituaries 2022
Marion City Wide Garage Sale 2023
Conscious Cloud Dispensary Photos
Craigslist Alo
Anonib Oviedo
Dmv In Anoka
Panolian Batesville Ms Obituaries 2022
Craigslist Pasco Kennewick Richland Washington
Arlington Museum of Art to show shining, shimmering, splendid costumes from Disney Archives
Pixel Combat Unblocked
Dhs Clio Rd Flint Mi Phone Number
Gopher Hockey Forum
Ipcam Telegram Group
Ancestors The Humankind Odyssey Wikia
Scat Ladyboy
Mumu Player Pokemon Go
Wega Kit Filtros Fiat Cronos Argo 1.8 E-torq + Aceite 5w30 5l
Gr86 Forums
Craigslist Albany Ny Garage Sales
Exploring The Whimsical World Of JellybeansBrains Only
Closest 24 Hour Walmart
Google Jobs Denver
Bitchinbubba Face
The TBM 930 Is Another Daher Masterpiece
Craigslist Ludington Michigan
877-292-0545
Fifty Shades Of Gray 123Movies
Dispensaries Open On Christmas 2022
Gary Vandenheuvel Net Worth
Deezy Jamaican Food
Conan Exiles Colored Crystal
Germany’s intensely private and immensely wealthy Reimann family
Craigslist Anc Ak
300 Fort Monroe Industrial Parkway Monroeville Oh
Latest Posts
Article information

Author: Errol Quitzon

Last Updated:

Views: 5608

Rating: 4.9 / 5 (79 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Errol Quitzon

Birthday: 1993-04-02

Address: 70604 Haley Lane, Port Weldonside, TN 99233-0942

Phone: +9665282866296

Job: Product Retail Agent

Hobby: Computer programming, Horseback riding, Hooping, Dance, Ice skating, Backpacking, Rafting

Introduction: My name is Errol Quitzon, I am a fair, cute, fancy, clean, attractive, sparkling, kind person who loves writing and wants to share my knowledge and understanding with you.