FoxPress – Octubre 2000

 

Registro Automático de ActiveX

 

Por Paco Simarro. psimarro@interbook.net                      ActiveX (21 K)

 

http://www.fpress.com/

 

 

Cuantas veces nos ha ocurrido que en el momento de instalar nuestro nuevo programa en casa del cliente, o en un nuevo puesto de la red y nos disponernos a mostrarles las maravillas que le hemos preparado, entre las que hemos introducido algún que otro control ActiveX, a la hora de ejecutar el programa nos salta el tan indeseado error que se reproduce a continuación:

 


 

 


          ¿Cómo se soluciona esta situación?. Pués es bién sencillo, y la mayoría de los lectores ya conocen la solución, copiando nuestro archivo OCX sobre el directorio de Windows y después ejecutando:

 

REGSVR32 C:\WINDOWS\SYSTEM32\MIARCHIVO.OCX

 

          Con lo cual el control quedará debidamente registrado y listo para ser empleado por nuestro programa. Pero la sensación inicial que sufre el usuario ante la circunstancia descrita es la de que somos un poco chapuceros.

 

          Después de que esta situación se me repitiera con cierta frecuencia, debido al despiste que me acompaña desde que ví la luz del día por primera vez, me planteé la posibilidad de investigar si sería posible preparar alguna utilidad que me evitara estas situaciones tan sonrojantes.  Y después de un tiempo y de encontrar en la red  de redes las utilidades que necesitaba para ello, me dispuse a integrar esta utilidad en mi programa encargado de lanzar la aplicación.

 

          La utilidad consiste en guardar en una tabla la información de los controles ActiveX que utilizo habitualmente. Y cada vez que arranco el programa recorro la tabla y compruebo si cada uno de los controles está registrado. Y si no es así, pues lo copio al directorio del sistema y después lo registro. De esta forma, me olvido también de incluir en la instalación los componenetes ActiveX, y marcarlos como tales en el proceso de generación de los discos de instalación. Paso a explicar más detalladamente esta cuestión.

 

          En primer lugar en el directorio de mi aplicación tengo un subdirectorio llamado ActiveX, dentro del cual he creado una tabla llamada igualmente ActiveX, con la siguiente estructura:

 

·                     cFileOCX  c(25)

·                     cOleClass  c(40)

 

En el primer campo guardo el nombre del archivo OCX que contiene los controles (Ej. El COMCTL32.OCX), y en el segundo guardo el OleClass, de uno de los controles contenidos en el archivo OCX. El segundo valor podemos verlo si insertamos un control en un formulario, seleccionamos la ventana de propiedades y vemos el valor de la propiedad OleClass (Ej. El caso del treeview: COMCTL.TreeCtrl.1).

 

En el mismo directorio guardo igualmente los archivos OCX que se corresponden con los registros de la tabla mencionada, para copiarlos y registrarlos si el cliente no los tiene aún.

 

El siguiente problema que me encontré era el de cómo comprobar si un control activex estaba o no registrado en el ordenador, y después de bucear durante un buen rato en el registro de Windows me dí cuenta de que por cada control había una entrada con la clave del OleClass en la clave primaria HKEY_CLASSES_ROOT. No tenía más que buscar esa clave en el registro y si no la encontraba es que el control no estaba debidamente registrado.

 

Para trabajar con el registro he usado la clase Registry de Rick Strahl, que es fantástica, y además de dominio público. Me vino de perlas para comprobar si existía la entrada mencionada en el registro. Podeis encontrar esto en registry.prg.

 

Después necesitaba registrar el control y siempre pensé que ejecutar con un RUN el REGSVR32 desde mi programa no era muy elegante. Investigando un poco encontré también un par de funciones de Paul Vlad Tatavu, que me vinieron de perlas. Resulta que cada archivo OCX contiene en sí mismo un par de funciones para registrarse y desregistrarse (DllRegisterServer y DllUnregisterServer), no hay mas que declararlas y utilizarlas para registrar/desregistrar el control. Incluí esas dos funciones como métodos de la clase Registry, aunque la única que se utiliza en el código es RegisterControl.

 

          También utilizo la función oPrg_Disk_CopiaFile, que es una función mía que utilizo para copiar archivos, y la función oPrg_Disk_SystemDir, que es de Luis María Guayan aunque un poco retocada, y la utilizo para localizar el directorio del sistema de Windows, todo ello va incluido en el archivo utilidad.prg.

 

          No queda más que exponer el código que utilizo para recorrer la tabla ActiveX y demás operaciones descritas, que se encuentra en el archivo ActiveX.prg:

 

 

