Uma rotina de impressão....

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

alvaro.bernardi
Usuário Nível 1
Usuário Nível 1
Mensagens: 40
Registrado em: 22 Nov 2008 11:02
Localização: Porto Velho

Uma rotina de impressão....

Mensagem por alvaro.bernardi »

Criei as seguintes rotinas de impressão, uma pra seleção da impressora, podendo selecionar também pra arquivo e monitor (que no sistema em clipper já existia) essas duas últimas são outras rotinas que não fazem parte das postadas, estou migrando do clipper, tive alguns contratempos mas agora está tudo bem...

Estou postando para que vocês possam ma ajudar a melhorá-la, pois acho que ainda possui algumas falhas, ou poderia ter mais opções...

Descrição:

Primeiro o usuário seleciona a impressora, se for uma impressora USB, por ex. é chamada a função PrintUSB que irá ler um arquivo gerado pelo sistema num diretório qualquer (C:\TEMP p. ex.), esse arquivo já foi formatado corretamente como se fosse impresso em uma impressora Lx300, com seus caracteres de formatação, etc... isso o programa faz em outras rotinas, quando a função é chamada, ela faz um laço para pegar a maior linha, e decidir se irá imprimir Retrato ou Paisagem, depois em novo laço compara os caracteres de formatação e substitui pelas respectivas oPrinter:setFonte e oPrinter:bold, depois imprime normalmente.
A parte de formatação de fontes ainda (nem sempre) formata legal, mas sempre encontra os chr() da vida dentro do documento.

Aproveitei alguns trechos de código que peguei no forum....

Tive, não sei porque, alguns problemas com nomes de variáveis, mas quando as localizei e troquei seus nomes, rodou legal...

Se alguém puder e se dispuser melhorar o código, agradeço.

Código: Selecionar todos

****************************************************
* Conjunto de funcoes para manipulacao de impressora
****************************************************

function IMPR()
************************************
* Funcao para selecao de impressoras
************************************

   LOCAL vaPrinter, i, vnAch, acPrinter, cRet, cCor,;
	      acPrn, acPrnSel, vcTela
   PUBLIC xPrinter
   cCor := setcolor()

	// Pego o nome da impressora padrao
	acPrinter := GetDefaultPrinter()
	// Pego a lista de todas a impressoras configuradas
	// na maquina
	vaPrinter := GetPrinters()
	// Mantenho a padrao para retorno
   cRet := acPrinter

	// Se nao tem nenhuma, mostra mesagem, mas
	// continua
	If Empty( vaPrinter )
		msgalert("Nenhuma impressora instalada")
   EndIf

	// Preparo os arrays
   vaPrinter := GetPrinters(.t.)
   acPrn := {}
   acPrnSel := {}
   
   // Laco para montar o array com
   // todas as impressoras
   For i:= 1 TO Len(vaPrinter)
      if acPrinter = vaPrinter[i,1]  // Sefor a padrao
         // Coloca um (P) antes do nome
			AADD(acPrn,"(P) "+vaPrinter[i,1]+' em '+vaPrinter[i,2])
      else
         // Armazena as outras
			AADD(acPrn,"    "+vaPrinter[i,1]+' em '+vaPrinter[i,2])
      endif
      // Monta um array secundario
      AADD(acPrnSel,vaPrinter[i,1])
	Next
   
   // Adiciona itens extras aos arrays
   AADD(acPrn,"    "+"(Monitor)")
   AADD(acPrnSel,"Monitor")
   AADD(acPrn,"    "+"(Arquivo)")
   AADD(acPrnSel,"Arquivo")

	// Monta a janela para selecao
	vcTela = savescreen(09, 14, 21, 67)
	setcolor("n/w,w+/g")
   @ 09, 14 clear to 21,67
   @ 09, 14 say " Sele‡Æo de impressora                                " color "w+/r"
   @ 21, 14 say " " +chr(24)+chr(25)+": Movimenta | Enter: Seleciona |  ESC: Cancelar    " color "w+/Gr"
	vnAch = achoice(10,15,20,66,acPrn,,"myFuncao")
	restscreen(09, 14, 21, 67,vcTela)

	// Selecionou ou pressionou ESC
	if lastkey() = 13
		// Se for USB
		if "USB" $ acPrn[vnAch]
		   cRet := "USB"
		else
		// Demais impressoras
         cRet := acPrnSel[vnAch]
      endif
   else
      // Abandonou
      cRet := "0"
   endif

	if ! acPrnSel[vnAch] $ "Monitor|Arquivo"
   	PrintOnLine(acPrnSel[vnAch])
   endif

	// Passa o nome da impressora para uma variavel publica
	// para ser utilizada depois
   xPrinter = acPrnSel[vnAch]
   
   Setcolor(cCor)

   Return(cRet)

*************************************


function myFuncao()
****************************
* Funcao de apoio do achoice
****************************
	local vnRetorno
	do case
	    case lastkey() = 19 .or. lastkey() = 4
	        vnRetorno := 2
	    case lastkey() = 13 .or. lastkey() = 16
	        vnRetorno := 1
	    case lastkey() = 27
	        vnRetorno := 0
	    otherwise
	        vnRetorno := 2
	    endcase
	return(vnRetorno)


*****************************************

Function PrintOnLine(vcPrintOn)
*****************************************
* Funcao para verificar o
* status da impressora
* selecionada, local ou em rede
*****************************************

	local nStatus := PrintStat(vcPrintOn)

	if nStatus > 0
	   MsgAlert("Condicao da impressora: " + IsImpressora(vcPrintOn))
	endif

	return .t.

*****************************************

function IsImpressora( QuePrinter )
*****************************************
* Funcao para retornar a mesnagem de
* status da impressora
*****************************************
	LOCAL nStatus
	nStatus := PrintStat( QuePrinter )
	if     nStatus <        1 ; return "OK"
	elseif nStatus =        1 ; return "Impressora Pausada"
	elseif nStatus =        2 ; return "Impressora com Erro"
	elseif nStatus =        4 ; return "Impressora Deletando"
	elseif nStatus =        8 ; return "Impressora em Modo Bandeja"
	elseif nStatus =       16 ; return "Impressora Sem Papel"
	elseif nStatus =       32 ; return "Impressora em Modo Manual"
	elseif nStatus =       64 ; return "Impressora com Problema no Papel"
	elseif nStatus =      128 ; return "Impressora OffLine"
	elseif nStatus =      256 ; return "Impressora com IO Ativo"
	elseif nStatus =      512 ; return "Impressora Ocupada"
	elseif nStatus =     1024 ; return "Impressora Imprimindo"
	elseif nStatus =     2048 ; return "Impressora Memoria Lotada"
	elseif nStatus =     4096 ; return "Impressora Nao Instalada"
	elseif nStatus =     8192 ; return "Impressora Aguardando"
	elseif nStatus =    16384 ; return "Impressora Processando"
	elseif nStatus =    32768 ; return "Impressora Inicializando"
	elseif nStatus =    65536 ; return "Impressora em Atencao"
	elseif nStatus =   131072 ; return "Impressora Toner Baixo"
	elseif nStatus =   262144 ; return "Impressora Sem Toner"
	elseif nStatus =   524288 ; return "Impressora PAGE_PUNT"
	elseif nStatus =  1048576 ; return "Impressora Intervencao do Usuario"
	elseif nStatus =  2097152 ; return "Impressora Sem Memoria"
	elseif nStatus =  4194304 ; return "Impressora Tampa Aberta"
	elseif nStatus =  8388608 ; return "Impressora Servidor Desconhecido"
	elseif nStatus = 16777217 ; return "Impressora POWER_SAVE"
	endif
   return(nil)

******************************************

Function PrintUSB(DocPrinter)
******************************************
* Funcao para impressao em impressoras USB
*
* Retorna .t. se bem sucedido
*         .f. se falhou
******************************************

	Local mDocPrint, vDocPrint, nA, nLand, nLin := 1, nTamPag, cMsg

	oPrinter := Win32Prn():new( xPrinter )   // Crio a instancia da impressora
	
   // LETTER 1 US  Letter format 8 1/2 x 11 inch
   // LEGAL  5 US  Legal  format 8 1/2 x 14 inch
   // A3     8 DIN A3     format 297 x 420 mm
   // A4     9 DIN A4     format 210 x 297 mm

   // Leio o arquvo gerado do diretorio temp ou outro qualquer
   mDocPrint = MemoRead(DocPrinter)
   
   // Verifica se vai imprimir em Retrato (nLand=.f.)
   // ou Paisagem (nLand=.t.)
   nLand   := .f.
   nTamPag := 62  // 62 Linhas em modo Retrato ou 45 em modo Paisagem
   // Faco um laco para pegar a maior linha
 	for nA := 1 to MLCount(mDocPrint,229)
 	    vDocPrint := rTrim(MemoLine(mDocPrint,229,nA))
 	    if len(vDocPrint) > 116  // Se a linha for maior
 	       nLand   := .t.        // Muda para Paisagem
 	       nTamPag := 45         // (Re)Configura o numero de linhas
 	       exit                  // Mudou, nao precisa continuar
 	    endif
 	next
 	
 	// Mostra mensagem no rodape
   cMsg := iif(nLand,"Imprimindo em modo Paisagem","Imprimindo em modo Retrato")
 	nA := len(cMsg)
 	nA := int((80-nA)/2)
	@ 24, nA say cMsg color "gr+/n"

	oPrinter:landscape := nLand
	oPrinter:formType  := 9   // Papel A4
	oPrinter:copies    := 1   // Numero de copias

	// Cria dispositivo de impressao
	If .not. oPrinter:create()
	   MsgAlert( "Nao foi possivel criar o dispositivo de impressao" )
      return(.f.)
	EndIf

 	// Criar trabalho de impressao
	If .not. oPrinter:startDoc( DocPrinter ) // Encarrega o spooler para comecar com um novo documento
	   MsgAlert( "Nao foi possivel criar o documento" )
      return(.f.)
	EndIf

   // Tabela para oPrinter:bold
   // DONTCARE     0    // THIN       100
   // EXTRALIGHT 200    // LIGHT      300
   // NORMAL     400    // MEDIUM     500
   // SEMIBOLD   600    // BOLD       700
   // EXTRABOLD  800    // HEAVY      900

   oPrinter:setFont("Courier",8) // Fonte Courier
   oPrinter:bold( 200 )
   
   vtTeste = "Entrada"
	// Laco para imprimir linha por linha
	for nA := 1 to MLCount(mDocPrint,229)
		 vDocPrint := rTrim(MemoLine(mDocPrint,229,nA))
   	 // Formata a Fonte de Caracteres da Impressora
       Do Case
           Case chr(14)+chr(15) $ vDocPrint
             // Fonte Courier, tamanho 12, Bold 400
             oPrinter:setFont("Courier",12)
             oPrinter:bold( 400 )
           Case chr(18) $ vDocPrint
              // Fonte Courier, tamanho 10, Bold 200
   			  oPrinter:setFont("Courier",8)
              oPrinter:bold( 200 )
   		  Case chr(20)+chr(15) $ vDocPrint
   		     // Fonte Courier, tamanho 10, Bold 800
              oPrinter:setFont("Courier",12)
              oPrinter:bold( 800 )
   		  Case chr(15) $ vDocPrint
              // Fonte Courier, tamanho 8, Bold 100
   			  oPrinter:setFont("Courier",6)
              oPrinter:bold( 100 )
        EndCase
		  // Remove todo e qualquer caractere especial
		  // menor que 32 ou maior que 125 (asc)
		  vDocPrint := RemoveMarcas(vDocPrint)
		  // Imprime a linha

	     oPrinter:textOut(rTrim(vDocPrint))
	     // Insere uma nova linha
   	  oPrinter:newLine()
   	  
        oPrinter:setFont("Courier",8) // Fonte Courier 8
        oPrinter:bold( 200 )          // 200
   	  // Verifica se chegou no final da pagina
        nLin ++
        if nLin > nTamPag
           nLin := 1
           oPrinter:newPage()
        endif
	next

	// Envia saida para impressora
	oPrinter:endDoc()

	// Encerra a impressao e destroi o objeto
	oPrinter:destroy()
	Return(.t.)

*********************************************

Function RemoveMarcas(mTexto)
*****************************
* Remove caracteres especiais
*
* Retorna uma string sem
* os caracteres especiais
*****************************
	Local vT, vRetornaTexto, vTemp
	vRetornaTexto := ''
	for vT := 1 to len(mTexto)
      vTemp = substr( mTexto, vT, 1 )
      if asc(vTemp) <= 31 .or. asc(vTemp) >= 126
         loop
      endif
      vRetornaTexto := vRetornaTexto + vTemp
	next
	Return(vRetornaTexto)

*********************************************
Obrigado,
Alvaro
Microline Software
Porto Velho-RO
Álvaro de Oliveira Bernardi
Microline Software
Porto Velho - RO
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Re: Uma rotina de impressão....

Mensagem por sygecom »

Esta usando alguma LIB grafica, como Hwgui, minigui, xHgtk ? se tiver, pode colocar a janelinha de impressora do proprio windows.
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
alvaro.bernardi
Usuário Nível 1
Usuário Nível 1
Mensagens: 40
Registrado em: 22 Nov 2008 11:02
Localização: Porto Velho

Re: Uma rotina de impressão....

Mensagem por alvaro.bernardi »

Não, ainda não estou utilizando libs gráficas, que alias está sendo meu calcanhar de aquiles, muito tenho lido sobre elas, como vou migrar para gráfico (próximo passo), não estou conseguindo chegar a um denominador comum sobre qual lib utilizar, baixei a Minigui, porém não consegui compilá-la, tenho que decidir agora por uma lib, mas não sei qual é a melhor, qual possui mais recursos, qual possui mais suporte, qual é mais produtiva, neste ponto, se vocês puderem me ajudar a decidir, eu agradeço, pois a migração para visual é aproxima etapa.
Álvaro de Oliveira Bernardi
Microline Software
Porto Velho - RO
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Re: Uma rotina de impressão....

Mensagem por sygecom »

Alvaro, sobre sua duvida de melhor sua rotina de impressão, acredito que se der uma procurada no forum já foi postado exemplos bons, que talvez posso pegar um pouco de cada e melhorar para vc mesmo a sua rotina de impressão, eu uso um pouco diferente e já postei no forum como uso.

Sobre qual LIB GUI(grafica) usar, vai depender muito dos seus objetivos, e de testes realizados por você mesmo nas LIB's disponiveis.
Por exemplo, tem LIB comeciais, LIB open source, algumas com IDE outras não, umas rodam Windows e Linux outras somente em Windows, umas é possivel usar o codigo atual e aos poucos ir colocando um visual grafico outras isso não é possivel, então vai do gosto de cada um, eu uso a Hwgui e estou muito feliz com ela, se Hoje eu fosse optar por um para iniciar iniciaria direto na xHgtk, que roda 100% em Windows e Linux.
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
Responder