View/Pro and accessing Windows Printer API (gdi32.dll)
[1/24] from: amicom:sonic at: 27-Jun-2002 9:31
Hello All!
I am looking to add native printing support to my REBOL applications for
Windows, but I am running into a problem with the library component of
View/Pro. Here's the story:
The following has C source code for sending raw data to a printer on Windows.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_93g2.asp
Converting it to View/Pro was going well until I hit the OpenPrinter routine!.
Here's a transcript of my efforts:
>> gdi32: load/library %gdi32.dll
>> startdoc: make routine! ["Start Document" hdc [string!] docinfo
[struct! [cbsize [int] lpszdocname [string!] lpszoutput [string!]
lpszdatatype [string!] fwtype [int]]] return: [int]] gdi32 "StartDocA"
;So far, so good...
>> openprinter: make routine! ["Open Printer" pprintername [string!]
phprinter [string!] pdefault [string!] return: [integer!]] gdi32 "OpenPrinterA"
** Access Error: Cannot open OpenPrinterA
** Near: openprinter: make routine! ["Open Printer" pprintername [string!]
phprinter [string!] pdefault [string!] return: [integer!]] gdi32
OK, maybe OpenPrinterA is not the correct name, let's see:
>> gdi32: read %/c/windows/system/gdi32.dll
>> find gdi32 "OpenPrinter"
==
{OpenPrinterA^@^@^@^@WritePrinter^@^@^@^@OPENGL32^@^@^@^@wglChoosePixelFormat^@^@^@^@wglDescribePixelFormat^@^@wglGetPixelFormat...
OpenPrinterA
is the correct name...AARGH! What's the deal?
Anyone have any ideas on this? Am I overlooking something?
I'm planning to release the REBOL Windows printer functionality to the
community once it is working because dumping raw data to LPT1: isn't
usually the most desirable method of printing. My plans are to get the raw
printing through GDI working first, and then making it more like the
integrated printing features in Windows complete with bitmap printing
support, etc. The URL listed above has complete details on how to do this
(in C).
Anyone willing to work with me on this project will be welcomed
enthusiastically!
Bohdan "Bo" Lechnowsky
Lechnowsky Technical Consulting
REBOL/IOS Value Added Reseller
Specializing in solutions using REBOL
[2/24] from: dockimbel:free at: 27-Jun-2002 20:26
Hi Bo,
Try using %winspool.drv instead of %gdi32.dll for OpenPrinter function.
(Works here on W2K)
HTH,
-DocKimbel.
Bohdan or Rosemary Lechnowsky wrote:
[...]
[3/24] from: ptretter:charter at: 27-Jun-2002 14:30
Hi Doc - do you have a sample of the code you use?
Paul Tretter
[4/24] from: greggirwin:mindspring at: 27-Jun-2002 13:52
Hi Guys,
<< Try using %winspool.drv instead of %gdi32.dll for OpenPrinter function.
(Works here on W2K) >>
Ditto. You'll probably also need to use %winspool.drv for ClosePrinter.
--Gregg
[5/24] from: ptretter:charter at: 27-Jun-2002 14:24
I want to work with you on this. I also have /Pro and but haven't use
library capabilities much.
Paul Tretter
----- Original Message -----
From: "Bohdan or Rosemary Lechnowsky" <[amicom--sonic--net]>
To: <[rebol-list--rebol--com]>
Sent: Thursday, June 27, 2002 11:31 AM
Subject: [REBOL] View/Pro and accessing Windows Printer API (gdi32.dll)
> Hello All!
>
> I am looking to add native printing support to my REBOL applications for
> Windows, but I am running into a problem with the library component of
> View/Pro. Here's the story:
>
> The following has C source code for sending raw data to a printer on
Windows.
>
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspo
l_93g2.asp
> Converting it to View/Pro was going well until I hit the OpenPrinter
routine!.
> Here's a transcript of my efforts:
> >> gdi32: load/library %gdi32.dll
<<quoted lines omitted: 4>>
> >> openprinter: make routine! ["Open Printer" pprintername [string!]
> phprinter [string!] pdefault [string!] return: [integer!]] gdi32
OpenPrinterA
> ** Access Error: Cannot open OpenPrinterA
> ** Near: openprinter: make routine! ["Open Printer" pprintername [string!]
<<quoted lines omitted: 3>>
> >> find gdi32 "OpenPrinter"
> >
{OpenPrinterA^@^@^@^@WritePrinter^@^@^@^@OPENGL32^@^@^@^@wglChoosePixelForma
t^@^@^@^@wglDescribePixelFormat^@^@wglGetPixelFormat...
[6/24] from: dockimbel:free at: 28-Jun-2002 0:09
Hi Paul,
Nope, just looked at VB WINAPI viewer and tested using Bo's sample replacing gdi32.dll
by winspool.drv. I just checked that 'make routine! was working for 'OpenPrinter.
-DocKimbel.
Paul Tretter wrote:
[7/24] from: amicom:sonic at: 28-Jun-2002 6:16
Thanks Doc and Gregg!
At 08:26 PM 6/27/02 +0200, you wrote:
[8/24] from: amicom:sonic at: 28-Jun-2002 10:33
OK, %winspool.drv is the correct library to use. Thanks! But now I have
other problems. Hopefully some of you familiar with C and the library
component of View/Pro will be able to help. Continuing from what I had in
my original message (contained below):
>> openprinter: make routine! ["Open Printer" pprintername [string!]
phprinter [char*] pdefault [string!] return: [integer!]]
winspool "OpenPrinterA"
>> hprinter: copy ""
== ""
;hprinter is the handle that should be returned by 'openprinter above if I
understand how 'openprinter works.
>> ret: openprinter "Brother MFC3100C" hprinter ""
== 1
;Great! 'openprinter returned 1 which indicates it worked!
>> hprinter
== ""
;Shouldn't 'hprinter now have some value that indicates the pointer? I've
also tried specifying 'phprinter above as LONG, but that didn't do it either
;Let's retrieve Windows' error code to see if there was an error
>> kernel32: load/library %kernel32.dll
>> getlasterror: make routine! [return: [long]] kernel32 "GetLastError"
>> ret: openprinter "Brother MFC3100C" hprinter ""
== 1
>> a: getlasterror
== 0
;OK! 'getlasterror states that there wasn't an error
>> hprinter
== ""
;but hprinter still is unchanged. Maybe my printer definition is
wrong. Let's try using an invalid name (missing the last C):
>> ret: openprinter "Brother MFC3100" hprinter ""
== 0
>> ret: openprinter "Brother MFC3100C" hprinter ""
== 1
;Well, I guess the second name IS valid according to 'openprinter. Maybe
that's not the issue...let's continue with the next routine.
>> startdocprinter: make routine! ["StartDocPrinter" hprinter [char*]
dwlevel [int] lpbdocinfo [struct! [cbsize [int] lpszdocn
ame [string!] lpszoutput [string!] lpszdatatype [string!] fwtype [int]]]
return: [int]] winspool "StartDocPrinterA"
>> dwjob: startdocprinter hprinter 1 docinfo
== 0
;Oh-oh! 'startdocprinter returned 0 which means it didn't work. Let's
find out why:
>> getlasterror
== 6
;This means the handle is invalid according to
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/errlist_7oz7.asp
;I'm thinking maybe passing 'hprinter as an argument to 'openprinter isn't
equivalent to passing &hprinter in C. Maybe we need to pass :hprinter
instead. Let's try this:
>> ret: openprinter "Brother MFC3100C" :hprinter ""
== 1
>> hprinter
== ""
>> dwjob: startdocprinter :hprinter 1 docinfo
== 0
>> getlasterror
== 6
;Same result. I've also tried replacing phprinter with a REBOL struct!,
but this crashed REBOL. I'm stumped. Any ideas?
At 08:26 PM 6/27/02 +0200, you wrote:
[9/24] from: cyphre:seznam:cz at: 28-Jun-2002 22:14
Hello Bo,
First of all I have to say that I'm not a C guru ;-) But we(together with
Pekr ;-)) were experimenting some time ago with Rebol DLL interface. We has
also lot of problems caused mainly by lacking the good docs but finally we
got to work rebol wrapper that is able to convert/proccess/load/save about
200 image formats!Really cool stuff. Unfortunately we couldn't get to work
showing images directly from the dll to View but I've written simple
intermediate library in C which will suit for that purposes...
I think in your case you need to pass the hprinter value as a pointer to
rebol integer!.
You could try following method:
>> hprinter: make integer! 0 ;this create an integer value in Rebol
== 0
>> hpr_str: make struct! [i [integer!]] reduce [hprinter] ;this is a
structure containing the Hprinter value
>> probe third hpr_str ;this give us the value(data) of hprinter
#{00000000}
== #{00000000}
But you probably don't need the data but pointer to this data, therefore we
make another structure which will point to the structure above....
>> phpr_str: make struct! compose/deep [pi [struct! [(first hpr_str)]]] none
;this create the struct
>> probe third phpr_str ;now you can see the real pointer in memory to the
hprinter!
#{703CD900}
== #{703CD900}
to get the data for testing if enything was changed we can made a reference
value in rebol:
hpr-ref: third phpr_str/pi
now you can put all it into the routine:
gdi32: load/library %winspool.drv
openprinter: make routine! compose/deep [
"Open Printer"
pprintername [string!]
phprinter [struct! [(first phpr_str)]]
pdefault [integer!]
return: [integer!]
] gdi32 "OpenPrinterA"
ret: openprinter "Brother MFC3100C" phpr_str 0
Unfortunately it doesnot work here under WIN XP. I was trying to get working
at least your example but it also returned 0 under so I cannot test it
further. Try to experiment with it under WIN98, maybe you will be more
succesfull.
Another thing is that I can be absoultely wrong ;-)
Good luck!
Best regards,
Cyphre
APPENDIX:
Here is explanation of argument of the OpenPrinter routine I found in my
WINAPI reference doc:
pPrinterName
The name of the printer or print server to obtain a handle to. If this is
an empty string, the function obtains a handle to the default print server.
phPrinter
Receives a handle to the newly opened printer.
pDefault
A printer defaults structure specifying some options for opening the
printer. To use the default settings, pass zero for this parameter.
----- Original Message -----
From: "Bohdan or Rosemary Lechnowsky" <[amicom--sonic--net]>
To: <[rebol-list--rebol--com]>
Sent: Friday, June 28, 2002 7:33 PM
Subject: [REBOL] Re: View/Pro and accessing Windows Printer API (gdi32.dll)
> OK, %winspool.drv is the correct library to use. Thanks! But now I have
> other problems. Hopefully some of you familiar with C and the library
<<quoted lines omitted: 14>>
> ;Shouldn't 'hprinter now have some value that indicates the pointer? I've
> also tried specifying 'phprinter above as LONG, but that didn't do it
either
> ;Let's retrieve Windows' error code to see if there was an error
> >> kernel32: load/library %kernel32.dll
<<quoted lines omitted: 25>>
> == 6
> ;This means the handle is invalid according to
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/errli
st_7oz7.asp
[10/24] from: dockimbel:free at: 29-Jun-2002 4:50
Hi,
This one seems to work but i'm not sure that the result is correct :
winspool: load/library %winspool.drv
hprinter: make struct! [address [char*]][""]
openprinter: make routine! compose/deep [
"Open Printer"
pprintername [string!]
phprinter [struct! [(first hprinter)]]
pdefault [integer!]
return: [integer!]
] winspool "OpenPrinterA"
ret: openprinter "Canon Bubble-Jet BJC-4300" hprinter 0
?? ret
print ["Handle =" to-integer to-issue enbase/base hprinter/address 16]
-DocKimbel.
Bohdan or Rosemary Lechnowsky wrote:
[11/24] from: greggirwin:mindspring at: 29-Jun-2002 9:23
Hi Bo,
<< ;hprinter is the handle that should be returned by 'openprinter above if
I
understand how 'openprinter works. >>
I think you need to pass a buffer and then check that when the call returns.
That's what I had to do to use the return connection ID from InternetDial.
Here's the idea. I have to run right now, but I'll check back tomorrow, or
mail me directly if this causes more confusion.
win-lib: load/library %wininet.dll
internet-dial: make routine! [
hwnd-parent [integer!]
connectoid [string!]
flags [integer!]
rtn-conn-id [char*] ; LPDWORD - either string! or char* work
here
reserved [integer!]
return: [integer!]
] win-lib "InternetDial"
;-- Internal support routines
null-buff: func [
{Returns a null-filled buffer of the specified length.}
len [integer!]
][
to-string array/initial len #"^@"
]
;-- Interface routines
connect: func [
{Initiates dial-up connection. Returns connection ID (to use with
disconnect) if successful; false otherwise.}
dial-up-name [string!]
/local id
][
id: null-buff 4
last-error: internet-dial no-hwnd dial-up-name dial-unattended id
zero
either all [(last-error = 0) (id <> null-buff 4)] [
last-error: none
return to-integer to-binary head reverse id
][
return false
]
]
HTH!
--Gregg
[12/24] from: g:santilli:tiscalinet:it at: 30-Jun-2002 11:26
Hi Gregg,
On Saturday, June 29, 2002, 5:23:23 PM, you wrote:
GI> null-buff: func [
GI> {Returns a null-filled buffer of the specified length.}
GI> len [integer!]
GI> ][
GI> to-string array/initial len #"^@"
GI> ]
head insert/dup make string! len #"^(00)" len
:-)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[13/24] from: greggirwin:mindspring at: 30-Jun-2002 13:20
Thanks Gabriele!
I have 3 or 4 versions of mk-string type functions floating around, most
from when I first started with REBOL. It's time to clean things up. :-)
--Gregg
[14/24] from: amicom:sonic at: 1-Jul-2002 9:41
Gregg,
Your solution does return an apparently valid handle when I apply it to
OpenPrinter, but StartDocPrinter still doesn't like it (returns a code of 6
which means "invalid handle").
Here's my script so far (beware of line-wrapping!):
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 [string!]
return: [integer!]
] winspool "OpenPrinterA"
print "Define StartDocPrinter"
startdocprinter: make routine! [
"StartDocPrinter"
hprinter [char*]
dwlevel [int]
lpbdocinfo [struct! [
cbsize [int]
lpszdocname [string!]
lpszoutput [string!]
lpszdatatype [string!]
fwtype [int]
]]
return: [int]
] 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
print "Create DocInfo Struct"
docinfo: make struct! [
cbsize [int]
lpszdocname [string!]
lpszoutput [string!]
lpszdatatype [string!]
fwtype [int]
][100 "Test Print" "" "" 0]
print "Call OpenPrinter"
print either zero? ret: openprinter "Brother MFC3100C" hprinter ""
["FAIL!"]["Success"]
prin "Current value: "
probe to-binary hprinter
print "Call StartDocPrinter"
print either zero? dwjob: startdocprinter hprinter 1 docinfo [["ERROR!"
getlasterror]]["SUCCESS!"]
halt
If anyone has suggestions on why StartDocPrinter doesn't like the handle,
I'd be very curious to find out!
Thanks for all the help so far. I'm hoping that someday REBOL users can
have graphical access to printers. I know it would make my applications a
lot more useful!
-Bo
At 09:23 AM 6/29/02 -0600, you wrote:
[15/24] from: greggirwin:mindspring at: 1-Jul-2002 20:44
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
[16/24] from: amicom:sonic at: 1-Jul-2002 23:30
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:
[17/24] from: g:santilli:tiscalinet:it at: 2-Jul-2002 12:16
Hi Bohdan,
On Monday, July 01, 2002, 6:41:08 PM, you wrote:
BoRL> Thanks for all the help so far. I'm hoping that someday REBOL users can
BoRL> have graphical access to printers. I know it would make my applications a
BoRL> lot more useful!
I actually prefer emitting PDF anyway, it's more easily
multiplatform... :-)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[18/24] from: amicom:sonic at: 2-Jul-2002 8:33
Gabriele,
I agree that PDF is more easily multiplatform, but sometimes you need the
output to go directly to the printer without any additional human
intervention. It would be nice if Acrobat could be told via an external
source (like REBOL) to print the current document. Additionally, Acrobat
loading on many machines is terribly slow.
It would be nice if REBOL had available printer support (kind of like
Python, but better). For that matter, printer page layout could use REBOL
faces so you could generate the output with View or VID and then send it to
the printer interface which does the conversion to the low-level printer
commands.
>> printer layout/origin [image %flag.gif text "Now is the time
for all good men to come to the aid of their country" 600 wrap] 10x20
The above would send the output directly to the default
printer. 'printer/query would query the user about which printer to use
and would allow the user to make adjustments to the print properties.
Simple things should be simple to do.
-Bo
At 12:16 PM 7/2/02 +0200, you wrote:
[19/24] from: cyphre:seznam:cz at: 2-Jul-2002 17:42
----- Original Message -----
From: "Bohdan or Rosemary Lechnowsky" <[amicom--sonic--net]>
To: <[rebol-list--rebol--com]>
Sent: Tuesday, July 02, 2002 8:30 AM
Subject: [REBOL] Re: View/Pro and accessing Windows Printer API (gdi32.dll)
...
> Anyway, here is the script (beware of line-wrapping). Let me know
directly
> if you have success/failure using this script:
>
...
Hi Bo,
the script doesnot work under WinXP(it crashes on "WritePrinter" call. IMO
incompatibilty between api of different Windows versions. I'll try to find
where is the problem...anyway will be tough to make it work between all
Windows transparently...
regards,
Cyphre
[20/24] from: g:santilli:tiscalinet:it at: 2-Jul-2002 19:13
Hi Bohdan,
On Tuesday, July 02, 2002, 5:33:39 PM, you wrote:
BoRL> I agree that PDF is more easily multiplatform, but sometimes you need the
BoRL> output to go directly to the printer without any additional human
BoRL> intervention.
That is absolutely true. However, users do not dislike to have a
screen preview of what they are going to print. At least, this has
not been a big problem to me, considering you are also giving the
user the ability so send the PDF via email etc. this way.
BoRL> It would be nice if Acrobat could be told via an external
BoRL> source (like REBOL) to print the current document.
Me and Gregg tried this using Window's ShellExecuteA; when asking
to print a PDF file, with something like:
win-lib: load/library %shell32.dll
execute: make routine! [
hwndParent [integer!]
Operation [string!]
File [string!]
Parameters [string!]
Directory [string!]
ShowCmd [integer!]
return: [integer!]
] win-lib "ShellExecuteA"
win-print-file:
func [file [file!]]
[ execute 0 "print" to-string to-local-file clean-path file "" "" 1]
we got inconsistent results unfortunately. I happened to me once
that win-print-file opened Acrobat and immediately sent the file
to the printer (without even showing it), but the first time I
tried it it only opened the file.
BoRL> Additionally, Acrobat
BoRL> loading on many machines is terribly slow.
That is true, too.
BoRL> It would be nice if REBOL had available printer support (kind of like
BoRL> Python, but better).
I agree, Bo. I just wanted to say that I've been able to live
without it, not that I wouldn't like to have it. ;-)
BoRL> Simple things should be simple to do.
Yes!
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[21/24] from: amicom:sonic at: 2-Jul-2002 10:37
Thanks for the report, Cyphre!
Yes, I think the problem you are experiencing is due to incompatibility
between Win95 and WinNT kernels. As you probably know, these are the two
basic kernels all versions of Windows are built on.
However, it should be possible to have the correct functions for each
kernel and only call the appropriate one depending on which OS you are
running. It may take a little extra work, but it shouldn't be *too* hard. :-)
-Bo
At 05:42 PM 7/2/02 +0200, you wrote:
[22/24] from: petr:krenzelok:trz:cz at: 2-Jul-2002 19:53
Bohdan or Rosemary Lechnowsky wrote:
> Thanks for the report, Cyphre!
> Yes, I think the problem you are experiencing is due to
<<quoted lines omitted: 5>>
> running. It may take a little extra work, but it shouldn't be *too*
> hard. :-)
And I think that Rebol should support printing and should do it using
port abstraction. Platform specific issues would be handled by rebol
port mechanism, as you always know, what system you are running on.
-pekr-
[23/24] from: greggirwin:mindspring at: 2-Jul-2002 11:54
Hi Bo,
Here are the changes I made to get it (sort of) working here.
.
.
.
print "Define WritePrinter"
writeprinter: make routine! [
"Write Printer"
hprinter [int]
lpdata [char*]
dwcount [int]
dwbyteswritten [char*] ;[int] This is another return value
return: [int]
] winspool "WritePrinter"
.
.
.
byteswritten: null-buff 4
; I had to add the form-feed here to make it flush on my laserjet.
; I'm not sure why the end-page stuff isn't doing it like I think it should.
; I could make it write to a file just fine without the form-feed.
testdata: {The quick brown fox jumped over the lazy dogs.^L}
print "Call WritePrinter"
either zero? writeprinter hprinter testdata length? testdata byteswritten [
print "FAIL!"
end-page-printer
end-doc-printer
close-printer
][print "Success"]
byteswritten: to-integer to-binary head reverse byteswritten
.
.
.
--Gregg
[24/24] from: greggirwin:mindspring at: 2-Jul-2002 11:54
Hi Bo,
<< It would be nice if Acrobat could be told via an external
source (like REBOL) to print the current document. >>
They don't make it easy, but it can be done. One catch is that it's tricky
to get right because Acrobat doens't like printing silently if it's already
running.
<< Additionally, Acrobat loading on many machines is terribly slow. >>
That I don't have an answer for. :)
<< It would be nice if REBOL had available printer support (kind of like
Python, but better). For that matter, printer page layout could use REBOL
faces so you could generate the output with View or VID and then send it to
the printer interface which does the conversion to the low-level printer
commands. >>
I've thought about this as well, but some issues with that approach are: 1)
the disparity in resolution and 2) what unit of measure should be used.
On the positive side, given a LAYOUT you might be able to generate output
commands without too much difficulty. I think a printing dialect, that know
how to deal with images, would be very nice though.
--Gregg
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted