O VFP 9 introduziu uma nova engrenagem de relatórios baseada em listeners (saída assistida por objeto).
Os listeners podem ser customizados de várias formas e há muitas coisas espetaculares que você pode fazer com eles.
Combinando o poder da GDI+ com listeners customizados você pode aumentar bastante a capacidade dos relatórios.
Mostrarei como você pode customizar o Report Listener para criar uma marca d'água em todas as páginas do relatório e como você pode customizar o Report Preview para mudar o texto dos botões da barra de ferramentas da janela de visualização de relatórios e como exibi-la maximizada.
Set Classlib To (Addbs(Home()) + "FFC\_GDIPlus.vcx") Additive
* Cria um objeto Report Listener
Local loReportListener
loReportListener = Newobject("MyReportListener")
With loReportListener
.ListenerType = 1 && Visualizar
* Configura as propriedades da marca d'água: texto, fonte e estilo
.cWatermark = "Watermark demo"
.cFontName = "Verdana"
.nFontStyle = 1 && Negrito
Endwith
* Cria um cursor que será utilizado como fonte de dados do relatório e insere alguns registros
Create Cursor curTest (field1 c(100))
Local i
For i=1 To 640
Insert Into curTest Values (Str(i)+" test, test, test, test, test, test, test, test, test, test, test, test, test")
Endfor
Select curTest
Go Top
* Cria um relatório
Create Report Test From curTest
* Executa o relatório usando a nova engrenagem de relatório (saída assistida por objeto)
Report Form Test Object loReportListener
* Fecha o cursor e exclui o relatório
Use In curTest
Delete File Test.fr?
Return
* Cria uma classe derivada da classe base _ReportListener e adiciona algumas funcionalidades
Define Class MyReportListener As _ReportListener Of Addbs(Home()) + "FFC\_ReportListener.VCX"
* Propriedades internas de uso da classe
Hidden nAngle, oBrush, oColor, oFont, oGDIGraphics, oRect, oStringFormat
Hidden ResourceStatus
nAngle = 0
oBrush = Null
oColor = Null
oFont = Null
oGDIGraphics = Null
oRect = Null
oStringFormat = Null
cResourceStatus = Set("Resource")
* Propriedades públicas
cWatermark = ""
cFontName = ""
nFontStyle = 0
*
Procedure Init
Lparameters cWatermark, cFontName, cFontStyle
Set Resource Off
With This
.cWatermark = Evl(cWatermark,"")
.cFontName = Evl(cFontName,"")
.nFontStyle = Evl(cFontStyle,0)
Endwith
DoDefault()
Endproc
*
Procedure Destroy
Local lcResourceStatus
lcResourceStatus = This.cResourceStatus
Set Resource &lcResourceStatus
DoDefault()
Endproc
*
Procedure LoadReport
DoDefault()
With This
If .ListenerType==1 And Not Vartype(.PreviewContainer)=="O"
.ExtendPreviewContainer()
Endif
Endwith
Endproc
*
Procedure BeforeReport
DoDefault()
With This
If Not Empty(.cWatermark)
.oGDIGraphics = Createobject('GPGraphics')
.SetWatermarkFontSize()
Endif
Endwith
Endproc
*
Procedure AfterBand(nBandObjCode, nFRXRecNo)
If nBandObjCode==7 && Rodapé da página
With This
If Not Empty(.cWatermark)
.AddWatermark()
Endif
Endwith
Endif
DoDefault(nBandObjCode, nFRXRecNo)
Endproc
*
Function SetWatermarkFontSize
With This
.SetoGDIGraphicsHandle()
* Cria uma cor cinza semi transparente
.oColor = Createobject('gpColor',128,128,128,127)
* Cria um pincel sólido com a cor criada acima
.oBrush = Createobject("gpSolidBrush", .oColor)
* Cria uma string de formato
#Define StringAlignmentNear 0
#Define StringAlignmentCenter 1
#Define StringAlignmentFar 2
.oStringFormat = Createobject('gpStringFormat')
With .oStringFormat
.Create()
.Alignment = StringAlignmentCenter
.LineAlignment = StringAlignmentCenter
Endwith
* Cria uma fonte
Local loFont
loFont = Createobject("GpFont")
Local lnFactor, lnMaxWidth
lnFactor = 0.80
lnMaxWidth = (Sqrt((.SharedPageHeight ^ 2) + (.SharedPageWidth ^ 2))) * lnFactor
* Para contornar um bug na função MeasureString da GDI+ e obter o tamanho correto
Local loStringFormat As 'GpStringFormat' Of Home() + 'FFC\_gdiplus.vcx'
loStringFormat = Newobject('GpStringFormat',Home() + 'FFC\_gdiplus.vcx')
loStringFormat.Create()
loStringFormat.GetGenericTypographic()
Local loSize, lnSize, lnCharsFitted, lnLinesFilled, lnPerc
lnSize = 1500
loFont.Create(.cFontName,lnSize,.nFontStyle,2)
lnCharsFitted = 0
lnLinesFilled = 0
loSize = .oGDIGraphics.MeasureStringA(.cWatermark,loFont, ,;
loStringFormat, @lnCharsFitted, @lnLinesFilled)
If Vartype(loSize)=="O"
If loSize.W > lnMaxWidth
lnPerc = loSize.W / lnMaxWidth
lnSize = Int(lnSize / lnPerc)
Endif
Endif
loFont.Create(.cFontName,lnSize,.nFontStyle,2)
.oFont = loFont
* Calcula o ângulo de rotação
.nAngle = Rtod(Atan(.SharedPageHeight / .SharedPageWidth ))
* cria um retângulo com dimensões especiais
.oRect = Createobject("gpRectangle", ;
-.SharedPageWidth/2, -.SharedPageHeight/2, ;
.SharedPageWidth*2, .SharedPageHeight*2)
Endwith
Endfunc
*
Function AddWatermark
With This
.SetoGDIGraphicsHandle()
* Prepara a transformação
.oGDIGraphics.TranslateTransform(.SharedPageWidth/2, ;
.SharedPageHeight/2)
.oGDIGraphics.RotateTransform(-.nAngle)
.oGDIGraphics.TranslateTransform(-.SharedPageWidth/2, ;
-.SharedPageHeight/2)
* Insere o texto da marca d'água
.oGDIGraphics.DrawStringA(.cWatermark, .oFont, .oRect, .oStringFormat, .oBrush)
* Desfaz a rotação
.oGDIGraphics.ResetTransform()
Endwith
Endfunc
*
Function SetoGDIGraphicsHandle
With This
If Not .IsSuccessor
.SharedGDIPlusGraphics = .GDIPlusGraphics
Endif
.oGDIGraphics.SetHandle(.SharedGDIPlusGraphics)
.oGDIGraphics.TextRenderingHint = 3 && AntiAlias
Endwith
Endfunc
*
Function ExtendPreviewContainer
Local loPreviewContainer
loPreviewContainer = Null
Do (_ReportPreview) With loPreviewContainer
loPreviewContainer.SetExtensionHandler(Newobject("MyExtensionHandler"))
This.PreviewContainer = loPreviewContainer
Endfunc
Enddefine
* Cria uma classe que extende o Report Preview
Define Class MyExtensionHandler As Custom
*
Procedure Show(iStyle)
With This.PreviewForm
With .Toolbar
* Traduz os botões da barra de ferramentas para o português
.cboZoom.ToolTipText = "Zoom"
.cmdClose.ToolTipText = "Fechar a visualização"
.cmdGoToPage.ToolTipText = "Ir para a página"
.cmdPrint.ToolTipText = "Imprimir"
With .cntNext
.cmdBottom.ToolTipText = "Última página"
.cmdForward.ToolTipText = "Próxima página"
Endwith
With .cntPrev
.cmdBack.ToolTipText = "Página anterior"
.cmdTop.ToolTipText = "Primeira página"
Endwith
With .opgPageCount
.opt1.ToolTipText = "Uma página"
.opt2.ToolTipText = "Duas páginas"
.opt3.ToolTipText = "Quatro páginas"
Endwith
*
Endwith
.WindowState = 2 && Maximiza a janela de visualização de relatórios
Endwith
DoDefault(iStyle)
Endproc
*
Enddefine
Para saber mais sobre a nova engrenagem de relatórios do VFP, eu recomendo:
- ler os tópicos do help do VFP 9: Understanding Visual FoxPro Object-Assisted Reporting e Using GDI+ in Reports;
- visitar o site VFPX e procurar pela classe GDIPlusX que extende a capacidade da GDI+;
- visitar o blog do César Chalom. Ele faz parte da equipe do VFPX que trabalha no projeto da classe GDIPlusX. No blog existem bons exemplos de utilização da GDI+.
Mais uma vez, obrigado ao César Chalom por desenvolver o código fonte da marca d'água. Parabéns pelo seu grande trabalho!