Página 1 de 1

Imprimir numa impressora matricial

Enviado: 08 Nov 2016 20:55
por Tomaz Edson Linhares
Olá amigos,
Tenho 02 impressoras matriciais (Bermath e Epson Lx-300) e fiz um programinha com tabela de preços e queria imprimir um relatório nessas impressoras. Na jato de tinta em USB eu imprimo sem dificuldades mas nas
matriciais não consigo, alias, consigo imprimir sim, quando segui o exemplo da pasta Samples , mas sem controle nos caracteres e quando termina
a impressão ela fica saltando diversas linhas no fim da impressão. No clipper eu imprimir nas matriciais sem problemas mas no Minigui não consegui controlar. No clipper eu fazia assim

Set print on
set device to print
....
? chr(15) *** para imprimir condensado
@ prow()+1,1 say "Nome do Produto : " + nProduto
? chr(14) *** para imprimir Expandindo
@ prow()+1,1 say "Preço do Produto : " + pProduto
. ....
eject *** só para a Epson, pois a Bermath é de bobina 33 colunas
set print off
set device to screen

Mas no minigui até imprime, mas quando termina a impressão fica saltando diversas linhas em branco e não sei
como parar isso.

Se não for pedir muito, teria como alguém postar um pequeno exemplo que venha do zero, para imprimir na impressora
matricial Bermateh ou na Epson Lx-300
uma relação de produtos com o título expandido 'chr(14)' e os demais condensado 'chr(15)'e normais 'chr(18)', para
eu ter uma noção de como fazer. E também qual comando uso para ela não ficar saltando diversas linhas em branco no final do relatório.

Imprimir numa impressora matricial

Enviado: 10 Nov 2016 09:28
por Pablo César
Oi Tomaz, basicamente muito pouca coisa mudou no Harbour. Alias, não mudou nada sobre o que já sabíamos em Clipper, tudo é 100% compativel. Seja HMG ou qualquer outra ferramenta seja gráfica ou não, o que realmente manda é compilador Harbour. O que mudou é o sistema operacional Windows que requer um certo cuidado. Há muito tempo eu escolhi para não jogar diretamente no spool de impressão e muito menos verificar se a impressora está pronta como faziamos antes nos antigos Windows. Todo relatório eu gosto de direcionar a impressão em arquivo, isso reduze o tempo de resposta e fica muito mais seguro e prático para imprimir. Já pensou poder visualizar o arquivo antes de imprimir ou até mesmo repetir a impressão por falta de papel na impressora e fazer tudo isso sem ter que repocessar a composição do seu relatório?. Acho que você já deve saber como direcionar a impressão para arquivo, não é ?
Sobre os comandos, sejam do tipo EPSON ou do tipo HP (tinta/laser) podem ser utilizados desde que a sua impressora comporte o modo RAW. Verifique as propriedades da impressora ou na internet pela marca e modelo.

