You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
OK. So I understood the M$ docs correctly. I don't particularly
care about collation as copy machines can handle this chore 99.99%
of the time for my end users. But, I'm going to go ahead and forgo
this flag and add in collation handling code for the color printer
crowd....
Dennis,
I think what Lance is getting at, is that if the DM specifies multiple
copies, you only need print once and the driver will automatically handle
the extra copies. So, your code only need concern itself with the PD values.
I do have another question though. Upon re-reading the M$ help file,
I noticed the pd.hDC field. If I specify the PD_RETURNDC flag when calling
PrintDlg(), can I forgo the CreateDC call (see code in initial post)?
And if so, I suppose I still need to call DeleteDC when I'm done?
------------------
Bernard Ertl
[This message has been edited by Bern Ertl (edited July 24, 2001).]
No that is not correct, unless MS have failed to document things correctly:
PD_USEDEVMODECOPIESANDCOLLATE
<snip> If this flag isn't set... and the driver doesn't support multiple copies and collation, the information is returned in the PRINTDLG structure. This means that an application only has to look at nCopies and PD_COLLATE to determine how many copies it needs to render and whether it needs to print them collated.
Dennis, in your "example 3", the device driver will be taking care of the multiple copies (2 in your example), therefore PD.nCopies returns 1. This means your code sends one copy, and the driver prints it twice on your behalf. This is why you need to look for PD_COLLATE in PD after the call.
I'm terribly sorry! I confused the issue with a critical typo in that message. Lets try it again:
IMHO, the best way is NOT to use the PD_USEDEVMODECOPIESANDCOLLATE flag when you call PrintDlg().
When the PrintDlg() API returns, test for the prescence of the %PD_COLLATE collate flag (and PD.nCopies member) in PD structure, and work with the results of those only, ignoring the DevMode structure (as the driver will handle it for you if necessary).
I understood that if the PD_USEDEVMODECOPIESANDCOLLATE flag is set
and the driver does not support collation, the check box would be
disabled. Thus the PD_COLLATE flag should never have the opportunity
to be set.
What I'm gathering from your last post is that the PD_USEDEVMODECOPIESANDCOLLATE
flag is basically useless because my code will need to check for and possibly handle
the collation whether I use the flag or not.
I always prefer to use the PD_USEDEVMODECOPIESANDCOLLATE flag, and my printing code just tests the PD structure flags and copies fields to determine what should be done by MY code.
The last sentence of the quote from MSDN is the clue here: if the the PD_COLLATE flag is set in the PD structure, YOUR code has to handle the collation (ie, the driver won't handle the collation for you).
Same applies to the 'PD.nCopies' member; your code should print as many copies as that field indicates. That is, if PD.ncopies = 1 and multiple copies are selected by the user, your code only needs to print 1 copy and the driver will handle the rest for you.
While I've never experimented with it, you may try adjusting the spool setting for "Start Printing After Last Page is Spooledd" rather than "After 1st Page is Spooled" and see if that makes any difference.
Thanks Dennis, that is what I thought was supposed to happen.
I think I need to test with another printer driver.
I'm currently using an NEC Superscript 860 laser printer. With
the flag ON, the collate box is enabled, but whether I check it
or not, the output remains non-collated. Perhaps the driver is
screwed up.....
With the pd_usedevmodecopiesandcollate flag on:
You only have to check the devmode structure for copies
no collation is done if the printer driver does not do it for you
With the flag off:
You have to check both the devmode and the pd structures for copies and collate, using the "highest" result from each
Here is a sample from one of my printers (HP LJ 4000), with two copies selected. This printer driver does not support collation!
Flag on:
Collate box is disabled
PD copies = 1, PD collate is off
DM copies = 2, DM collate is off
Flag off, collate is checked:
PD copies = 2, PD collate is on
DM copies = 1, DM collate is off
Flag off, collate not checked:
PD copies = 1, PD collate is off
DM copies = 2, DM collate is off
In summary, using the flag is easier, but with no collation unless the printer driver supports it. If you need to offer collation, you cannot use the flag.
Never mind. I rebooted my machine and the error
messages vanished.
The code is printing now. Must have been some left over
garbage in memory from earlier attempts.
However, either I misunderstood the Win32.HLP or something is fishy:
PD_USEDEVMODECOPIESANDCOLLATE
Disables the Copies edit control if the printer driver does not support multiple copies, and disables the Collate checkbox if the printer driver does not support collation. If this flag is not specified, PrintDlg stores the user selections for the Copies and Collate options in the dmCopies and dmCollate members of the DEVMODE structure.
If this flag isn't set, the copies and collate information is returned in the DEVMODE structure if the driver supports multiple copies and collation. If the driver doesn't support multiple copies and collation, the information is returned in the PRINTDLG structure. This means that an application only has to look at nCopies and PD_COLLATE to determine how many copies it needs to render and whether it needs to print them collated.
I understood this to mean that with the flag set as I have it, the
collate option would only be enabled if the printer driver supported it.
In this case, if chosen, the dmCollate field of the DEVMODE structure
would be set and I don't have to do any special processing when printing
(ie. the printer device context would handle it automatically when
initialized with this DEVMODE structure).
In testing, the # of copies is working as expected, but it is
not collating.
...
IF <Print to printer> THEN
IF pd.hDevMode THEN
ptrDM = GlobalLock( pd.hDevMode)
szTemp = @ptrDM.dmDeviceName
PrintFmt.hDCPrinter = CreateDC( "", szTemp, "", @ptrDM )
END IF
' <Farpoint Spread SSPrint call>
IF PrintFmt.hDCPrinter THEN DeleteDC PrintFmt.hDCPrinter
END IF
'Release memory even if not printing....
IF pd.hDevMode THEN
GlobalUnlock pd.hDevMode
GlobalFree pd.hDevMode
GlobalFree pd.hDevNames
pd = initpd
END IF
When printing, I get a message box stating:
"Already printing: <crlf>
<my report name>"
The printer queue shows an entry for my print
job, but printing page zero of <X> pages.
As soon as I click OK on the message box, I get
another message box titled "Printers Folder"
which states that there was an error writing
to the printer - "The specified procedure could not be found."
Any ideas what is (could be) causing this?
------------------
Bernard Ertl
[This message has been edited by Bern Ertl (edited July 23, 2001).]
hDevmode is usually only a handle, not a pointer (unless %GMEM_FIXED is specified in the GlobalAlloc call, but I do not believe that PrintDlg() uses that flag when it allocates the DM structure block).
Therefore, you probably have to use something like this:
I've been reading through past postings regarding the
Common Dialog printer set-up.
I've added the following code to my app:
Code:
GLOBAL pd AS PRINTDLGAPI
...
pd.lStructSize = LEN(PRINTDLGAPI)
pd.Flags = %PD_HIDEPRINTTOFILE OR %PD_NOPAGENUMS OR %PD_NOSELECTION OR %PD_USEDEVMODECOPIESANDCOLLATE
PrintDlg pd
...
so far, so good. This creates the printer dialog and appears to
work just fine.
Later, I've added:
Code:
LOCAL szTemp AS ASCIIZ * 260
LOCAL ptrDM AS DEVMODE PTR
...
IF pd.hDevMode THEN
ptrDM = pd.hDevMode
szTemp = @ptrDM.dmDeviceName
PrintFmt.hDCPrinter = CreateDC( "", szTemp, "", BYVAL pd.hDevMode )
MSGBOX "hDC="+STR$( PrintFmt.hDCPrinter)+", szTemp = " + szTemp
END IF
' <Farpoint Spread SSPrint call>
IF pd.hDevMode THEN
GlobalFree pd.hDevMode
GlobalFree pd.hDevNames
DeleteDC PrintFmt.hDCPrinter
END IF
The message box indicates that szTemp is garbage (approx 3 chars).
CreateDC returns 0.
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Leave a comment: