Thanks Gregg!

What a wonderful bunch of help I've received in getting this working!  I 
hope others on the list have gained some insight as well on using the 
library component!

It appears to work now, but is giving me fits on my home printer (but no 
errors).  I'm going to try it on a client's computer tomorrow to see if it 
is only my printer and not the program itself that is messed up.  Below 
I've included the script with Gregg's additions and the rest of the 
functionality needed, although it is still horribly messy and un-optimized.

In case you are curious, the error I'm getting is this:

[Printers Folder]
There was an error writing to LPT1: for the printer (Brother MFC3100C):
There was a problem printing to the network resource.  Check to
make sure the printer server is working properly, and try printing again.
[OK]

When I change the printer to use the built-in virtual driver (BRMFC:), I 
get the following message:

[Printers Folder]
There was an error writing to BRMFC: for the printer (Brother MFC3100C):
The specified path is invalid.
[OK]

What path?  What network resource?  It is a local printer connected to LPT1:.

Anyway, here is the script (beware of line-wrapping).  Let me know directly 
if you have success/failure using this script:

winspool: load/library %winspool.drv
kernel32: load/library %kernel32.dll

print "Define GetLastError"
getlasterror: make routine! [
         return: [long]
] kernel32 "GetLastError"

print "Define OpenPrinter"
openprinter: make routine! [
         "Open Printer"
         pprintername [string!]
         phprinter [char*]
         pdefault [integer!]
         return: [integer!]
] winspool "OpenPrinterA"

print {Define ClosePrinter - Thanks to Gregg Irwin on REBOL list}
closeprinter: make routine! [
         "Close Printer"
         hprinter [integer!]
         return: [integer!]
] winspool "ClosePrinter"

; DOCINFO is used by StartDoc, and has a different structure than 
StartDocument,
; which the spooler uses. StartDoc is what you use for the actual printing
; commands (to a device context). The spooler uses the DOC_INFO_1 structure
; which doesn't have the size or type elements.
print "Define StartDocPrinter"
startdocprinter: make routine! [
         "StartDocPrinter"
         hprinter [integer!]
         dwlevel [integer!]
         lpbdocinfo [
                 struct! [
                         ;cbsize [int]
                         lpszdocname [string!]
                         lpszoutput [string!]
                         lpszdatatype [string!]
                         ;fwtype [int]
                 ]
         ]
         return: [integer!]
] winspool "StartDocPrinterA"

print {Create a Null Buffer - Thanks to Gregg Irwin and Gabriele Santilli 
on REBOL list}
null-buff: func [len][
         head insert/dup make string! len #"^(00)" len
]

print {Create Pointer Variable - Thanks again to Gregg Irwin}
prin "Initial value: "
probe to-binary hprinter: null-buff 4

print "Create DocInfo Struct"
docinfo: make struct! [
         ;cbsize [int]
         lpszdocname [string!]
         lpszoutput [string!]
         lpszdatatype [string!]
         ;fwtype [int]
] reduce ["Test Print" "" "RAW"]

print "Call OpenPrinter"
print either zero? ret: openprinter "Brother MFC3100C" hprinter 0 
["FAIL!"]["Success"]

prin "Current value: "
probe to-binary hprinter

; Have to cast the string buffer to a proper-endian integer.
; The string buffer trick is only needed for return filled (i.e. OUT) 
parameters.
hprinter: to-integer to-binary head reverse hprinter
print ["Printer handle:" hprinter]

; Don't forget, for structures that *do* have a size element, that you have to
; set it before the call.
;print "Set docinfo structure size"
;print docinfo/cbsize: length? third docinfo

close-printer: does [
         print "Closing Printer"
         print either zero? ret: closeprinter hprinter ["FAIL!"]["Success"]
]
end-doc-printer: does [
         print "Closing Document"
         print either zero? ret: enddocprinter hprinter ["FAIL!"]["Success"]
]
end-page-printer: does [
         print "Ending Page"
         print either zero? ret: endpageprinter hprinter ["FAIL!"]["Success"]
]

print "Call StartDocPrinter"
either zero? dwjob: startdocprinter hprinter 1 docinfo [
         print ["ERROR!" getlasterror]
         close-printer
][print "SUCCESS!"]

print "Define StartPagePrinter"
startpageprinter: make routine! [
         "Start Page Printer"
         hprinter [int]
         return: [int]
] winspool "StartPagePrinter"

print "Define EndDocPrinter"
enddocprinter: make routine! [
         "End Doc Printer"
         hprinter [int]
         return: [int]
] winspool "EndDocPrinter"

print "Define WritePrinter"
writeprinter: make routine! [
         "Write Printer"
         hprinter [int]
         lpdata [char*]
         dwcount [int]
         dwbyteswritten [int]
         return: [int]
] winspool "WritePrinter"

print "Define EndPagePrinter"
endpageprinter: make routine! [
         "End Page Printer"
         hprinter [int]
         return: [int]
] winspool "EndPagePrinter"

