21 de mayo de 2008

Haciendo aplicaciones portables en VFP - Parte 2 de 3

Autor: Sergio Hugo Sanchez

Continuando con lo de la creacion de sistemas portables, como llevo tiempo que utilizo algunos de los controles DBI-Tech, pues si que es un problema. (Malo malo, al no usar VFP puro verdad?). Bueno, ni modo.

Y aqui viene la parte dificil. Determinar si el control esta registrado, registrarlo en su caso y al finalizar desregistrarlo. Asi que he creado una pequena rutina:
*
* CHECKOCX.PRG
* Programa para checar si estan registrados los controles OCX necesarios
* Junio, 22, 2004.
*
*
* Necesitamos tener una variable en alguna parte para saber si ya esta registrado o no…
* MOD: 14,Mayo,2008… Agregamos una funcion para detectar primero si el OCX esta registrado.
*       En caso de no estarlo debemos hacerlo.
*
* Checando si los controles ActiveX necesarios para el sistema estan registrados
*
* Listado con todos los con todos los controles OCX necesarios. 
* Poner en el array tantos OCX como necesite el sistema. Este numero debera ser pasado
* mas adelante para el proceso.
*
* El array necesita 2 dimensiones o columnas, ya que la segunda correspondera al 
* archivo fisico OCX y en donde se encuentra si es que esta en una subcarpeta.
* Ejs.
*  lstOCX(1,1) = "ctdropdate.ctdropdatectrl.2"
*  lstOCX(1,2) = "ctdropdate.ocx"
*   o
*  lstOCX(1,2) = "OCX\ctdropdate.ocx"
*
* Tambien usaremos una variable de parametro para hacer 1 de 3 cosas:
* 1) Check = Checar si el control esta registrado o no y registrarlo en su caso
* 2) RegALL = Registrar el control aunque ya estuviera registrado
* 3) UnRegALL = Desregistrar el control.
* 
* La razon de estas opciones es que para aplicaciones portables necesitaremos desregistrar el control
* para que no quede huella en el sistema Host.
*
PARAMETERS cOpcion
IF PARAMETERS() = 0
 RETURN
ENDIF
DIMENSION lstOCX(2,2)
lstOCX(1,1) = "ctdropdate.ctdropdatectrl.2"
lstOCX(1,2) = "ctdropdate.ocx"
lstOCX(2,1) = "cttoolbar.cttoolbarctrl.3"
lstOCX(2,2) = "cttoolbar.ocx"

* Hacer un ciclo con el ultimo numero que corresponde a la cantidad de OCX necesarios
* No calculamos porque nosotros le damos la cantidad
FOR i = 1 TO 2
 DO CASE
  CASE cOpcion = "Check" 
   WAIT WINDOW "Checando controles"
   lCheck = OcxRegistrado( lstOCX( i, 1 ) ) && Llamamos la funcion que checa si esta registrado o no: (.T./.F.)
   IF lCheck = .F.
    * Si el control necesario no esta registrado en la PC, registremoslo
    * Debemos pasarle a esta funcion el archivo OCX a registrar
    lRegistrado = OCXCmdReg( lstOCX( i, 2) )
    *  ? "Archivo " + lstOCX( i,2) +" Ya NO ESTABA registrado. Pero ahora si lo esta"
   ELSE
    *  ? "Archivo " + lstOCX( i,2)+ " Ya estaba registrado"
   ENDIF 
  CASE cOpcion = "RegALL"
   lRegistrado = OCXCmdReg( lstOCX( i, 2) )
  CASE cOpcion = "UnRegALL" 
   WAIT WINDOW "Desregistrando controles" 
   lRegistrado = OCXCmdUnReg( lstOCX( i, 2) )

 ENDCASE
NEXT
RETURN

