Imprime Gráficos con MSChart
http://www.fpress.com/ Chart.zip
N.R.: (rutina de código de impresión
facilitada por J. Enrique Ramos Menchaca)
Visual FoxPro viene con un control de Gráficos llamado
Microsoft Chart Control (MSChart para los amigos) que permite al ponerlo en un
formulario visualizar gráficos en formato de barras, tarta, etc....
El control
viene con Fox y se puede distribuir con las aplicaciones que se hagan. En abril de 2002 esta revista ya publicó un
artículo sobre las diversas opciones que uno tenía y no se trata ahora de
volver a repetirlo. Unicamente, como aperitivo para centrarse en el tema
repetiré un pequeño código que si lo ejecutas verás que es bastante fácil el uso
de este control que te puede abrir nuevas opciones.
El código
es:
pantalla
= createobject("form")
pantalla.addobject("objeto",
"olecontrol", "MSChart20Lib.MSChart.2")
pantalla.objeto.top
= 0
pantalla.objeto.left
= 0
pantalla.objeto.height
= pantalla.height
pantalla.objeto.width
= pantalla.width
pantalla.objeto.visible
= .t.
pantalla.objeto.chartType
= 1
pantalla.objeto.Title.Text
= "Pedidos"
pantalla.objeto.ColumnCount
= 1
pantalla.visible
= .t.
pantalla.lockscreen
= .t.
lnRow
= 1
WITH
pantalla.objeto.Object
.RowCount = 0
.RowLabelCount = 0
.RowCount = 12
.RowLabelCount = 1
FOR x =1 to 12
.Column = 1
.Row = lnRow
.RowLabel = 0 + x
.Data = 10 + x
lnRow = lnRow+1
ENDFOR
ENDWITH
pantalla.lockscreen
= .f.
Si este
código lo metes en un programa y lo ejecutas empezarás rapidamente a entender
lo que te voy a contar.
El control
es muy versatil pero tiene algunas limitaciones que es bueno conocer antes de empezar
a desarrollar sobre él y en concreto es su incapacidad nativa de ponerse en un
informe (report) y por tanto de imprimir este chart en un Report.
No obstante,
existe un pequeño truco que es lo que vamos a contar en este artículo que
consiste en crear el gráfico en un formulario y copiarlo al clipboard y desde
ahí pasarlo a disco en un bmp y luego ponerlo en un Informe.

Si al leer
lo anterior, te has asustado de la cantidad de cosas que hay que hacer, no te
preocupes pues en el fuente tienes todo hecho: sólo tienes que ‘cortar y pegar’
( ¿quién inventaría la expresión de ‘cortar y pegar’?).
La operación
de generar el Chart ya lo tienes en el código anterior.
El copiar el
Chart al ClipBoard es bastante fácil cuando te das cuenta de que este control
tiene un método llamado EditCopy que lo que hace es copiar lo mostrado por el
objeto al portapapeles. Esto lo hacemos en el botón de comandos en el que he
puesto: Imprime con la dificil instrucción:
THISFORM.Objeto.EditCopy
Quizás la
operación más compleja es copiar del portapapeles a un fichero de tipo *.bmp.
Aquí hay que acudir a una serie de funciones de API que son todas las que he
metido en el programa que adjunto a los fuentes no obstante te trascribo el
trozo de código principal:
#DEFINE CF_BITMAP 2
#DEFINE OBJ_BITMAP 7
DO decl
LOCAL hClipBmp,
lcTargetFile
lcTargetFile =
"C:\clipboard.bmp"
= OpenClipboard (0)
hClipBmp =
GetClipboardData (CF_BITMAP)
= CloseClipboard()
IF hClipBmp = 0 Or
GetObjectType(hClipBmp) <> OBJ_BITMAP
=
MessageB ("No se encontro imagen bitmap en el Portapapeles.",;
64, "Clipboard to BMP")
RETURN .F.
ENDIF
= bitmap2file
(hClipBmp, lcTargetFile)
= DeleteObject
(hClipBmp)
CREATE CURSOR GRAFICO
(GRAFICA G)
APPEND BLANK
APPEND GENERAL GRAFICO.GRAFICA
FROM "c:\clipboard.bmp"
REPORT FORM GRAFICA
preview
USE IN grafico
RETURN
Para los más inquietos les
trascribo la definición de las funciones del API de Win que se usan:
DECLARE INTEGER GetActiveWindow IN user32
DECLARE INTEGER GetClipboardData IN user32
INTEGER uFormat
DECLARE INTEGER OpenClipboard IN user32
INTEGER hwnd
DECLARE INTEGER CloseClipboard IN user32
DECLARE INTEGER DeleteObject IN gdi32
INTEGER hObject
DECLARE INTEGER GetWindowDC IN user32
INTEGER hwnd
DECLARE INTEGER ReleaseDC IN user32
INTEGER hwnd, INTEGER hdc
DECLARE INTEGER CreateCompatibleDC IN
gdi32 INTEGER hdc
DECLARE INTEGER DeleteDC IN gdi32 INTEGER
hdc
DECLARE INTEGER GlobalAlloc IN kernel32
INTEGER wFlags, INTEGER dwBytes
DECLARE INTEGER GlobalFree IN kernel32
INTEGER hMem
DECLARE INTEGER GetObject IN gdi32 AS
GetObjectA;
INTEGER hgdiobj, INTEGER cbBuffer,
STRING @lpvObject
DECLARE INTEGER GetObjectType IN gdi32
INTEGER h
DECLARE RtlZeroMemory IN kernel32 As
ZeroMemory;
INTEGER dest, INTEGER numBytes
DECLARE INTEGER GetDIBits IN gdi32;
INTEGER hdc, INTEGER hbmp, INTEGER
uStartScan,;
INTEGER cScanLines, INTEGER lpvBits,
STRING @lpbi,;
INTEGER uUsage
El fichero resultante del *.bmp lo dejamos con
nombre clipboard.bmp en la unidad C. Posteriormente lo metemos en un cursor y
desde ahí lo invocamos en un informe de esta forma:
CREATE CURSOR GRAFICO
(GRAFICA G)
APPEND BLANK
APPEND GENERAL
GRAFICO.GRAFICA FROM "c:\clipboard.bmp"
REPORT FORM GRAFICA
preview
El resultado
es este:

en
el que se ve el Preview de un informe con nuestro Chart. Para ti te dejo el
hacerlo más bonito y versatil. No obstante, te recomiendo de nuevo que vuelvas
a leer el artículo que se publicó en esta revista en Abril de 2002 pues en los
fuentes tienes muchas de las diversas posibilidades de este control.
FoxPress – Diciembre de 2002
© 2002 FoxPress. All rights reserved