Archivo

Entradas Etiquetadas ‘DLL’

Controlador de Previsualización (PreviewHandler) para imágenes (v.1.0)

lunes, 10 de junio de 2024 3 comentarios
Share Button

ShellPreviewImagesFiles es un controlador de vista previa (PreviewHandler) para las últimas versiones de Windows que admite los tipos de imágenes más habituales actualmente.

Esta herramienta está basada en la serie de entradas que puedes encontrar en este mismo blog sobre la creación de Previews Handler en Delphi.

Los sistemas Windows traen por defecto algunas previsualizaciones incluidas, pero no todos los ficheros de tipos habituales traen una previsualización «de fábrica». Esto pasa con algunos ficheros de imágenes. Esta extensión permite ver previsualizaciones de las siguientes imágenes en el panel de Vista Previa del Explorador de Windows.

Permite trabajar con los siguientes formatos/extensiones:

Extensiones Descripción
.bmp Imagenes de mapas de bits
.jpg, .jpeg Imágenes jpg (Joint Photographic Experts Group)
.png Portable Network Graphics
.gif Graphics Interchange Format
.ico Ficheros de iconos
.wmf, .emf Windows metafiles y Enhanced Windows Metafiles
.tif, .tiff Tagged Image File Format
.svg Gráficos vectoriales (Scalable Vector Graphics)

Para algunas imágenes hacemos un tratamiento especial.

En el caso de las SVG, dado que son imágenes vectoriales que internamente se almacenan como archivos de texto (XML), la previsualización nos permite verlas como imagen (opción por defecto y más habitual), pero si es necesario también como texto.

Debajo se ve una imagen con las 2 previsualizaciones disponibles para un fichero,

En el caso de los ficheros de iconos ICO, que pueden almacenar varias imágenes en diferentes resoluciones, también reciben un comportamiento especial. Se muestra en la previsualización las diferentes imágenes incluida en el fichero de icono, junto con las dimensiones de cada uno de ellos.

Debajo de este texto se ve una imagen de la previsualización de un fichero de icono que incluye dentro varias imágenes de diferentes dimensiones.

Por ahora no necesita librerías de terceros y está totalmente programada utilizando Delphi.

Es de uso libre.

Os aquí el instalador para descarga. Por defecto la instalación se realiza sobre el directorio:
«c:\Program Files (x86)\ShellPreviewExtFiles\»

Download instalador (Windows 32b)

Cualquier duda, comentarios, error,… me lo podéis dejar en los comentarios.

 

 

IV – Instalador para PreviewHandler de imágenes/texto (Inno Setup)

lunes, 3 de junio de 2024 Sin comentarios
Share Button

Continuando con las entradas anteriores, en esta última vamos a crear una extensión para visualizar los tipos de imágenes más habituales y usados en Windows. Además vamos a «redistribuir»  un poco nuestro esqueleto inicial para reorganizar las clases (tal y como comentamos en entradas anteriores); Y finalmente vamos a crear un instalador para poder ofrecer esta extensión de una forma más profesional.

Os adjunto los links de todas las entradas de esta serie, como he hecho en las anteriores:

  1. Crear una Previsualización de ficheros en Windows
  2. «Registros» de una DLL de previsualización
  3. Generando previsualización funcional (PreviewHandler)
  4. Instalador para PreviewHandler de imágenes/texto (Inno Setup)

.

INTRODUCCION

Con todo los visto hasta ahora en las entradas anteriores, vamos a crear una DLL para imágenes de diferentes formatos, modificando un poco el esqueleto del proyecto que teníamos hasta ahora.

Vamos a tratar las extensiones más comunes con las que trabajamos:  bmp, jpg, jpeg, png, gif, ico, wmf, emf, tif, tiff

Además vamos a generar un instalador con Inno Setup que instale (y desinstale cuando sea necesario) nuestra DLL de previsualización. Inno Setup, para los que no lo conozcáis, es un generador de instalaciones para Windows muy potente y totalmente gratuito. En otras ocasiones ya he hablado de él, y a día de hoy es un estándar en generar programas de instalación.

Además de ser sencillo de utilizar, hay multitud de scripts predefinidos y de ejemplo por la web, que podéis utilizar, modificar y adaptar a vuestras necesidades. Para lo que necesitamos nosotros veréis que es sumamente sencillo y fácil.

Leer más…

II – «Registros» de una DLL de previsualización (PreviewHandler)

miércoles, 22 de mayo de 2024 Sin comentarios
Share Button

INTRODUCCIÓN