Outra coisa que você deve verificar se quiser imprimir em paralela é na BIOS do PC se está habilitado o padrão ECP. (http://www.bpiropo.com.br/paralela.htm)

Depois que você tem o arquivo texto para imprimir é só utilizar:

If !(Win_PrintFileRaw(cPrinter,cFile,"Descrição do job "+cFile)>0)
   cMsgErrorPrint := "Não imprimiu na "+cPrinter+" (Modo Raw)."+CRLF+"Tente outra impressora."
  • cPrinter: deve ser o nome da impressora instalada no Windows (nome exato, a função Win_PrinterGetDefault() retoirna o nome padrão, mas cuidado nem sempre é a impressora que você deseja porque o usuário muda sempre).
Você também poderá imprimir em modo gráfico que é muito mais certeiro, porém gasta mais tinta, mais lento e é totalmente outra composição para fazer a impressão.

Se a sua impressão for paralela e a paralela estiver habilitada. Você também poderá fazer com um simples comando:

If !(FileCopy(cFile,cPrinter)>0) // cPrinter pode ser: "LPT1", "\\computador\nome_do_compartilhamento"
   cMsgErrorPrint := "Não imprimiu na "+cPrinter+" (Modo Texto)."+CRLF+"Tente outra impressora."

Sobre o salto de página, não utilize a ultima página ao menos que a impressora requera isso. Também depende da impressora se está configurada ou não para dar o salto no final. Deixe opcional.

Espero ter podido responder todas as suas dúvidas.

Imprimir numa impressora matricial

Enviado: 15 Nov 2016 16:08
por Tomaz Edson Linhares
Olá amigo, obrigado pela sua atenção, e peço mais ajuda.

Baixei um exemplo de impressão e fiz algumas adaptações somente na função PRINT_ORCAR. Mas está dando um erro que eu não consegui identificar. Quando eu abro um arquivo para extrair os dados dele e mando imprimir, vem uma mensagem dizendo que o arquivo de dados não existe.

a impressora é uma Bematech 33 colunas.

As impressoras são reconhecidas normalmente mas dá erro na hora da impressão.

O que me deixou intrigado, é que se eu não abrir nenhum arquivo DBF e mandar imprimir, é impresso normal, ou Seja, se eu por exemplo fizer assim :

? ' Relatório de Pedido '
? ' '
? ' Nome

assim a impressão é realizada, mas se eu mandar extrair de um DBF dá erro.

Do exemplo que baixei, só alterei a função PRINT_ORCAR , e mais nada.

Acho que tem alguma instrução que impedi abrir os DBFs, que eu não consegui identificar.

Imprimir numa impressora matricial

Enviado: 15 Nov 2016 16:11
por Tomaz Edson Linhares
ESSE É O FONTE:

Código: Selecionar todos


 ANNOUNCE RDDSYS

#include "minigui.ch"

#ifndef __XHARBOUR__
#xtranslate At(<a>,<b>,[<x,...>]) => hb_At(<a>,<b>,<x>)
#endif
#define Alert( c ) MsgExclamation( c, "Atenção" )

#define TAB       CHR(9)
#define FORMFEED  CHR(12)
#define CR        CHR(13)
#define CRLF      CHR(13)+CHR(10)

#define TESTFILE "__testFile.txt"
 
//////////////////////////////
PROCEDURE main()
//////////////////////////////

	DEFINE WINDOW Win_1 ;
		AT 0,0 ;
		WIDTH 640 ;
		HEIGHT 480 ;
		TITLE 'Seleção de Impressoras' ;
		MAIN ;
		TOPMOST NOMINIMIZE NOMAXIMIZE NOSIZE ;
		ON INIT DEFINE_PRINT() ;
		ON RELEASE FERASE(TESTFILE)

	END WINDOW

	CENTER WINDOW Win_1
	ACTIVATE WINDOW Win_1

RETURN

*--------------------
function opentables()

***  DADOS.DBF   Recebe o número do orcamento (ORCAR) CARACTER  5
***              Recebe o nome do cliente (NOME)      CARACTER 20
***				  Recebe o endereço do cliente (END)   CARACTER 20

 USE DADOS ALIAS DAD NEW SHARED
  IF ! FILE("IND1_DAD.NTX")
   INDEX ON ORCAR TO IND1_DAD
  ENDIF
 SET INDEX TO IND1_DAD
*------------------------------------     

***  PEDIDOS.DBF  Recebe o número do orcamento (ORCAR)    CARACTER  5
***               Recebe o nome do produto (DESCR)        CARACTER 20
***				   Recebe a quantidade do produto (QUANT)  NUMERIC  10   2

USE PEDIDOS ALIAS PED  NEW SHARED
 IF ! FILE("IND1_PED.NTX")
  INDEX ON ORCAR TO IND1_PED
 ENDIF
 SET INDEX TO IND1_PED

return nil
* -------------------
//////////////////////////////
PROCEDURE DEFINE_PRINT()
//////////////////////////////
  LOCAL aPrn, nPos

 
  @ 10, 10 LABEL LBL_PRINT_1 ;
	OF Win_1 ;
	VALUE "Selecione a impressora no menu" AUTOSIZE

  IF EMPTY( aPrn := WinGetPrinters() )
    Alert("Atenção, Impressora não instalada!")
  ELSE
    // Locate default windows printer and set as starting selection
    IF EMPTY( nPos := ASCAN( aPrn, WinDefaultPrinter() ) )
      nPos := 1
    ENDIF
    IF !EMPTY( nPos := MENU_PRINT( 3,0,20,33,aPrn,,,nPos ) )
      PRINT_ORCAR( aPrn[nPos] )
    ELSE
      Win_1.Release
    ENDIF
  ENDIF

RETURN

//////////////////////////////
FUNCTION MENU_PRINT( t, l, b, r, aItems, cTitle, dummy, nValue )
//////////////////////////////

	DEFAULT cTitle TO "Selecione a impressora", nValue TO 0

	DEFINE WINDOW Win_2 ;
		AT 0,0 ;
		WIDTH 400 HEIGHT 300 ;
		TITLE cTitle ;
		ICON 'MAIN' ;
		TOPMOST ;
		NOMAXIMIZE NOSIZE ;
		ON INIT Win_2.Button_1.SetFocus
 
		@ 235,190 BUTTON Button_1 ;
		CAPTION 'OK' ;
		ACTION {|| nValue := Win_2.List_1.Value, Win_2.Release } ;
		WIDTH 80

		@ 235,295 BUTTON Button_2 ;
		CAPTION 'Cancel' ;
		ACTION {|| nValue := 0, Win_2.Release } ;
		WIDTH 80

		@ 20,15 LISTBOX List_1 ;
		WIDTH 360 ;
		HEIGHT 200 ;
		ITEMS aItems ;
		VALUE nValue ;
		FONT "Ms Sans Serif" ;
		SIZE 12 ;
		ON DBLCLICK {|| nValue := Win_2.List_1.Value, Win_2.Release }

	END WINDOW
   
	CENTER WINDOW Win_2
	ACTIVATE WINDOW Win_2

RETURN nValue


Imprimir numa impressora matricial

Enviado: 15 Nov 2016 16:13
por Tomaz Edson Linhares

Código: Selecionar todos

//////////////////////////////
// This function prints the entire file in one call to PrintFileRaw()
FUNCTION VALIDA_PRINT(cPrinter,cFileName,cDocumentName)
//////////////////////////////
  LOCAL nPrn:= -1, cMess:= ""

  IF !EMPTY(cFilename)
    IF (nPrn := PrintFileRaw(cPrinter,cFileName,cDocumentName)) < 0
      DO CASE
      CASE nPrn = -1
        Alert(cMess+"Incorrect parameters passed to function")
      CASE nPrn = -2
        Alert(cMess+"WINAPI OpenPrinter() call failed")
      CASE nPrn = -3
        Alert(cMess+"WINAPI StartDocPrinter() call failed")
      CASE nPrn = -4
        Alert(cMess+"WINAPI StartPagePrinter() call failed")
      CASE nPrn = -5
        Alert(cMess+"WINAPI malloc() of memory failed")
      CASE nPrn = -6
        Alert(cMess+"WINAPI CreateFile() call failed - File "+cFileName+" no found??")
      ENDCASE
    ENDIF
  ENDIF

RETURN(nPrn)

//////////////////////////////
STATIC FUNCTION PRINT_ORCAR(cPrinter)
//////////////////////////////
 SET CONS OFF
 SET ALTE TO (TESTFILE)            
 SET ALTE ON
 
vORCAR := 1  /// Numero do pedido que será impresso

SELECT DAD 
go top
 locate for VAL(ORCAR) = vORCAR
	IF FOUND()
	  ?  'Relatorio de pedido'
     ?
     ? 'Nome : ' + DAD->nome 
     ? 'Endereço : ' + DAD->end 
	  ? ''
  	  ? 'COD.PROD. Descrição      QUANT'
	  ? ''
	  ? ''
    SELECT PED
		go top
		locate for VAL(ORCAR) = VORCAR 
	    while .not. eof()
          if VAL(ORCAR) = vORCAR 
			   ? PED->cod + ' '+ PED->descr +' '+PED->(transform(quant, "@r 99,999.999"))
 	         ? ''
		    endif
           PED->(dbskip())
       enddo
   ENDIF
  SET ALTE OFF
  SET ALTE TO
  SET CONS ON
  set printer off
  Valida_print(cPrinter, TESTFILE, "Impressão Concluída com sucesso!")
RETURN(.T.)

//////////////////////////////
FUNCTION WinGetPrinters()
//////////////////////////////
  LOCAL aPrn := {}, nStart := 1, cPrinters, nStop, nPos, cPrn
  cPrinters := EnumPrinters()+';'
  nStop := LEN(cPrinters)+1
  DO WHILE nStart < nStop
    nPos := AT(';', cPrinters, nStart)
    IF !EMPTY(cPrn := SUBSTR(cPrinters, nStart, nPos-nStart))
      AADD(aPrn, cPrn)
    ENDIF
    nStart := nPos+1
  ENDDO
RETURN(aPrn)


#pragma BEGINDUMP

#undef UNICODE

#include <windows.h>
#include "hbapi.h"
#include "hbvm.h"
#include "hbstack.h"
#include "hbapiitm.h"

#ifndef __XHARBOUR__
   #define ISCHAR( n )           HB_ISCHAR( n )
#endif

#define MAX_FILE_NAME 1024
#define BIG_BUFFER (1024*32)

HB_FUNC ( ENUMPRINTERS )
{
  UCHAR *Result ;
  DWORD x, Flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS ;
  LPSTR Name = NULL ;
  DWORD Level = 5 ;
  PRINTER_INFO_5 *pPrinterEnum, *pFree;
  PRINTER_INFO_4 *pPrinterEnum4, *pFree4;
  DWORD cbBuf  ;
  DWORD BytesNeeded=0 ;
  DWORD NumOfPrinters=0 ;
  OSVERSIONINFO osvi ;  //  altered to check Windows Version
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  GetVersionEx (&osvi);
  if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
  {
    Level = 4 ;
    EnumPrinters(Flags,Name,Level,(LPBYTE) pPrinterEnum4,0,&BytesNeeded,&NumOfPrinters) ;
    if (BytesNeeded > 0)
    {
      Result = (UCHAR *) hb_xgrab(BytesNeeded) ;
      *Result = '\0' ;
      pFree4 = pPrinterEnum4 = (PRINTER_INFO_4 *)  hb_xgrab(BytesNeeded) ;
      cbBuf = BytesNeeded ;
      if (EnumPrinters(Flags,Name,Level,(LPBYTE) pPrinterEnum4,cbBuf,&BytesNeeded,&NumOfPrinters))
      {
        for (x=0 ; x < NumOfPrinters ; x++, pPrinterEnum4++ )
        {
          strcat(Result,pPrinterEnum4->pPrinterName) ;
          strcat(Result,";") ;
        }
      }
      hb_retc(Result) ;
      hb_xfree(Result) ;
      hb_xfree(pFree4) ;
    }
    else
      hb_retc("") ;
  }
  else
   {
    EnumPrinters(Flags,Name,Level,(LPBYTE) pPrinterEnum,0,&BytesNeeded,&NumOfPrinters) ;
    if (BytesNeeded > 0)
    {
      Result = (UCHAR *) hb_xgrab(BytesNeeded) ;
      *Result = '\0' ;
      pFree = pPrinterEnum = (PRINTER_INFO_5 *)  hb_xgrab(BytesNeeded) ;
      cbBuf = BytesNeeded ;
      if (EnumPrinters(Flags,Name,Level,(LPBYTE) pPrinterEnum,cbBuf,&BytesNeeded,&NumOfPrinters))
      {
        for (x=0 ; x < NumOfPrinters ; x++, pPrinterEnum++ )
        {
          strcat(Result,pPrinterEnum->pPrinterName) ;
          strcat(Result,";") ;
        }
      }
      hb_retc(Result) ;
      hb_xfree(Result) ;
      hb_xfree(pFree) ;
    }
    else
      hb_retc("") ;
  }
}

Imprimir numa impressora matricial

Enviado: 15 Nov 2016 16:15
por Tomaz Edson Linhares

Código: Selecionar todos

HB_FUNC( WINDEFAULTPRINTER )
{
  DWORD x, y ;
  UCHAR lpReturnedString[MAX_FILE_NAME] ;
  x = GetProfileString("windows","device","",lpReturnedString,MAX_FILE_NAME-1);
  y = 0 ;
  while ( y < x && lpReturnedString[y] != ',' )
    y++ ;
  hb_retclen(lpReturnedString,y) ;
}

Imprimir numa impressora matricial

Enviado: 15 Nov 2016 16:17
por Tomaz Edson Linhares

Código: Selecionar todos

HB_FUNC( PRINTFILERAW )
{
  UCHAR  printBuffer[BIG_BUFFER], *cPrinterName, *cFileName, *cDocName ;
  HANDLE  hPrinter, hFile ;
  DOC_INFO_1 DocInfo ;
  DWORD nRead, nWritten, rVal = -1 ;
  if (ISCHAR(1) && ISCHAR(2))
  {
    cPrinterName= (UCHAR*)hb_parc(1) ;
    cFileName= (UCHAR*)hb_parc(2) ;
    if ( OpenPrinter(cPrinterName, &hPrinter, NULL) != 0 )
    {
      DocInfo.pDocName = (UCHAR*)hb_parc(3) ;
      DocInfo.pOutputFile = NULL ;
      DocInfo.pDatatype = "RAW" ;
      if ( StartDocPrinter(hPrinter,1,(char *) &DocInfo) != 0 )
      {
        if ( StartPagePrinter(hPrinter) != 0 )
        {

Imprimir numa impressora matricial

Enviado: 15 Nov 2016 16:28
por Tomaz Edson Linhares
Não consegui enviar o restante do código, estou mandando anexo.

Imprimir numa impressora matricial

Enviado: 16 Nov 2016 10:20
por Pablo César
Oi Tomaz,

Pelo que vejo você está utilizando HMG Extended. Eu uso HMG. Nada em contra mas, eu não criaria tantas funções em C *(também nada em contra) mas desnecessariamente. Pois a ferramenta tanto HMG como HMG Extended já as possui como por exemplo: PRINTFILERAW, WINDEFAULTPRINTER.

Eu preciso sair (estou atrasado). Mas prometo ver esse código exemplo. Se cPrinter (nome da impressora), não estiver correto ie norme exato como está instalado no Windows (como já tinha te falado anteriormente): não vai funcionar nem a pau. Comece, com debugar esse cóidigo. Se não souber debugar, utilize o MsgDebug() que é uma função parecida com MsgInfo() para que não precisa tratar os tipos de variaveis que você quer enxergar. Como neste caso MsgDebug(cPrinter). Verifique também se o seu arquivo de impressão foi realmente criado. Lembrando que o File() do Harbour precisa o path completo, senão as vezes não funciona corretamente.

Imprimir numa impressora matricial

Enviado: 16 Nov 2016 15:34
por Pablo César
Olá Tomaz,

Eu vou direto no assunto e ser breve para ajudar você a resolver o seu problema.

Agora que eu li com mais atenção, percebí que você quer imprimir numa matricial de bobina Bematech.

Meu conselho, esqueça toda a impressão modo gráfico, porque se o driver instalado não corresponder não irá imprimir.

Se essa impressora estiver conectada em uma saída paralela: perfeito. Porque essas impressorinhas são para imprimir em modo TEXTO.

1. Crie o seu arquivo texto. Pelo que pude ver você está utilizando o padrão log name files. Não é padrão 8x2 (8 caracteres como nome do arquivo e 3 a extensão. Já que você utiliza o SET ALTERNATE para criar arquivos (use um nome mais simples).

2. Na composição desse arquivo você disse que imprimiu direto sem varrer os registros do DBF. Você já se perguntou se a sua "busca" com LOCATE não tenha atendido a sua condição ?
Você usou LOCATE e logo while .not. eof(). Você até poderá encontrar os dados mais irá continuar até o final do DBF que pode ser uma continuação bem longa e sem necessidade, pois os outros registros talvez você não queira imprimir. Faça primeiramente o seu relatório em arquivo texto. Não delete o arquivo ainda. Edite e veja se os resultados são os esperados.
Porque eu não consigo testar sem os DBFs, apesar que você indicou a estrutura. Mas na prática pra mim aqui fica dificil. Eis a dica de fazer um teste simple para matar as suas dúvidas aqui no fórum.

Na minha opinião você deve procurar os registros, até pode ser com LOCATE, isso se o tamanho do DBF não for muito grande. Aí e próximo comando após o LOCATE é IF FOUND() e o DO WHILE precisa ter uma composição melhor como por exemplo:

nOrcar:=Val(VOrcar) // já trazer a variavel numérica. Porquê teria que ser do tipo caracter ?
DO WHILE nORCAR = vORCAR

3. Se for uma impressora conectada na paralela que suponho que seja, após você ter o arquivo texto de impressão aprovado e disponível.
Coloque:

Copy File("TESTFILE.txt") To ("LPT1") // quando for impressora local

ou

Copy File("TESTFILE.txt") To ("\\<nome_computador>\<nome_do_compartilhamento_da_impressora>") // quando for em outro terminal que a impressora não esteja conectada. Mas lembre em rede ela precisa ser compartilhada.

A compisição do arquivo de impressão pode conter:
Chr(15) - Condensado
Chr(18) - Tamanho normal 10

Não use EJECT nem Chr(12) em impressoras de bobinas, ok ?

Se o passo 3 que indiquei não te funciona. Abra a linha de comando, se posicione na pasta onde está o seu aquivo de impressão (CD\nome_da_pasta) e digite:

COPY TESTFILE.txt LPT1

Se imprimiu é porque está habilitada a paralela. Então na sua aplicação deverá funcionar sim.