* Ahora vamos con la comprobación de la instalación de los controles ActiveX 

PUBLIC cRutaServ, oRegistry

LOCAL cValorRegistro, laOCXLocal, laOCXServer, cFileLocal, cFileServ

CRutaServ = ‘C:\MIAPP\’

oRegistry=CREATE("Registry")

 

IF FILE(cRutaServ+'ACTIVEX\ACTIVEX.DBF')

      * Está la tabla de los ActiveX a utilizar

      USE (cRutaServ+'ACTIVEX\ACTIVEX.DBF') ALIAS CX

      GO TOP

      SCAN

            cValorRegistro = ALLTRIM(oRegistry.ReadRegistryString(HKEY_CLASSES_ROOT,;

                                    ALLTRIM(Cx.cOleClass),;

                                    ""))

  IF !ISNULL(cValorRegistro)                         

     * El control está registrado

     * Puede darse la circunstancia, de que a pesar de estar registrado el control, el

     * archivo OCX haya sido eliminado del directorio del sistema de Windows.

     * Lo comprobamos por si acaso.

         cFileServ = cRutaServ+'ACTIVEX\'+CX.cFileOCX

         cFileLocal  = oPrg_Disk_SystemDir()+CX.cFileOCX

         IF !FILE(cFileLocal)

            IF oPrg_Disk_CopiaFile(cFileServ,cFileLocal,llMuestraMensajeCopiado)

                  IF oRegistry.RegisterControl(cFileLocal)

                        WAIT WIND 'Registrado control '+CX.cFileOCX NOWAIT

                  ELSE

WAIT WIND 'ATENCION:'+CHR(13)+'No se ha podido registrar el control '+CX.cFileOCX

                  ENDIF

            ENDIF

         ELSE

            * El archivo OCX está en su sitio.

            * Y todo está OK.

         ENDIF    

                ELSE

      * El control no está registrado

      cFileServ = cRutaServ+'ACTIVEX\'+CX.cFileOCX

      cFileLocal  = oPrg_Disk_SystemDir()+CX.cFileOCX

      IF !FILE(cFileLocal)

          IF oPrg_Disk_CopiaFile(cFileServ,cFileLocal,llMuestraMensajeCopiado)

              IF oRegistry.RegisterControl(cFileLocal)

                  WAIT WIND 'Registrado control '+CX.cFileOCX NOWAIT

              ELSE

                  WAIT WIND 'ATENCION:'+CHR(13)+'No se ha podido registrar el control '+CX.cFileOCX

             ENDIF

          ENDIF

      ELSE

         * El OCX ya se encuentra en el directorio del sistema local

         * Podría darse el caso de que se tratara de una versión distinta de la

         * que vamos a utilizar.

         IF ADIR(laOCXLocal,cFileLocal) = 1 AND ADIR(laOCXServer,cFileServ) = 1

            IF laOCXLocal[1,3] # laOCXServer[1,3]

                  IF oPrg_Disk_CopiaFile(cFileServ,cFileLocal,llMuestraMensajeCopiado)

                  ENDIF                              

            ELSE

            ENDIF

         ELSE

         ENDIF         

         *-

         IF oRegistry.RegisterControl(cFileLocal)

            WAIT WIND 'Registrado control '+CX.cFileOCX NOWAIT

         ELSE

            WAIT WIND 'ATENCION:'+CHR(13)+'No se ha podido registrar el control '+CX.cFileOCX

        ENDIF                                  

         *-

       ENDIF     

      ENDIF

  ENDSCAN

ENDIF

 

 

Para probarlo no teneis mas que introducir el valor correcto a la variable cRutaServ, y ejecutar el activex.prg.

En los ficheros del més os adjunto el resto del código necesario y espero que os resulte de utilidad lo que aquí os he expuesto.

 

 

FoxPress – Octubre de 2000

© 2000 FoxPress. All rights reserved