Opened 9 years ago

Closed 5 years ago

#10323 closed defect (fixed)

printing problem when set copies > 1

Reported by: Lexxigo Owned by:
Priority: normal Milestone:
Component: wxMSW Version: stable-latest
Keywords: print copy count wrong Cc: schauff@…
Blocked By: Blocking:
Patch: yes



I'm using wxWidgets 2.8.9 (not svn) under Windows XP (32 bit gcc/MingW) Vista 64 (32 bit gcc/MingW) and openSuse 11.1 64 (64 bit gcc).
I using Samsung SCX-4200 printer as default printer.

wxWidgets print more copies than I set in printing dialog.
for Example: I have set it to 2. wxWidgets will print 4 copies.
The wxWidgets printing framework call the print callback functions twice, but the printer get the number of copies already as 2. My both print job will be printed twice, i.e. my document will printed 4 times. :(
The printing sample will do this already. I can't confirm it under wxGTK but under Windows this bug exists.


Attachments (1)

printwin.cpp.patch download (1.0 KB) - added by johnr 5 years ago.

Download all attachments as: .zip

Change History (14)

comment:1 Changed 7 years ago by ls2000

  • Keywords windows 7 added
  • Version changed from 2.8.x to 2.8.12


I have the same problem with the current stable release 2.8.12 under win xp (32 bit gcc/mingw).

It can be reproduced with the "printing"-sample.


comment:2 Changed 7 years ago by ls2000

  • Cc schauff@… added
  • Status changed from new to confirmed

comment:3 Changed 5 years ago by johnr

  • Keywords print copy count wrong added; printing windows 7 removed
  • Version changed from 2.8.12 to 2.9-svn

comment:4 Changed 5 years ago by johnr

I am not sure how to fix this. We do similar to what both windows GDI and XPS printing examples do i.e. loop for every page copy. I can see how this would work where collation is specified and each document copy ends up with its pages in order. Perhaps we need to check whether collation is specified and loop only if so but I doubt this is the answer. To confuse matters further there may be a device dependent ability to print multiple page copies when provided with one. Some HP printers had a mopier mode that could be switched on or off.

Contrary to the above posts I found XP printed the correct number of copies but after reading the above posts I will test again and also continue reading in my spare time. Anyone with knowledge in this area is welcome to chime in.

comment:5 Changed 5 years ago by johnr

  • Patch set

Ah, there was something different and I see it now. We do call printout->OnBeginDocument(...) for every document copy within the copyCount <= maxCopyCount loop when we really only need to call it once and then print the multiple page copies. Remove this from the loop and do it once for the document prior to entering the loop and things work as expected.

Patch attached.

comment:6 Changed 5 years ago by johnr

Seems I may have posted too soon as PDF printing shows 4 pages. Patch overwritten with a revision.

comment:7 Changed 5 years ago by johnr

Vadim, I had a mild dose of poster's remorse after sleep brought on more ideas so I will ruminate further before reporting back.

comment:8 follow-up: Changed 5 years ago by vadz

Sorry, I didn't follow this at all so far (I'm printophobic) so I don't know if I should apply (or at least check) the latest version of the patch or if you're still working on improving it?


comment:9 in reply to: ↑ 8 Changed 5 years ago by johnr

Replying to vadz:

Sorry, I didn't follow this at all so far (I'm printophobic) so I don't know if I should apply (or at least check) the latest version of the patch or if you're still working on improving it?


The patch as it stands is an improvement but hold off applying it. I was still trying to understand the finer points of the Microsoft provided print examples hence my previous comment on the ticket. I will attempt to explain the differences between Microsoft recommended and wxWidgets' implementation when I get time over the next few days and may provide a different patch.

comment:10 Changed 5 years ago by johnr