Continuando el tema de «Crear una Previsualización de ficheros en Windows», vamos a seguir completando esta serie, haciendo referencia al tema del registro que nos quedó pendiente en la anterior entrada.
Os adjunto los links de todas las entradas de esta serie, que iré completando a medida que avance:

  1. Crear una Previsualización de ficheros en Windows
  2. «Registros» de una DLL de previsualización
  3. Generando previsualización funcional (PreviewHandler)
  4. Instalador para PreviewHandler de imágenes/texto (Inno Setup)

 

Hablo de «registros» en el título de esta entrada, porque vamos a abordar por un lado, los cambios en el «registro de Windows» que debemos realizar para que nuestra DLL quede «inscrita» en el sistema (con esto le decimos al sistema, que cuando quiera visualizar un determinado fichero de extensión AAA, debe cargar nuestra DLL para mostrar ese contenido). Y en segundo lugar, veremos cómo registrar nuestra DLL en Windows a través de regsrv32.

.

CLAVES DE REGISTRO

Cuando registramos nuestra DLL (regsvr32) necesitamos modificar algunos valores en el registro de Windows para indicar al sistema que tiene una DLL disponible para utilizar cuando se le solicite una vista previa de un archivo con extensión AAA.
Para ello tenemos disponible esta documentación que explica los diferentes cambios a crear/borrar cuando realizamos el register/unregister.

https://learn.microsoft.com/en-us/windows/win32/shell/how-to-register-a-preview-handler
https://learn.microsoft.com/es-es/windows/win32/shell/how-to-register-a-preview-handler

Lo primero que debemos tener en cuenta, es que si nuestro controlador de Vista previa (de 32 bits) se está registrando en un sistema de 64 bits, tal y como se describe aquí, debe usar un IdApp diferente;

Leer más…

Categories: Código, DLL, Ejemplos, Windows Tags: , , ,

I – Creando una DLL de previsualización de ficheros (Preview Handler)

miércoles, 22 de mayo de 2024 Sin comentarios
Share Button

La idea de esta serie de entradas es ver todos los pasos necesarios para generar desde cero una DLL de Previsualización para Windows, de un determinado tipo de ficheros.

Antes de continuar os adjunto los links de las entradas de esta serie, que iré ampliando a medida que las vaya publicando:

  1. Crear una Previsualización de ficheros en Windows
  2. «Registros» de una DLL de previsualización
  3. Generando previsualización funcional (PreviewHandler)
  4. Instalador para PreviewHandler de imágenes/texto (Inno Setup)

¿A qué me refiero con eso de «PreviewHandler»?

Si abrimos el Explorador de Windows, para algunos tipos de ficheros que existen en nuestro equipo, el sistema operativo dispone de vista una previa desde el propio explorador. Nos permite ver el contenido del fichero de forma rápida, sin necesidad de abrir el programa asociado.
Al seleccionar una imagen o un fichero .INI en el explorador de Windows, si tenemos la previsualización activada, veremos directamente una «vista previa» de ese archivo sin necesidad de abrir otro programa.

Si por el contrario, el fichero no tiene vista previa definida, veremos un mensaje de Windows indicándolo. Algo similar a esto (varía dependiendo de la versión):

Leer más…

DLL’s, BPL’s, Carga dinámica/Estática y «Packages en Runtime»

lunes, 19 de julio de 2010 9 comentarios
Share Button

Cuando uno empieza a conocer Delphi (al menos a mi me pasó) y dependiendo de si «viene» de otros lenguajes, se hace un lío con las diferentes formas en que podemos generar un programa; Con la forma de trabajar con packages o sin packages, con los ficheros a distribuir,… Y le empiezan a surgir diferentes preguntas:

¿Porqué mi ejecutabe ocupa tanto si sólo he puesto un botón?
¿Qué son los packages de liberías? ¿Los debo copiar con mi aplicación?
¿Porque si marco «Build with runtime packages» mi programa ocupa tampoco?
¿Porque si marco «Build with runtime packages» mi programa no funciona en otras máquinas?
¿Como trabajar con DLL’s? ¿Y con BPL’s? ¿Cual es mejor? ¿Es lo mismo?

Y muchas otras relacionadas con los elementos que aparecen en el título de esta entrada.

Mi idea en este caso es, intentar aclarar algunos de estos términos y las diferentes formas de generar un programa desde Delphi (utilizando DLL’s y BPL’s -packages-). Otra cosa, es que lo consiga…  ;-D

Antes de comenzar, debemos aclarar algunos términos o elementos que debemos tener claros antes de continuar.

——————————————————————————————————————————————-

BWRP = «Build with runtime packages»

Esta opción se encuentra en las «Opciones de proyecto/Packages» y con ella conseguimos:

  • ACTIVADA: El programa no incluye las librerías (normalmente la VCL y componentes de terceros) en el EXE; El ejecutable es más pequeño, pero necesita de los packages (BPL’s) de la VCL; Al distribuir la aplicación se deben copiar también esos ficheros (los necesarios -NOTA1-) y los packages que hayamos creado nosotros.
  • DESACTIVADA: El programa incluye en el EXE los packages de librerías y componentes de terceros. En un único fichero va todo incluído. El EXE tiene mayor tamaño (lógico porque todo va incluído).

NOTA1: Se puede saber qué librerías (DLL’s o BPL’s) necesita un ejecutable utilizando herramientas como «Dependency Walker», GExperts o CnWizards.

DLL = «Dinamic Link Libray / Librería de enlace dinámico»

Son ficheros con código ejecutable, que se utilizan en sistemas Windows, y que forma parte de otras aplicaciones o del propieo sistema operativo. Permiten hacer que los programas sean más pequeños y que el código que contienen pueda ser usado por diferentes aplicaciones.

BPL = «Borland Package Library»

En pocas palabras podemos decir que una BPL es una DLL sólo para Delphi. Las BPL’s son más potentes que las DLL’s. Permiten almacenar más información fFunciones, procedimientos, Units, pero también Clases, Objetos y Componentes). La mayor potencia de estos ficheros se «paga» con la exclusividad de poderlos utilizar únicamente en Delphi.

Carga estática de librerías

Tanto para DLL’s como para BPL’s, cuando hablamos de carga estática, nos referimos a que al ejecutarse el programa, se carga automáticamente esa librería. Aunque en ese momento no se vaya a utilizar el código que hay dentro de la librerías, esta se carga al iniciar. Si la librerías no existe en disco el programa falla durante la carga y no es posible ejecutarlo.

Carga dinámica de librerías

La carga dinámica de packages, tiene como contrapartida que es más compleja (programáticamente) que la carga estática. La carga se debe hacer de forma expresa por el programador cuando se dese. Esto significa que sólo se cargará esa librería cuando se necesite. El programa puede funcionar aunque no esté (el programador deberá comprobarlo antes de cargarla). Este sistema hace que este tipo de carga sea ideal para sistemas con plugins/Addins.

——————————————————————————————————————————————-

Una vez revisado esto, voy a intentar explicar las diferencias al crear un proyecto, segun si utilizamos DLL’s o BPL’s y carga estática/dinámica.

EXE + DLL con Carga estática(El EXE puede ser con o sin BWRP)

Tal y como hemos dicho, la DLL debe existir en disco cuando se ejecuta la aplicación, de otra forma esta no funcionaría y fallaría al arrancar.
Hay que definir dónde se encuentra la DLL (en el que la carga -el EXE-)

function Sumar(x,y:integer):Integer; stdcall; external 'sumas.dll';

Y con eso ya se puede hacer la llamada:

Res := Sumar(4,5);

EXE + DLL con Carga dinámica(El EXE puede ser con o sin BWRP)

En este caso el programa puede funcionar aunque la DLL no exista; En el momento de intentar cargarla se debe comprobar si está o no en disco. Se puede cargar cuando se necesita y descargarla cuando ya no es útil. La carga es un poco más compleja que el caso anterior.

Se utiliza LoadLibrary para cargar la DLL en el momento en que se necesita:

H := LoadLibrary('SUMAS.DLL');

Para acceder a las funciones de la DLL se usa GetProcAddress:

@sum := GetProcAddress(H, 'Sumar2');

En el programa que hace la llamada (el EXE) debe estar predefinido el tipo de la función a la que vamos a realizar la llamada:

Sum: function(x,y:Integer):integer; stdcall;

EXE + BPL con Carga estática(El EXE puede ser con o sin BWRP)

En este caso no hace falta definir nada referente a la función que se encuentra en el package, simplemente hacer referencia a ella en diseño (añadiendo la unit al USES).

Si el programa principal (EXE) se compila con «BRWP Desactivado» todo va dentro del EXE (componentes de terceros y código de la VCL); Si se compila con «BWRP activado» la VCL y los packages de terceros van aparte; Estos packages se deberán distribuir junto al EXE.

Utilizando carga estática es obligatorio que exista el package en disco y que esté accesible al arrancar la aplicación; Si la BPL no existe el programa no puede funcionar.

EXE + BPL con Carga dinámica + RTTI(El EXE debe ser con BWRP)

Es el caso más potente que tenemos. Cargar el package (hemos dicho que las BPL’s son más potentes que las DLL’s) de forma dinámica. Para ello hacemos uso de RTTI (Runtime Type Information) que es lo que le da la potencia extra a las BPL’s. Es obligatorio en este caso que «BWRP esté activado»; Es decir, obligatoriamente debemos distribuir nuestra aplicación con packages.

Los packages se cargan de forma dinámica con LoadPackage (de forma similar a cómo se hace con LoadLibrary):

H := LoadPackage('RESTAS.BPL');

