III-Generando una previsualización funcional (PreviewHandler)
Contenido
INTRODUCCIÓN
Continuamos con el tema de las 2 últimas entradas. Visto el esqueleto del proyecto y probado que funciona (la carga, descarga y registro de la DLL) ahora nos queda generar una previsualización funcional. Hasta ahora hemos visto que podemos mostrar un formulario «vacío», ahora nos toca programar realmente la carga del fichero (según su tipo).
Os adjunto los links de todas las entradas de esta serie, que iré completando a medida que avance:
- Crear una Previsualización de ficheros en Windows
- «Registros» de una DLL de previsualización
- Generando previsualización funcional (PreviewHandler)
- Instalador para PreviewHandler de imágenes/texto (Inno Setup)
.
PROGRAMAR REALMENTE LA PREVISUALIZACIÓN
Con la estructura que tenemos del proyecto anterior, lo único que tenemos que hacer ahora es programar la carga y visualización de la información del fichero en el formato que queramos ofrecerla al usuario.
Para este primer ejemplo vamos a empezar con algo sencillo.
Realizaremos una previsualización de ficheros de log (*.LOG) que vamos a tratar como ficheros de texto plano.
El primer cambio que vamos a realizar sobre el esqueleto que ya tenemos de la anterior entrada, es definir nuestra extensión para ficheros *.log. Para ello basta con modificar la extensión que nos encontramos en la unit uConstantes.pas (sin el punto)
// NOTA: sólo cambiando esta constante podemos registrar otra extensión diferente const EXTENSION_FICHERO_SIN_PUNTO = 'log'; |
.
CARGAR INFORMACION A VISUALIZAR
Tal y como comenté en la primera entrada de la serie, la inicialización del Preview se puede hacer con dos métodos diferentes que vienen de dos interfaces diferentes:
- IInitializeWithFile a partir del path del fichero
- IInitializeWithStream a partir del Stream del fichero
Vamos a empezar con el más sencillo, el que utiliza el path del fichero (aunque no es el recomendado por Microsoft).
.
INICIALIZAR CON FICHERO (IInitializeWithFile)
En el procedimiento de Inicialización recibimos el path del fichero para la previsualización, por lo que en este caso la carga es muy sencilla.
Modificamos ligeramente nuestro anterior formulario, para cargar el fichero en un TMemo. Y haremos algunos cambios para modificar la fuente de letra y añadir un botón para controlar el WordWrap del texto.
Si revisamos la documentación, el método Initialize, vemos que el primer parámetro nos devuelve el path del fichero a mostrar; En delphi tendremos esta cabecera:
function IInitializeWithFile_Init(pszFilePath: LPCWSTR; grfMode: DWORD): HRESULT; stdcall; |
El código (y la DLL compilada) y la imagen del formulario queda como se ve a continuación.
En código para visualizar el fichero a partir del path que nos llega del sistema es bastante simple en Delphi:
procedure TBaseShellExt.InternalDoPreview; begin // Chequear la ventana TestPreviewWindows; // Cargar la preview if FileExists(FFilePath) then FormPreview.mmFile.Lines.LoadFromFile(FFilePath); end; |
.
ALGUNAS VARIANTES
Vamos a aplicar algunas «mejoras» sobre nuestro proyecto.
La primera, es simple; Quiero que mi previsualizador no sólo funcione para la extensión LOG, sino también para otras extensiones. Es habitual que utilizando una única DLL podamos previsualizar más de un tipo de fichero (más de una extensión). Pensemos por ejemplo en una DLL para visualizar imágenes que trate diferentes extensiones.
Así que haremos algunos cambios en el registro de mi «Preview Handler» para poder tratar varias extensiones.
Modificamos los procedimientos del registro para que admitan varias extensiones. Y ahora la constante del proyecto la definiremos de esta forma:
// NOTA: sólo cambiando esta constante podemos registrar varias extensiones diferentes const EXTENSIONES_FICHEROS_SEPARADAS = 'log;aaa;ini;cfg'; |
Basta con añadir más extensiones se paradas por ;
Pare que esto funcione, en la siguiente versión del proyecto, se modifican los procedimientos del registro, para que admitan una extensión como parámetro y así poder llamarlos con todas las extensiones que queramos registrar/desregistrar.
.
INICIALIZAR UTILIZANDO STREAMS
Además de la inicialización por fichero (IInitializeWithFile), hemos visto que también existe una inicialización por Stream, que además es la que se recomienda utilizar por defecto por Microsoft en la creación de «Previews Handlers».
Para ello vamos a cambiar la inicialización de nuestra DLL y tendremos que cambiar el procedimiento InternalDoPreview para trabajar con un TStream (IStream).
Os dejo igual que antes el proyecto modificado y la DLL compilada (trabajar con Stream y varias extensiones):
Para este ejemplo, las extensiones que se registran son las siguientes (en la forma en que hemos comentado antes):
// NOTA: sólo cambiando esta constante podemos registrar varias extensiones diferentes const EXTENSIONES_FICHEROS_SEPARADAS = 'log;ini;cfg;inf;key;nfo;txt'; |
Y utilizaremos este procedimiento para obtener el texto a mostrar, a partir del IStream que nos devuelve el método de inicialización.
// Inicilización para stream function IInitializeWithStream_Init(const pstream: IStream; grfMode: DWORD): HRESULT; stdcall; |
function IStreamToString(FStream:IStream; var AString:String):boolean; begin Result := False; var bStream := TOleStream.Create(FStream); var str := TStringStream.Create; try str.LoadFromStream(bStream); AString := str.DataString; Result := True; finally FreeAndNil(str); FreeAndNil(bStream); end; end; |
Os adjunto aquí un video de cómo funciona el registro, previsualización y el «unregister» con esta última versión del proyecto (extensiones log;ini;cfg;inf;key;nfo;txt).
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…