I have summarized code from the Microsoft MSW GDI print example and wxWidgets equivalent code:

	// MSW
	while (((waitStatus = ... && SUCCEEDED(hr))
	// wxWidgets 
	for ( int copyCount = 1; copyCount <= maxCopyCount; copyCount++ )
		// print doc copies
		// MSW
		hr = PrintStep_3_DoOneDoc
		// wxWidgets
		if ( !printout->OnBeginDocument(minPageNum, maxPageNum) )
			// log error reporting if fails "could not start printing"

see note
		// MSW
		while (((waitStatus = ...  && SUCCEEDED(hr))
		// wxWidgets 
		for ( pn = minPageNum; pn <= maxPageNum && printout->HasPage(pn); pn++ )
			// print pages
			// MSW
			hr = PrintStep_4_DoOnePage
			// wxWidgets dc->StartPage();
            		// wxWidgets bool cont = printout->OnPrintPage(pn);
            		// wxWidgets dc->EndPage();

		// wxWidgets 
		printout->OnEndDocument() // is same as PrintStep_5_CloseDoc 
                // note this is located in the copies loop and so it is called for every copy

	// MSW
	hr = PrintStep_5_CloseDoc // note this is outside the copies loop and so only called once

	// MSW indicate print job completion status to parent
	if (FAILED(hr))

The main difference is that Microsoft do not call hr = PrintStep_5_CloseDoc after each copy but we do call its equivalent printout->OnEndDocument()
This is we call EndDocW() for every StartDocW(). Microsoft do not do this and only call EndDocW() after breaking from the copies loop.
With Microsoft's example the loop will break if a printer driver does not open when StartDocW() has been called for subsequent copies. I think this is likely with most printers that can print multiple copies from a single passed copy.

We report every failure from StartDoc() but the only hr fail reported by MSW is hr = PrintStep_5_CloseDoc.
We don't report failures from printout->OnEndDocument() at all.

Disk files done with Bullzip.pdf printer will only ever produce one copy on disk and no page duplication within the file. Other disk file printers may behave differently but I haven't tested any others.

Another difference is that MSW recommend doing the above code in a separate thread but I am not about to tackle that.

I can change our code to follow the MSW example if this is considered an OK approach keeping in mind the MSW code is an example only.

comment:11 Changed 5 years ago by johnr

Well that is interesting. I had been testing using a pdf printer both for convenience and to save paper. When using my network printer, the GDI print sample from Microsoft fails to print anything at all. Makes it difficult when even the people at Microsoft who wrote the stuff can't get it right.

I am starting to think that we should just remove the for() loop for the copies but there may be problems with XP and I need to test further as long as my paper and toner hold out. I am still researching this when able and will eventually convince myself about the correct fix.

comment:12 Changed 5 years ago by johnr

If we use the wxPrinterDC returned from the wxWindowsPrintDialog then we don't need the copies loop if the device supports multiple copy printing. However, if we construct our own wxPrinterDC and set copies > 1 then we do need the copies loop.

We have 2 options:

  1. Always construct our own wxPrinterDC and loop until copy count.
  2. Loop for multiple copies only when we have not used the dc from the printdialog or the device doesn't support it.

Both options work and are trivial to implement.
1 gives us fixed collation only with the current code. Disk file printing will produce copy count files.
2 will always give us only one file for a disk file print job when the printdialog is shown and may produce the copy count of each page in that file.

I have overwritten my original patch to do option 2 and use native printing. I have tested this here but I have a limited number of printers.

Changed 5 years ago by johnr

comment:13 Changed 5 years ago by VZ

  • Resolution set to fixed
  • Status changed from confirmed to closed

(In [74055]) Fix printing multiple copies in wxMSW.

If wxPrinterDC was created by the native "Print" dialog for a printer that
supports printing multiple copies, we must not manually print multiple copies
ourselves as this results in too many copies being printed. However we still
need to loop explicitly for wxPrinterDC objects created manually or for the
printers without support for multiple copies (supposing they still exist).

Closes #10323.

Note: See TracTickets for help on using tickets.