Eu ficava pensando enquanto desenvolvia a interface de meu sistema, que até agora não ficou do jeito que eu queria em termos de beleza.
Da forma como esta chama muito a atenção das pessoas, mas uma interface é como uma obra de arte, e como no DOS minhas interfaces são preparadas para aguçar o desenvolvimento e desempenho de meus usuários.
Mas entre um design e outro das telas que são porta de entrada dos dados ficava a incógnita dos relatórios e impressos que deveriam ser cópias fiéis da versão DOS e tornar a transição indolor.
Como o 5Win tem muitos engines de impressão fica dificil escolher qual é o ideal. Usar Print, DOSPrint, Report, foi duro mas cheguei a conclusão que tenho de usar todos dependendo do resultado que desejo.
Abaixo estão a codificação completa do engine DOSPrint modificado e contendo um teste com caracteres gráficos conhecidos.
Este método deve ser usado para impressão sem preview já que os documentos em questão são pré-impressos e apenas recebem o conteúdo.
Abaixo encontra-se o código do .CH usado no exemplo:
/*
* File : Dosprin.ch
*/
#define ALEFT 0
#define ARIGHT 1
#define ACENTER 2
STATIC CPIMedium
STATIC CPINormal
STATIC CPICompress
STATIC CPILarge
STATIC CPIBold
STATIC CPITiny
STATIC CPINoTiny
STATIC CPIImage
STATIC CPIHeader
STATIC CPIFooter
STATIC CPIJump
STATIC CPIFormFeed
STATIC CPILength
#xcommand @ <nLine>,<nColumn> SAY <uData> ;
OF <oPrinter> ;
[ WIDTH <nWidth> ] ;
[ ALIGN <nAlign> ] ;
[ <lDuplicate: DUPLICATE> ] ;
[ <lMultiline: MULTILINE> ] ;
=> ;
<oPrinter>:Say(<nLine>,<nColumn>,<uData>,<nWidth>,.F.,<nAlign>,<.lDuplicate.>,<.lMultiline.>)
#xcommand ? <uData> ;
OF <oPrinter> ;
[ WIDTH <nWidth> ] ;
[ ALIGN <nAlign> ] ;
[ <lDuplicate: DUPLICATE> ] ;
[ <lMultiline: MULTILINE> ] ;
=> ;
<oPrinter>:Say(,,<uData>,<nWidth>,.T.,<nAlign>,<.lDuplicate.>,<.lMultiline.>)
#xcommand ?? <uData> ;
OF <oPrinter> ;
[ WIDTH <nWidth> ] ;
[ ALIGN <nAlign> ] ;
[ <lDuplicate: DUPLICATE> ] ;
[ <lMultiline: MULTILINE> ] ;
=> ;
<oPrinter>:Say(,,<uData>,<nWidth>,.F.,<nAlign>,<.lDuplicate.>,<.lMultiline.>)
#xcommand DEFINE DOS PRINTER <oPrinter> ;
[ ALIGN <nAlign> ] ;
[ TOP <nTop> ] ;
[ BOTTOM <nBottom> ] ;
[ LEFT <nLeft> ] ;
[ RIGHT <nRight> ] ;
[ WIDTH <nWidth> ] ;
[ LENGTH <nLength> ] ;
[ PORT <cPort> ] ;
[ PRINTER <cPrinter> ] ;
[ PAPER <nInches> ] ;
=> ;
<oPrinter> := TDosPrint():New(<nLeft>,<nRight>,<nTop>,<nBottom>,<nAlign>,<nWidth>,<nLength>,<cPort>,<cPrinter>,<nInches>)
#xcommand SET FONT <cFont> OF <oPrinter> ;
[ WIDTH <nWidth> ] ;
[ LEFT <nLeft> ] ;
=> ;
<oPrinter>:SetFont(<cFont>,<nWidth>,<nLeft>)
#xcommand NEWPAGE OF <oPrinter> ;
=> ;
<oPrinter>:NewPage()
#xcommand END OF <oPrinter> ;
=> ;
<oPrinter>:End()
Coloquei o código completo abaixo, recorte e cole dentro do notepad e salve.
/* File : Dosprin.prg
Autor : Jorge Mason
Wwww : www.htcsoft.cl
mail : htcsoft@iname.com
CopyRight : hctsoft
Version : 1.12
Description : CLASS for manage DOS printer
This version not need any .bat or .pif files
and work with any port printer like LPTx,COMx,\\netaddress,
and use Windows Spooler and setprinter method
*/
#include "FiveWin.ch"
#include "DosPrint.ch"
STATIC aLines, aFonts, cPrinter, cPort, nHeight, nLines, hFile, PRNcFile
STATIC nLeft, nRight, nTop, nBottom // Margins
STATIC nLine, nColumn, nAlign, nMultiLine // Position
STATIC nWidth, nLength // Page Sizes
STATIC cFont // Font
STATIC PRNcPort, PRNcPrinter, PRNnLeft, PRNnRight, PRNnTop, PRNnBottom:=0, ;
PRNnAlign, PRNnWidth, PRNnLength, PRNnLine, PRNnColumn, PRNnMultiLine,;
PRNcFont, PRNaLines, PRNaFonts, PRNhFile, PRNnHeight
FUNCTION DOSPRINT(cPort)
LOCAL oPrinter
LOCAL CONTADOR := 1
PUBLIC CPIMedium
PUBLIC CPINormal
PUBLIC CPICompress
PUBLIC CPILarge
PUBLIC CPIBold
PUBLIC CPITiny
PUBLIC CPINoTiny
PUBLIC CPIImage
PUBLIC CPIHeader
PUBLIC CPIFooter
PUBLIC CPIJump
PUBLIC CPIFormFeed
PUBLIC CPILength
DEFAULT cPort := "LPT1"
DEFINE DOS PRINTER oPrinter ;
ALIGN ACENTER ;
TOP 0 LENGTH 66 ;
PORT cPort ;
PAPER 166 ;
PRINTER "OKIDATA"
SET FONT CPICompress OF oPrinter WIDTH 73 LEFT 0
//oPrinter:ImportWMF("pedidos.wmf")
//oPrinter:SayImage(0,0,"logo.bmp",300,400,0)
@ 01, 00 SAY "ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿:ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿" OF oPrinter
@ 02, 00 SAY "³ ³³ Ú ¿ ³:³ ³" OF oPrinter
@ 03, 00 SAY "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´³ ³:ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´" OF oPrinter
@ 04, 00 SAY "³ NOME DO CLIENTE ³³ ³:³ NOME DO CLIENTE ³" OF oPrinter
@ 05, 00 SAY "³ TAKAU HOMBO-ME ³³ C A R I M B O ³:³ TAKAU HOMBO-ME ³" OF oPrinter
@ 06, 00 SAY "ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´³ ³:ÃÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´" OF oPrinter
@ 07, 00 SAY "³ PARCELA ³ VENCIMENTO ³ VALOR EM (R$) ³³ ³:³ PARCELA ³ VENCIMENTO ³ VALOR EM (R$) ³" OF oPrinter
@ 08, 00 SAY "³ 001/03 ³ 18/10/2004 ³ 366,67 ³³ ³:³ 001/03 ³ 18/10/2004 ³ 366,67 ³" OF oPrinter
@ 09, 00 SAY "ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´³ _________________________ ³:ÃÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´" OF oPrinter
@ 10, 00 SAY "³ CLIENTE ³ APROVACAO ³ CONTRATO ³³ A S S I N A T U R A ³:³ A T E N C A O ³" OF oPrinter
@ 11, 00 SAY "³ 00240 ³ 28/09/2004 ³ 001675 ³³ ³:³ EM CASO DE DUVIDA SOBRE O SEU CARNE ³" OF oPrinter
@ 12, 00 SAY "ÃÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´³ _______/________/________ ³:³ LIGUE PARA ³" OF oPrinter
@ 13, 00 SAY "³ EVITE PAGAR JUROS QUITANDO EM DIA ³³ D A T A ³:³ ( 0 1 1 ) 3 9 9 1 - 3 9 2 3 ³" OF oPrinter
@ 14, 00 SAY "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ:ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ" OF oPrinter
/*
USE C_PEDIDO NEW
GO TOP
DO WHILE CONTADOR < 10
@ 3,10 SAY "Eficacia de frenos menos que la norma asi que llevalo a un taller lo antes posible" OF oPrinter ;
WIDTH 20 ALIGN ACENTER DUPLICATE MULTILINE
@ 10,30 SAY C_PEDIDO->OBSERVA OF oPRINTER WIDTH 32 ALIGN ALEFT MULTILINE
? "------------------------------------------------------------" OF oPrinter ALIGN ACENTER DUPLICATE
? "Jorge" OF oPrinter
?? " Mason " OF oPrinter
?? " from htcsoft" OF oPrinter
*/
NEWPAGE OF oPrinter
/*
CONTADOR ++
SKIP + 1
ENDDO
*/
END OF oPrinter
RETURN nil
/*
* ****** ****** ****** ******
* ****** DOS PRINT ******
* ****** ****** ****** ******
*/
FUNCTION PRNEnd(_preview_) //CLASS TDosPrint
default _preview_ := .f.
FCLOSE( PRNhFile )
if _preview_
WAITRUN("write " + PRNcFile, 0 )
else
WAITRUN("command.com /c copy /b " + PRNcFile + " lpt1" , 0 )
endif
//FERASE( PRNcFile )
RETURN nil
FUNCTION PRNNewPage( pula ) //CLASS TDosPrint
LOCAL nStep
LOCAL nUltima := LEN(PRNaLines)
//msgstop( LEN(PRNaLines))
FWRITE( PRNhFile , CPILength + CHR(PRNnHeight) + CPIHeader )
WHILE EMPTY(PRNaLines[nUltima])
--nUltima
if nUltima < 1
exit
endif
END
FOR nStep = 1 TO nUltima
FWRITE( PRNhFile , PRNaFonts[nStep] + TRIM(PRNaLines[nStep]) + CRLF )
NEXT
IF pula = nil
FWRITE( PRNhFile , CPIFormFeed + CPIFooter )
ENDIF
AFILL(PRNaLines,SPACE(500))
AFILL(PRNaFonts,"")
PRNnLine = PRNnTop + 1
PRNnColumn = 1
SysRefresh()
RETURN nil
FUNCTION PRNPaint(nLine,nColumn,uData,nAlign,nWidth,lDuplicate) //CLASS TDosPrint
LOCAL linea := nLine + PRNnTop
LOCAL cLine
DEFAULT PRNnBottom := 0
IF nLine + PRNnTop <= PRNnLength - PRNnBottom .AND. ;
nLine > PRNnTop
cLine = PRNaLines[nLine+PRNnTop]
DO CASE
CASE nAlign = ALEFT
uData = PADR(uData,nWidth)
CASE nAlign = ARIGHT
uData = PADL(uData,nWidth)
CASE nAlign = ACENTER
IF nWidth > LEN(uData)
uData = PADR(SPACE((nWidth-LEN(uData))/2)+uData,nWidth)
ELSE
uData = PADR(uData,nWidth)
ENDIF
ENDCASE
cLine = LEFT(cLine,nColumn-1+PRNnLeft) + uData + SUBS( cLine , (nColumn+LEN(uData)+PRNnLeft) )
IF lDuplicate
cLine = PADR( PADR(cLine,PRNnWidth) + PADR(cLine,PRNnWidth) , 500 )
ENDIF
PRNaLines[nLine+PRNnTop] = cLine
PRNaFonts[nLine+PRNnTop] = PRNcFont
ENDIF
RETURN nil
FUNCTION PRNSay(nLine,nColumn,uData,nWidth,lNextLine,nAlign,lDuplicate,lMultiline) //CLASS TDosPrint
LOCAL nNext := 0
LOCAL cLine
LOCAL nAt
DEFAULT uData := "" ,;
nWidth := LEN( cValToChar(uData) ) ,;
nAlign := ALEFT ,;
lDuplicate := .F. ,;
lNextLine := .F. ,;
lMultiLine := .F.
IF nLine = nil
nLine = MIN( PRNnLine + IF( lNextLine , MAX(PRNnMultiLine,1) , 0 ) , PRNnLength )
IF lNextLine
PRNnMultiLine = 0
ENDIF
ENDIF
IF nColumn = nil
IF lNextLine
nColumn = 1
ELSE
nColumn = PRNnColumn
ENDIF
ENDIF
uData = cValtoChar( uData )
IF lMultiLine
WHILE !EMPTY(uData)
IF ( nAt := AT(CRLF,uData) ) < nWidth .AND. ;
nAt > 0
cLine = Saca(@uData,CRLF)
ELSE
cLine = Corta(@uData,nWidth)
ENDIF
PRNPaint(nLine+nNext,nColumn,cLine,nAlign,nWidth,lDuplicate)
++nNext
IF nLine + nNext > PRNnLength - PRNnBottom
PRNNewPage()
nLine = PRNnTop + 1
nNext = 0
ENDIF
PRNnMultiLine = MAX( PRNnMultiLine , nNext )
END
ELSE
PRNPaint(nLine,nColumn,uData,nAlign,nWidth,lDuplicate)
ENDIF
PRNnColumn = nColumn + nWidth
PRNnLine = nLine
RETURN nil
FUNCTION PRNSetFont(cFont,nWidth,nLeft) //CLASS TDosPrint
DEFAULT cFont := CPINormal ,;
nWidth := PRNnWidth ,;
nLeft := PRNnLeft
PRNcFont := cFont
PRNnWidth := nWidth
PRNnLeft := nLeft
RETURN .t.
FUNCTION PRNNew( nLeft,nRight,nTop,nBottom,nAlign,nWidth,nLength,cPort,cPrinter,nHeight) //CLASS TDosPrint
DEFAULT PRNnLeft := 0 ,;
PRNnRight := 0 ,;
PRNnTop := 0 ,;
PRNnBottom := 0 ,;
PRNnAlign := ALEFT ,;
PRNnWidth := 80 ,;
PRNnLength := 66 ,;
PRNcPort := "LPT1" ,;
PRNcPrinter := "IBM-PROPRINTER" ,;
PRNnHeight := 11
PRNcPort := cPort
PRNcPrinter := cPrinter
PRNnLeft := nLeft
PRNnRight := nRight
PRNnTop := nTop
PRNnBottom := nBottom
PRNnAlign := nAlign
PRNnWidth := nWidth
PRNnLength := nLength
PRNnLine := PRNnTop + 1
PRNnColumn := 1
PRNnMultiLine := 1
PRNcFont := ""
PRNaLines := ARRAY(nLength)
PRNaFonts := ARRAY(nLength)
PRNhFile := FCREATE( PRNcFile := L2HEX(GETTICKCOUNT())+".POS" , 0 )
AFILL(PRNaLines,SPACE(500))
AFILL(PRNaFonts,"")
PRNSetPrinter(cPrinter)
//PRNSetHeight(nHeight)
RETURN nil
FUNCTION PRNSetPrinter(cPrinter) //CLASS TDosPrint
LOCAL oIni
LOCAL cCompress
LOCAL cNormal
LOCAL cMedium
LOCAL cLarge
LOCAL cBold
LOCAL cTiny
LOCAL cNoTiny
LOCAL cImage
LOCAL cHeader
LOCAL cFooter
LOCAL cJump
LOCAL cFormFeed
LOCAL cLength
INI oIni FILE "Dosprint"
GET cNormal SECTION cPrinter ENTRY "Normal" OF oIni DEFAULT "27,70,27,84,27,50,27,15,18"
GET cBold SECTION cPrinter ENTRY "Bold" OF oIni DEFAULT "27,18,27,69"
GET cMedium SECTION cPrinter ENTRY "Medium" OF oIni DEFAULT "27,70,27,58"
GET cCompress SECTION cPrinter ENTRY "Compress" OF oIni DEFAULT "27,70,27,84,27,15"
GET cLarge SECTION cPrinter ENTRY "Large" OF oIni DEFAULT "27,69,27,18,27,14"
GET cTiny SECTION cPrinter ENTRY "Tiny" OF oIni DEFAULT "27,70,27,83,0,27,49,18,15"
GET cNoTiny SECTION cPrinter ENTRY "NoTiny" OF oIni DEFAULT "27,70,27,84,27,50"
GET cImage SECTION cPrinter ENTRY "Image" OF oIni DEFAULT "27,76"
GET cHeader SECTION cPrinter ENTRY "Header" OF oIni DEFAULT ""
GET cFooter SECTION cPrinter ENTRY "Footer" OF oIni DEFAULT ""
GET cJump SECTION cPrinter ENTRY "Jump" OF oIni DEFAULT "216"
GET cFormFeed SECTION cPrinter ENTRY "FormFeed" OF oIni DEFAULT "12"
GET cLength SECTION cPrinter ENTRY "Length" OF oIni DEFAULT "27,67,0"
ENDINI
CPINormal = cPrnCodes( cNormal )
CPIBold = cPrnCodes( cBold )
CPIMedium = cPrnCodes( cMedium )
CPICompress = cPrnCodes( cCompress )
CPILarge = cPrnCodes( cLarge )
CPITiny = cPrnCodes( cTiny )
CPINoTiny = cPrnCodes( cNoTiny )
CPIImage = cPrnCodes( cImage )
CPIHeader = cPrnCodes( cHeader )
CPIFooter = cPrnCodes( cFooter )
CPIJump = cPrnCodes( cJump )
CPIFormFeed = cPrnCodes( cFormFeed )
CPILength = cPrnCodes( cLength )
RETURN nil
FUNCTION cPrnCodes(cPrnCodes,cDelimited)
LOCAL cCodes := ""
DEFAULT cDelimited := ","
WHILE !EMPTY(cPrnCodes)
cCodes += CHR( VAL( Saca(@cPrnCodes,cDelimited) ) )
END
RETURN cCodes
FUNCTION Corta(cVar,nAt)
LOCAL cReturn := LEFT( cVar , nAt )
cVar = SUBS( cVar , nAt + 1 )
RETURN TRIM(cReturn)
FUNCTION Saca(cVariable,cString,lUpper,lLtrim)
LOCAL nPosition
LOCAL cResult
DEFAULT lUpper := .f. ,;
lLTrim := .f.
nPosition := AT( cString , IF( lUpper , UPPER(cVariable) , cVariable ) + cString )
cResult := LEFT( cVariable , nPosition - 1 )
cVariable = SUBS( cVariable , nPosition + LEN(cString) )
cVariable = IF( lLtrim , LTRIM(cVariable) , cVariable )
RETURN cResult
Boa sorte.