print "Call StartPagePrinter"
either zero? startpageprinter hprinter [
         print "FAIL!"
         end-doc-printer
         close-printer
][print "Success"]

byteswritten: 0

testdata: {The quick brown fox jumped over the lazy dogs.}

print "Call WritePrinter"
either zero? writeprinter hprinter testdata length? testdata byteswritten [
         print "FAIL!"
         end-page-printer
         end-doc-printer
         close-printer
][print "Success"]

print "Call EndPagePrinter"
either zero? endpageprinter hprinter [
         print "FAIL!"
         end-doc-printer
         close-printer
][print "Success"]

print "Call EndDocPrinter"
either zero? enddocprinter hprinter [
         print "FAIL!"
         close-printer
][print "Success"]

close-printer

if byteswritten <> length? testdata [
         print "Incorrect number of bytes written!"
]

halt

Have fun!

-Bo

At 08:44 PM 7/1/02 -0600, you wrote:
>Hi Bo,
>
><< If anyone has suggestions on why StartDocPrinter doesn't like the handle,
>I'd be very curious to find out! >>
>
>Below is a modified version of your script. Let me know if it works OK for
>you (I'm on W2K and some structures have changed compared to '95). If you
>have any questions about the changes I made, just holler. Hopefully I didn't
>muddy things up too badly.
>
>--Gregg
>
>REBOL []
>
>winspool: load/library %winspool.drv
>kernel32: load/library %kernel32.dll
>
>print "Define GetLastError"
>getlasterror: make routine! [
>          return: [long]
>] kernel32 "GetLastError"
>
>print "Define OpenPrinter"
>openprinter: make routine! [
>          "Open Printer"
>          pprintername [string!]
>          phprinter [char*]
>          pdefault [integer!] ;[string!] We want to pass a NULL here for now.
>          return: [integer!]
>] winspool "OpenPrinterA"
>
>; Added ClosePrinter so we can clean up while testing. Gregg
>print "Define ClosePrinter"
>closeprinter: make routine! [
>          "Close Printer"
>          hprinter [integer!]
>          return: [integer!]
>] winspool "ClosePrinter"
>
>; DOCINFO is used by StartDoc, and has a different structure than
>StartDocument,
>; which the spooler uses. StartDoc is what you use for the actual printing
>; commands (to a device context). The spooler uses the DOC_INFO_1 structure
>; which doesn't have the size or type elements.
>print "Define StartDocPrinter"
>startdocprinter: make routine! [
>          "StartDocPrinter"
>          hprinter [integer!] ;[char*] This needs to be an integer here.
>          dwlevel [integer!]  ;[int]
>          lpbdocinfo [
>             struct! [
>                  ;cbsize [int]
>                  lpszdocname [string!]
>                  lpszoutput [string!]
>                  lpszdatatype [string!]
>                  ;fwtype [int]
>             ]
>          ]
>          return: [integer!]
>] winspool "StartDocPrinterA"
>
>print {Create a Null Buffer - Thanks to Gregg Irwin and Gabrielle Santilli
>on REBOL list}
>
>null-buff: func [len][
>     head insert/dup make string! len #"^(00)" len
>]
>
>print {Create Pointer Variable - Thanks again to Gregg Irwin}
>prin "Initial value: "
>probe to-binary hprinter: null-buff 4
>
>; You have to give it a datatype it understands (e.g. "RAW"),
>; rather than an empty string.
>print "Create DocInfo Struct"
>docinfo: make struct! [
>          ;cbsize [int]
>          lpszdocname [string!]
>          lpszoutput [string!]
>          lpszdatatype [string!]
>          ;fwtype [int]
>] reduce ["Test Print" "" "RAW"] ;[100 "Test Print" "" "" 0]
>
>;!!! I CHANGED THE PRINTER NAME FOR TESTING !!! Gregg
>print "Call OpenPrinter"
>print either zero? ret: openprinter "HP LaserJet 4" hprinter 0
>["FAIL!"]["Success"]
>
>prin "Current value: "
>probe to-binary hprinter
>; Have to cast the string buffer to a proper-endian integer.
>; The string buffer trick is only needed for return filled (i.e. OUT)
>parameters.
>hprinter: to-integer to-binary head reverse hprinter
>print ["Printer handle:" hprinter]
>
>; Don't forget, for structures that *do* have a size element, that you have
>to
>; set it before the call.
>;print "Set docinfo structure size"
>;print docinfo/cbsize: length? third docinfo
>
>print "Call StartDocPrinter"
>print either zero? dwjob: startdocprinter hprinter 1 docinfo [["ERROR!"
>getlasterror]]["SUCCESS!"]
>
>print "Closing Printer"
>print either zero? ret: closeprinter hprinter ["FAIL!"]["Success"]
>
>
>halt
>
>--
>To unsubscribe from this list, please send an email to
>[EMAIL PROTECTED] with "unsubscribe" in the
>subject, without the quotes.

-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.

Reply via email to