Announcement

Collapse
No announcement yet.

Fun with printers?!?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Lance Edmonds
    replied
    And I bleed when I get a paper cut too!

    Aye, you must delete the DC with DeleteDC().

    However, I prefer to use CreateDC() since I often "adjust" some portions of the DevMode structure before actually creating the device context.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Bern Ertl
    replied
    Aha! Lance is human!

    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).]

    Leave a comment:


  • Lance Edmonds
    replied
    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.

    Printing is such fun.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Dennis Pearson
    replied
    If you do not use the flag, you MUST check both the pd and dm structures! (See my reply above, third example)

    The reason I do use the flag is I do not care about collation, and provide no code to collate when the printer driver cannot.

    ------------------
    Dennis
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Lance Edmonds
    replied
    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).

    Does this help?

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Bern Ertl
    replied
    Hi Lance,

    Your last post is befuddling .

    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.

    Is that correct?



    ------------------
    Bernard Ertl

    Leave a comment:


  • Lance Edmonds
    replied
    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.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Bern Ertl
    replied
    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.....



    ------------------
    Bernard Ertl

    Leave a comment:


  • Dennis Pearson
    replied
    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.

    ------------------
    Dennis
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Bern Ertl
    replied
    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.



    ------------------
    Bernard Ertl

    Leave a comment:


  • Bern Ertl
    replied
    OK. On to the next stumbling block....

    I've got :

    Code:
    ...
      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).]

    Leave a comment:


  • Bern Ertl
    replied
    He shoots.... He scores!

    Thanks Lance. Problem solved.



    ------------------
    Bernard Ertl

    Leave a comment:


  • Lance Edmonds
    replied
    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:
    Code:
    ptrDM = GlobalLock(pd.hDevMode)
    @ptrdm...
    GlobalUnlock pd.hDevMode
    GlobalFree pd.hDevMode
    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Bern Ertl
    started a topic Fun with printers?!?

    Fun with printers?!?

    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.

    Is there something obvious that I'm missing?

    Help!



    ------------------
    Bernard Ertl
Working...
X