En mi ya larga experiencia usando xailer, siempre he tenido dos espinitas clavadas que se me habían resistido especialmente:
La integración de controles ActiveX en mis programas y la posibilidad de visualizar limpiamente archivos pdf dentro de un formulario sin tener que recurrir a trucos con el explorer que se empeña en que me aparezcan las barras de herramientas de acrobat cada vez que intento visualizar un documento.
Pues bien, hoy vamos a matar dos pájaros de un tiro y ver cómo hacer ambas cosas.
Imaginaros mi sorpresa al ver que además disponía de un control activex para acceder a esa maravilla. Total, que no me pude resistir, y aquí está el resultado.
En el
área de descargas de xailer, en la sección de ejemplos, tenéis el instalable del ejemplo que vamos a ver, así como todos los fuentes necesarios para poder crear vosotros mismos el ejecutable.
Os recomiendo que os lo instaléis antes de seguir leyendo, ya que así os registrará el fichero ocx en vuestro sistema y os permitirá seguir los ejemplos paso a paso.
Lo primero que vamos a hacer será crear un sencillo formulario en el que vamos a situar a la izquierda del todo un Listbox para mostrar los ficheros que queremos visualizar y un Bevel a la derecha, que será donde se mostrará el contenido del fichero seleccionado.
Justo encima del bevel pondremos dos controles más: un BtnBmp para poder imprimir lo que estamos viendo, y un Combobox que nos permitirá seleccionar la forma de visualizar nuestro documento
Algo así:
Una vez tengamos el formulario creado, nos vamos al menú componentes de xailer y seleccionamos importar activex
Veremos como nos aparece una ventana que se va llenando con todos los controles activex que están disponibles en nuestro sistema.
De todos ellos tenemos que seleccionar el que dice oixctrl class, que es el correspondiente al control activex de Oracle Outside In technology.
Como os decía, lo seleccionamos y pulsamos el botón crear clase.
Veremos como xailer se pone a trabajar y nos crea el solito el fichero prg necesario para poder interactuar con el control indicado.
Cuando termine, veremos en nuestro gestor de proyectos un nuevo prg llamado oixctrl.prg que contiene todas las propiedades, métodos y eventos necesarios para poder trabajar con el nuevo control.
Ya sólo nos queda poner un poco de nuestra parte y decirle al programa qué hacer con las nuevas características recien estrenadas.
Para empezar, vamos a crear dos datas nuevas a nuestro formulario
Data oView
Data cDir INIT '.samples'
oView: el objeto que contendrá el control ocx
cDir: el directorio donde están los ficheros de ejemplo que vamos a mostrar.
Es importante tener muy claro que de momento sólo le hemos dicho al programa que tenemos la intención de usar un nuevo elemento que se llamará oView, pero aún no le hemos dicho que va a contener.
Para ello usaremos el evento OnInitializate del formulario.
METHOD FormInitialize( oSender ) CLASS TForm1
Local aImges,n
WITH OBJECT ::oView := Toixctrl():New( ::oBevel1 )
:nAlign := alCLIENT
:Create()
:ViewFile( .f., ::cDir+"oivwx.pdf" )
END
aImges := Directory( ::cDir )
FOR n := 1 TO Len( aimges )
::oListbox1:addItem( aImges[n,1] )
NEXT
RETURN Nil
Aunque no os lo creáis, las palabras mágicas que van a hacer que podamos mostrar hasta ficheros de autocad dentro de nuestros formularios ya se las hemos dicho y son :.
WITH OBJECT ::oView := Toixctrl():New( ::oBevel1 )
Si nos fijamos en el fichero oixctrl.prg que nos ha creado Xailer vemos que aparece una línea que dice
CLASS Toixctrl FROM TOcx
En ella, Xailer crea una nueva clase llamada Toixctrl «con capacidades ocx», así que lo primero que hemos hecho ha sido decirle al programa que nuestro data oView va a ser
un objecto del tipo Toixctrl y que queremos que «cuelgue» no del formulario principal si no del bevel que hemos creado al empezar (::oBevel1)
Una vez creado, para que sea más bonito, vamos a indicarlo a Xailer que además de colgar de oBevel1, queremos que ocupe todo el espacio posible dentro del bevel (:nAlign := alCLIENT)
Ahora que ya tenemos definidad las características del control, tan sólo nos queda decirle que lo cree llamando al método :create()
Y listo!, a empezar a utilizarlo!!
En oixctrl.prg tenemos todos los métodos, propiedades y eventos que ha «heredado» nuestro nuevo control del ocx original. Eso sí, para saber qué hace cada una de ellas no nos quedará más remedio que recurrir a la documentaciónd del ocx en cuestión.
Vamos a ver las más elementales del ocx que estamos usando.
Para visualizar un fichero utilizaremos el método ViewFile( lFileOpenDlg, cFile)
– lFileOpenDlg es una variable lógica que si la establecemos a .t. nos mostrará una caja de diálogo estándar de apertura de fichero y nos mostrará el fichero seleccionado
– cFile es una variable de tipo texto con el nombre del fichero a visualizar.
En nuestro ejemplo vamos a establecer
:ViewFile( .f., ::cDir+"oivwx.pdf" )
para que nada más crear el control nos muestre en la ventana el manual de instrucciones del mismo.
Bien, pero… ¿dónde se va mostrar?. Pues dentro de oBevel1!, ocupando todo el espacio posible.
Todo lo demás es púramente decorativo,
Leemos todos los ficheros del directorio samples y se los asignamos al listbox
aImges := Directory( ::cDir )
FOR n := 1 TO Len( aimges )
::oListbox1:addItem( aImges[n,1] )
NEXT
Cada vez que cambiamos de línea en el listbox hacemos una nueva llamada a ViewFile con el valor del nuevo fichero a visualizar
METHOD Listbox1Change( oSender, nIndex ) CLASS TForm1
::oCombobox1:nIndex=1
::Combobox1Change( ::oCombobox1, 1 )
::oView:ViewFile( .f., ::cDir+oSender:aItems[nIndex] )
RETURN Nil
En el combobox definiremos cómo se va a visualizar el fichero: a tamaño natural, ajustado en ventana, etc..
Para ello utilizamos las propiedades BMPFitMode, VECFitMode y WPFitMode que nos definen el tipo de visualización para ficheros de imagen, vectoriales y texto
METHOD Combobox1Change( oSender, nIndex, nOldIndex ) CLASS TForm1
IF nIndex > 4
::oView:BMPFitMode := nIndex
IF nIndex > 3
::oView:WPFitMode := nIndex
ENDIF
ENDIF
::oView:VECFitMode := nIndex
RETURN Nil
y por último, en el botón utilizamos el método PrintOI(0,128,0,0)
METHOD BtnBmp1Click( oSender ) CLASS TForm1
::oView:PrintOI(0,128,0,0)
RETURN Nil
De este método sólo nos interesa el primer parámetro, que si es 1 nos muestra la caja de configuración de impresora antes de imprimir.
El resto de los parámetros, mejor dejarlos como están.
Listo, ya sólo tenemos que darle al play y disfrutar de nuestro ejemplo funcionando.
Para terminar, recordaros que para que nuestro ejemplo funcione en otros ordenadores, no basta con copiar el fichero ejecutable, sino que es necesario copiar y registrar el ocx y todos los ficheros accesorios.
Dentro del fichero zip con los fuentes del ejemplo os dejo el script de instalación de
Inno setup, pero esa es otra historia y os la contaré otro día.
Fredy,
Muchísimas gracias por tu estupenda aportación y detallada explicación. Estoy seguro de que va a ser muy útil a muchísimos usuarios.
Un saludo
Fredy,
no es necesario el script de InnoSetup para instalar el OCX, puedes hacerlo desde tu propia aplicación con: DLLRegisterServer( «c:Myapptest.ocx» ).
José,
Perfecto.
¿Hay alguna manera de saber si el ocx está registrado?
Fredy,
Estupendo tu aporte, y además la explicación està magníficamente detallada.
¿de donde se descarga este ocx?
Quedaria saber si su uso es libre…
Gracias
Un Saludo,
Xevi
Fredy,
no estoy seguro. Acabo de mirar la MSDN y quizás esto pueda servir:
IsOcxRegistered( «oicxctrl.oixctrl.1» )
HB_FUNC( ISOCXREGISTERED )
{
CLSID clsid;
HRESULT hr = CLSIDFromProgID( (LPCOLESTR) hb_parc( 1 ), &clsid);
hb_retl( SUCCEEDED( hr ) );
}
La he escrito mirando la documentación y seguramente necesite convertir hb_parc( 1 ) con AnsiToWide().
Xevi,
El enlace de la descarga es:
http://www.oracle.com/technetwork/middleware/content-management/downloads/oit-dl-otn-097435.html
en el apartado que pone: Viewer Technology 8.3.5
Sección: Windows ActiveX (x86-32)
En cuanto a si su uso es libre o no, no estoy seguro. He estado buscando una versión de pago y no la he encontrado. Si alguien sabe buscar mejor que yo que nos aclare la duda.
José,
Como siempre, magistral!
Podemos mejorar el código poniendo, al principo del FormInitialize:
IF !( IsOcxRegistered(«oixctrl.oixctrl.1») )
MsgStop(«Imposible continuar»+ CRLF + ;
«Por favor,reinstale el programa»,»Atención»)
QUIT
ENDIF
y al final del código:
//——————————
#pragma BEGINDUMP
#include «windows.h»
#include «xailer.h»
HB_FUNC( ISOCXREGISTERED )
{
CLSID clsid;
HRESULT hr = CLSIDFromProgID( (LPCOLESTR) AnsiToWide(hb_parc( 1 )), &clsid);
hb_retl( SUCCEEDED( hr ) );
}
#pragma ENDDUMP
//——————————
Este control es un poco más complicado para registrarlo automáticamente, porque hay que insertar unas entradas en el registro de windows y copiar un montón de filtros y dll además del ocx, pero si alguien se anima a hacerlo, puedo publicarlo en el blog cuando quiera 🙂
Fredy,
tienes una pérdida de recursos que hay que corregir: es necesario liberar el puntero devuelto por AnsiToWide() y, de paso, comprobar que se pasa el parámetro para evitar GPFs.