Printing
[1/11] from: mattsmac:ho:tmail at: 12-Sep-2003 9:27
Ok, I know this gets asked alot, but does anybody know how to print in rebol
using the windows print dialog. I can't just hard code what port or printer
to use because I am making an application for varying users. All help would
be appreciated.
Matt
[2/11] from: greggirwin:mindspring at: 12-Sep-2003 10:35
Hi Matt,
MM> Ok, I know this gets asked alot, but does anybody know how to print in rebol
MM> using the windows print dialog. I can't just hard code what port or printer
MM> to use because I am making an application for varying users. All help would
MM> be appreciated.
A lot of people use either Gabriele's PDFMaker or write HTML and let
Acrobat or the browser deal with the details. If you want to call the
print dialog to set the printer, that should be doable (with View/Pro
or command for API access), but then you still have the issue of how
to render the data. Do you know how you're going to do that?
In any case, here's the function:
PrintDlg: make routine! compose/deep/only [
; pointer to structure with initialization data
lppd [struct! (LPPRINTDLG-def)] ;LPPRINTDLG
return: [integer!] ;BOOL
] comdlg32.dll "PrintDlg"
and the main struct you'd need:
PRINTDLG: make struct! PRINTDLG-def: compose/deep [
lStructSize [integer!] ; DWORD
hwndOwner [integer!] ; HWND
hDevMode [integer!] ; HANDLE (NULL or pointer to struct)
hDevNames [integer!] ; HANDLE (NULL or pointer to struct)
hDC [integer!] ; HDC
Flags [integer!] ; DWORD
nFromPage [short] ; WORD
nToPage [short] ; WORD
nMinPage [short] ; WORD
nMaxPage [short] ; WORD
nCopies [short] ; WORD
hInstance [integer!] ; HINSTANCE
lCustData [integer!] ; DWORD
lpfnPrintHook [integer!] ; LPPRINTHOOKPROC (decl for NULL, not struct)
lpfnSetupHook [integer!] ; LPSETUPHOOKPROC (decl for NULL, not struct)
lpPrintTemplateName [string!] ; LPCTSTR
lpSetupTemplateName [string!] ; LPCTSTR
hPrintTemplate [integer!] ; HANDLE
hSetupTemplate [integer!] ; HANDLE
] none
I've used it from other languages, but not REBOL, so this is all
untested stuff here.
-- Gregg
[3/11] from: rebol:techscribe at: 12-Sep-2003 10:15
Hi Gregg and Matt.
If you are using /Pro or /Command, then you should be able to render the
data using EMF diskbased files.
Elan
Gregg Irwin wrote:
[4/11] from: mattsmac:hotma:il at: 12-Sep-2003 13:44
Gregg
Ok, this stuff is all kinda new to me, how exactly do I use what you gave
me? There is not really any sophisticated data to render, just a couple of
strings, so anyway to do it is fine. Let me know,
Matt
Hi Matt,
MM> Ok, I know this gets asked alot, but does anybody know how to print in
rebol
MM> using the windows print dialog. I can't just hard code what port or
printer
MM> to use because I am making an application for varying users. All help
would
MM> be appreciated.
A lot of people use either Gabriele's PDFMaker or write HTML and let
Acrobat or the browser deal with the details. If you want to call the
print dialog to set the printer, that should be doable (with View/Pro
or command for API access), but then you still have the issue of how
to render the data. Do you know how you're going to do that?
In any case, here's the function:
PrintDlg: make routine! compose/deep/only [
; pointer to structure with initialization data
lppd [struct! (LPPRINTDLG-def)] ;LPPRINTDLG
return: [integer!] ;BOOL
] comdlg32.dll "PrintDlg"
and the main struct you'd need:
PRINTDLG: make struct! PRINTDLG-def: compose/deep [
lStructSize [integer!] ; DWORD
hwndOwner [integer!] ; HWND
hDevMode [integer!] ; HANDLE (NULL or pointer to
struct)
hDevNames [integer!] ; HANDLE (NULL or pointer to
struct)
hDC [integer!] ; HDC
Flags [integer!] ; DWORD
nFromPage [short] ; WORD
nToPage [short] ; WORD
nMinPage [short] ; WORD
nMaxPage [short] ; WORD
nCopies [short] ; WORD
hInstance [integer!] ; HINSTANCE
lCustData [integer!] ; DWORD
lpfnPrintHook [integer!] ; LPPRINTHOOKPROC (decl for NULL,
not struct)
lpfnSetupHook [integer!] ; LPSETUPHOOKPROC (decl for NULL,
not struct)
lpPrintTemplateName [string!] ; LPCTSTR
lpSetupTemplateName [string!] ; LPCTSTR
hPrintTemplate [integer!] ; HANDLE
hSetupTemplate [integer!] ; HANDLE
] none
I've used it from other languages, but not REBOL, so this is all
untested stuff here.
-- Gregg
_________________________________________________________________
Get 10MB of e-mail storage! Sign up for Hotmail Extra Storage.
[5/11] from: greggirwin:mindspring at: 12-Sep-2003 13:24
Hi Elan,
E> If you are using /Pro or /Command, then you should be able to render the
E> data using EMF diskbased files.
How do you create the EMFs though? I haven't dealt with metafile
format in many years. I seem to recall that EMF's big benefit was the
ability to embed raster elements. Not sure though.
-- Gregg
[6/11] from: greggirwin:mindspring at: 12-Sep-2003 13:35
Hi Matt,
MM> Ok, this stuff is all kinda new to me, how exactly do I use what you gave
MM> me? There is not really any sophisticated data to render, just a couple of
MM> strings, so anyway to do it is fine. Let me know,
Ah, sorry, I forgot you're kind of new to REBOL. You would need
View/Pro or Command to call DLL functions in any case, then the
declarations I posted could be used, but still may not solve your
problem.
The issue is that if you want Windows to handle things, you may have
to do more work. There are lots of ways to do it though. If you use
something like the ShellExecute API (again requiring View/Pro) you can
write the data out to a file and let the app registered to that type
print it.
You can also write the data out to an LPT port, but that may not work
too well. Others may know more than I do about that approach.
Writing HTML and letting the browser print it may be a good bet in
your case. Going to more complex APIs for rendering to DCs is going to
be painful.
I've used Gabriele's PDFMaker to write files and the print them
automatically. Kind of a pain IIRC, because of some issues with
Acrobat itself.
Hey, RT! What about a /PRINT refinement on BROWSE to do that kind of
thing silently?
-- Gregg
[7/11] from: rebol:techscribe at: 12-Sep-2003 13:16
Hi Gregg.
Typically something like this:
in the WndProc procedure
LRESULT WndProc( ....)
{
static HENHMETAFILE hemf;
HDC hdc, hdcemf;
PAINTSTRUCT ps;
RECT rect;
switch(iMsg)
case WM_CREATE :
hdcEMF = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
..
...
...
hemf = CloseEnhMetaFile(hdcEMF);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
...
PlayEnhMetaFile(hdc, hemf, &rect);
EndPaitn(hwnd, &ps);
return 0;
See:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/metafile_81yd.asp
and
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/metafile_0whf.asp
Hope this helps.
Elan
Gregg Irwin wrote:
[8/11] from: mattsmac::hotmail::com at: 12-Sep-2003 16:24
OK, Gregg, I found some stuff online that kindof says the same thing you
said the first time about using the external libraries. I'm not really
woried about the rendering right now, I just want to get the set-up right.
By combining you and their code I get:
rebol[]
print-lib: make library! %/c/windows/system32/comdlg32.dll
PRINTDLG: make struct! PRINTDLG-def: compose/deep [
lStructSize [integer!] ; DWORD
hwndOwner [integer!] ; HWND
hDevMode [integer!] ; HANDLE (NULL or pointer to
struct)
hDevNames [integer!] ; HANDLE (NULL or pointer to
struct)
hDC [integer!] ; HDC
Flags [integer!] ; DWORD
nFromPage [short] ; WORD
nToPage [short] ; WORD
nMinPage [short] ; WORD
nMaxPage [short] ; WORD
nCopies [short] ; WORD
hInstance [integer!] ; HINSTANCE
lCustData [integer!] ; DWORD
lpfnPrintHook [integer!] ; LPPRINTHOOKPROC (decl for NULL,
not struct)
lpfnSetupHook [integer!] ; LPSETUPHOOKPROC (decl for NULL,
not struct)
lpPrintTemplateName [string!] ; LPCTSTR
lpSetupTemplateName [string!] ; LPCTSTR
hPrintTemplate [integer!] ; HANDLE
hSetupTemplate [integer!] ; HANDLE
] none
PrintDlg: make routine! compose/deep/only [
; pointer to structure with initialization data
lppd: [struct! (LPPRINTDLG-def)] ;LPPRINTDLG
return: [integer!] ;BOOL
] print-lib "PrintDlg"
upon running that code , not that i expect it to do much by itself. I get
the following error.
** Script Error: LPPRINTDLG-def has no value
** Near: LPPRINTDLG-def
If i tweak it a little bit, I can get that error to go away, but then it
says it can't open PrintDlg
Any Ideas?
_________________________________________________________________
Fast, faster, fastest: Upgrade to Cable or DSL today!
[9/11] from: mattsmac:hotm:ail at: 12-Sep-2003 16:27
here's that error code
** Access Error: Cannot open PrintDlg
** Near: PrintDlg: make routine! compose/deep/only [
lppd: [struct! (LPPRINTDLG-def)]
return: [integer!]
]
_________________________________________________________________
Get a FREE computer virus scan online from McAfee.
[10/11] from: greggirwin:mindspring at: 12-Sep-2003 15:04
Hi Elan,
E> hdcEMF = CreateEnhMetaFile(NULL, NULL, NULL, NULL);
Right, but then all you have is a DC, so you still have to use other
APIs (e.g. DrawTextEx) to render data into that DC, and if you're
dealing with text then you're probably going to need to select font
objects in and out of it, etc., right?
Also, I'm not sure for EMF DCs if using NULL for the reference DC will
affect them. Not a problem for rendering to the screen of course. If
it does, then you might have to use CreateDC, which leads to DEVCAPS
stuff, and so on.
Just trying to look at what all would be involved. As soon as you get
into GDI stuff you end up going down a lot of little side-paths in my
experience. Lots of potential for resource leaks too.
-- Gregg
[11/11] from: greggirwin:mindspring at: 12-Sep-2003 15:07
Hi Matt,
MM> upon running that code , not that i expect it to do much by itself. I get
MM> the following error.
MM> ** Script Error: LPPRINTDLG-def has no value
MM> ** Near: LPPRINTDLG-def
MM> If i tweak it a little bit, I can get that error to go away, but then it
MM> says it can't open PrintDlg
Yeah, the LP needs to be removed to match the struct decl I posted,
sorry. I'll try to find time to take a look at it. The first thing to
try is changing:
print-lib "PrintDlg"
to
print-lib "PrintDlgA"
It does have string elements, so there's undoubtedly an ANSI version.
-- Gregg