* Funcion Como saber si un activex ya fue registrado
* JCVisual. 19/Dic/2007
*
* http://www.portalfox.com/article.php?sid=2543
*
FUNCTION OcxRegistrado(cClase)
    Declare Integer RegOpenKey In Win32API ;
        Integer nHKey, String @cSubKey, Integer @nResult
    Declare Integer RegCloseKey In Win32API ;
        Integer nHKey
    nPos = 0
    lEsta = RegOpenKey(-2147483648, cClase, @nPos) = 0
 
    If lEsta
        RegCloseKey(nPos)
    Endif

    Return lEsta
Endfunc

* Funcion: Registrar y Desregistrar un OCX
* Jorge Mota. 16/Agosto/2002
*
* http://www.portalfox.com/article.php?sid=506
*
FUNCTION OCXRegistrar(cActiveX)
DECLARE INTEGER DLLSelfRegister IN "vb6stkit.DLL” STRING lpDllName
* Debemos de poner una lista de los controles
lcFileOCX = SYS(5) + CURDIR() + cActiveX
*lcFileOCX = "C:\DBITECH\Toolbox6\DBITech\Component Toolbox 6.0\Components\ctlist.ocx”
liRet = DLLSelfRegister( lcFileOCX )
IF liRet = 0
 SelfRegisterDLL = .T.
* MESSAGEBOX( "Registrado OCX” )
ELSE
 SelfRegisterDLL = .F.
 MESSAGEBOX( "Error - No registrado OCX” )
ENDIF
ENDFUNC


* Funcion: Registrar OCX con comando
* 
* JCVisual. 19/Dic/2007
*
* http://www.portalfox.com/article.php?sid=2543
*
FUNCTION OCXCmdReg(cActiveX)
 cRun=”REGSVR32 /s ” + cActiveX
 RUN /N &cRun
ENDFUNC

* Funcion: Des-registrar OCX con comando cuando termine
FUNCTION OCXCmdUnReg(cActiveX)
 cRun=”REGSVR32 /u /s ” + cActiveX
 RUN /N &cRun
ENDFUNC
Como pueden observar he usado una función publicada en PortalFox para checar si el control esta registrado en el sistema. Si no, registrarlo.

Cabe notar que la funcion de Jorge Mota no funciona. Busque en Internet otra sin exito por lo que segui el metodo tradicional de REGSVR32. En la pagina http://support.microsoft.com/kb/146219/es de Microsoft, incluso indican que se puede distribuir este archivo con nuestra aplicacion, asi que lo pondre en mi directorio.

Como nota, aclaro que el programa tiene un listado de mis controles que utilizo en un arreglo bidimensional. En la primer columna esta la referencia al registro que se obtiene de la forma y la propiedad OleClass. La segunda columna corresponde al archivo fisico OCX.

Ahora, desde mi programa principal, antes de iniciar el programa mando llamar la rutina:
*
* Checar si los controles OCX necesarios para el sistema se encuentran
* registrados, en caso contrario deben registrarse. Es util para sistemas portables
* o PCs donde no estan instaladas todas las librerias necesarias.
*
WAIT WINDOW "Checando OCX"
DO CheckOCX WITH "Check"
*_Screen.Visible = .f.
DO FORM tc_consulta
READ EVENTS
* Al terminar no olvidar desregistrar si es portable
WAIT WINDOW "Si es portable todos fuera"
DO CheckOCX WITH "UnRegALL"
Y listo. Ahora a ejecutar el sistema desde un USB Disk. Funcionara? Vamos a ver…
Pues si. Funciona. Con WindowsXP. Compile mi programa, lo pase a mi USB y lo ejecute en una maquina que no tiene nada de activeX y VFP. El programa detecta que los controles no estan registrados y procede a hacerlo. De momento como demo, he dejado unas cuantas lineas visibles y wait windows para ver que estaba haciendo. Despues, el programa se ejecuto sin problemas. Al cerrarlo, desregistro los controles y aqui no paso nada.

Ahora viene otro problema. El registro en Windows Vista. Eso lo veremos en el siguiente tema.

Se aceptan comentarios.

1 comentario :

  1. Sergio:
    La función de Jorge Mota sí funciona. La uso desde WinXP, ahora en Win7 y en Win8... con el mismo vb6stkit.DLL .

    ResponderBorrar

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.