I modified the routine is that the first call leaves your variables in
PUBLIC. After printing is done you need to call it to clean things up.
Seems to be working fine. I'll have to try it on the client site to
make sure.
A lot of effort on your part. Thanks. I have an information sheet on
my web site, I'd like to add you and your code to it. Who knows, maybe
some other fpw programmer can benefit from your work...Dennis
*
PROCEDURE fnPRINT_RAW
*
* THE PURPOSE OF THIS FUNCTION IS TO SEND RAW OUTPUT TO SPECIFED
* PRINTER VIA SPOOLER. DESIGNED AS WORK AROUND FOR FOXPRO 2.6A
* FOR WINDOWS BUG.
*
* PARAMETERS:
* cNAME - PRINTER DEVICE NAME, IF NOT CHARACTER THEN RELEASE
LIBRARIES
* cDATA - DATA OUTPUT
*
* PUBLIC:
* cMEMPATH - MEMORY FILE PATH STRING
* cPR_NAME - PRINTER DEVICE NAME
*
PARAMETERS cNAME, cDATA
IF .NOT. "FOXPRO 2.6A FOR WINDOWS" $ UPPER(VERSION())
IF TYPE("cDATA") = "C"
??? cDATA
ENDIF
RETURN .T.
ENDIF
IF !fnFILE(cMEMPATH+'foxtools.fll') .OR. !fnFILE(cMEMPATH+'call32.dll')
IF TYPE("cDATA") = "C"
??? cDATA
ENDIF
RETURN .T.
ENDIF
m.pprinter = ALLTRIM(IIF(TYPE("cNAME") = "C", cNAME,
IIF(TYPE("cPR_NAME")="C", cPR_NAME, "")))
IF EMPTY(m.pprinter)
IF TYPE("cDATA") = "C"
??? cDATA
ENDIF
RETURN .T.
ENDIF
IF !'FOXTOOLS' $ SET('LIBRARY')
SET LIBRARY TO (cMEMPATH+'foxtools') ADDITIVE
ENDIF
* "Andrew Howell" <microsoft.public.fox.programmer.exchange>
PRIVATE ALL LIKE l*
* returns .T. if all calls OK, .F. if anything went wrong
* (although you may get GPF before you can check return value..)
m.lallok=.t.
IF TYPE("_decl32") = "U"
PUBLIC _decl32, _free32, _close32, _edoc32, _epage32, _open32,
_stard32, _starp32, _write32
PUBLIC _close16, _edoc16, _epage16, _open16, _stard16, _starp16,
_write16
PUBLIC _hprint, _docinfo
_decl32=regfn('Declare32', 'CCC', 'L', cMEMPATH+'call32.dll')
_free32=regfn('FreeCall32IDs', '', '', cMEMPATH+'call32.dll')
* call Declare32 to register 32bit functions
_close32=callfn(_decl32, 'ClosePrinter', 'winspool.drv', 'i')
_edoc32=callfn(_decl32, 'EndDocPrinter', 'winspool.drv', 'i')
_epage32=callfn(_decl32, 'EndPagePrinter', 'winspool.drv', 'i')
_open32=callfn(_decl32, 'OpenPrinter', 'winspool.drv', 'ppi')
_stard32=callfn(_decl32, 'StartDocPrinter', 'winspool.drv', 'iip')
_starp32=callfn(_decl32, 'StartPagePrinter', 'winspool.drv', 'i')
_write32=callfn(_decl32, 'WritePrinter', 'winspool.drv', 'ipii')
* now register 16bit calls to pass through the 32bit calls
* (actually, 4 of these are identical but it's easier to remember by
(truncated) name <g>)
_close16=regfn('Call32', 'LL', 'L', cMEMPATH+'call32.dll')
_edoc16=regfn('Call32', 'LL', 'L', cMEMPATH+'call32.dll')
_epage16=regfn('Call32', 'LL', 'L', cMEMPATH+'call32.dll')
_open16=regfn('Call32', '***@CLL', 'L', cMEMPATH+'call32.dll')
_stard16=regfn('Call32', 'LLCL', 'L', cMEMPATH+'call32.dll')
_starp16=regfn('Call32', 'LL', 'L', cMEMPATH+'call32.dll')
_write16=regfn('Call32', 'LCLLL', 'L', cMEMPATH+'call32.dll')
* open printer and get its handle
* I should have been able to pass 0 as a long/int and get it back as
numeric,
* in fact I'm sure I did this whilst hacking and it worked
* but now it won't so I pass a null dword and convert it to int
_hprint=REPLICATE(CHR(0), 4)
=callfn(_open16, m.pprinter, @_hprint, 0, _open32)
_hprint=dwton(_hprint)
IF _hprint # 0
* docinfo_1 struct - 12 bytes:
* LPCTSTR DocName, 4
* LPCTSTR Output, 4
* LPCTSTR DataType, 4
_docinfo= REPLICATE(CHR(0), 12) && they appear as "Remote Downlevel
Document" having not passed a pointer to a name for the job..
* all the following calls return 0 if they fail
* if that happens then don't bother calling any more, just free
libraries and return
* start document
IF m.lallok
m.lallok=0#callfn(_stard16, _hprint, 1, _docinfo, _stard32)
ENDIF
* start page
IF m.lallok
m.lallok=0#callfn(_starp16, _hprint, _starp32)
ENDIF
ELSE
m.lallok = .f.
ENDIF
IF .NOT. m.lallok
DO ERR WITH 'Bad printer name "'+m.pprinter+'" ?', 'Error opening
printer..'
RETURN .f.
ENDIF
ENDIF
IF TYPE("cNAME") = "C"
* write data
IF _hprint # 0
IF m.lallok
m.lallok=0#callfn(_write16, _hprint, cDATA, LEN(cDATA), 0,
_write32)
ENDIF
IF .NOT. m.lallok
DO ERR WITH 'Error writing to printer..'
ENDIF
ENDIF
ELSE
IF _hprint # 0
* end page
IF m.lallok
m.lallok=0#callfn(_epage16, _hprint, _epage32)
ENDIF
* end document
IF m.lallok
m.lallok=0#callfn(_edoc16, _hprint, _edoc32)
ENDIF
* close printer
IF m.lallok
m.lallok=0#callfn(_close16, _hprint, _close32)
ENDIF
ENDIF
* free libraries
=callfn(_free32)
RELEASE _decl32, _free32, _close32, _edoc32, _epage32, _open32,
_stard32, _starp32, _write32
RELEASE _close16, _edoc16, _epage16, _open16, _stard16, _starp16,
_write16
RELEASE _hprint, _docinfo
ENDIF
RETURN m.lallok
*
*
* PRINT RAW ROUTINES SECTION.
*
FUNCTION dwton
*
* convert dword to fox numeric
*
PARAMETERS m.pstr
* pstr - [R] C binary dword
RETURN ASC(SUBSTR(m.pstr, 1, 1))+ ;
ASC(SUBSTR(m.pstr, 2, 1))*256+ ;
ASC(SUBSTR(m.pstr, 3, 1))*65536+ ;
ASC(SUBSTR(m.pstr, 4, 1))*16777216
*
* PRINT RAW ROUTINES SECTION EXIT.
*