Podemos acceder a las funciones de la misma forma que lo hacemos con las DLL’s, utilizando GetProcAddress:

@resta := GetProcAddress(H, 'Resta');

Podemos utilizar RTTI para acceder a classes que previamente se han registrado (con RegisterClass) utilizando funciones de RTTI como GetClass:

AClass := GetClass('TFormMain');

Y podemos acceder a métodos de las clases utilizando también RTTI, utilizando MethodAddress:

// Acceder al método
Routine.Data := Pointer((F as FormClass));
// Ejecutar al código
Routine.Code := (F as FormClass).MethodAddress('ExecForm');

No es necesario definir nada en el programa principal, puesto que podemos obtener todo la información de las clases definidas en el package utilizando RTTI.

Quedaría una última combinación, posible, pero un poco extraña, que sería EXE sin «runtime packages» y con carga dinámica. Y digo que es un poco rara, porque es un poco contracorriente. Utilizar BPL’s tiene la ventaja que le confiere utilizar RTTI, sin ella los BPL’s pasan a ser DLL’s normales. Esta opción haría justo eso, utilizar BPL’s, pero sin RTTI.

EXE + BPL con Carga dinámica sin RTTI(El EXE sin BWRP)

Esta opción (un poco rara) sería la de utilizar una aplicación con «BRWP Desactivado» (es decir TODO en un único EXE) y cargar en él package de forma dinámica. Esto es posible, pero en este caso perdemos la opción de utilizar RTTI; El EXE (fichero único) podría funcionar sin que exista la BPL que vamos a cargar. Al no poder utilizar RTTI, las «mejoras» que tienen las BPL’s se pierden y pasan a usarse como DLL’s.

Se pueden cargar las BPL’s de forma dinámica con LoadPackage:

H := LoadPackage('RESTAS.BPL');

Y para acceder a las funciones usamos GetProcAddress (como en las DLL’s):

@resta := GetProcAddress(H, 'Resta');

Por supuesto si intentamos acceder a información de clases (GetClass) el programa falla.
Más o menos hasta aquí las diferentes opciones de compilar el proyecto y algunas referencias a cómo hacer las llamadas y las definiciones.

Todo ello está implementado en los ejemplos que ajunto al final de esta entrada. Hay un grupo de proyectos (compilado con Delphi 6) que incluye los siguientes ficheros:

  • sumas.dpr: Proyecto que genera un DLL con una función de suma
  • Call_suma_estat.dpr: Proyecto para llamar a una DLL con carga estática.
  • Call_suma_dinam.dpr: Proyecto para llamar a una DLL con carga dinámica.
  • restas.dpk: Proyecto para generar una BPL con una función de resta y un formulario.
  • Call_resta_estat.dpr: Proyecto para llamar a la BPL con carga estática.
  • Call_suma_dinam.dpr: Proyecto para llamar a la BPL con carga dinámica (uso de RTTI y proyecto compilado con Runtime Packages).
  • Call_resta_dinam_sin_pack.dpr: Proyecto para llamar a la BPL con carga dinámica, pero sin compilación con packages (sin uso de RTTI).

El Grupo de proyectos completo se puede descargar desde aquí.

[Link descarga código fuente]

AÑADIDO: El otro día me dejé sin poner algunas referencias que tengo sobre el tama y que me parecen interesante, así que ahí van:

Categories: OOP Tags: , ,

PING «threaded» usando ICMP.DLL

miércoles, 16 de diciembre de 2009 4 comentarios
Share Button

Hay muchas formas de implementar un PING. Una de ellas es utilizando la librería ICMP.DLL (Internet Control Message Protocol).
Basándome en la Unit Ping.pas que utiliza esta librería extraída de delphi-Central, he creado un ejemplo que la utiliza combinando las llamadas con Threads.

La unit Ping.pas se puede descargar desde la página anterior o desde aquí (raw_ping). El ejemplo crea una clase llamada TPingThread con la siguiente estructura:

  TPingThread = class(TThread)
  private
    mmResult:TMemo;
  protected
    procedure Execute; override;
    procedure UpdateResult;
  public
    PingResult:TPingResult;
    Ready:Boolean;
    constructor Create(Ping:TPingResult);
  end;

En este caso hemos añadido un TMemo para poder usarlo en la sincronización y mostrar los resultados, aunque no seía necesario (sólo para mostrarlos en este ejemplo), ya que los resultados realmente se alamacenan en la variable PingResult.

El thread utiliza el procedimiento IcmpSendEcho para realiza el Ping.

Se puede descargar el código fuente y los binarios compilados con Delphi 6:
<CODIGO FUENTE>
<BINARIO>

Se puede comparar este con un ejemplo similar realizado sin threads.
<DESCARGAR BINARIO>

Categories: Delphi, Ejemplos Tags: , ,