20 de julio de 2018

Evitar que un programa activado desde VFP se cargue más de una vez y visualizarla

La misma función que hemos visto en el caso anterior puede ser usada para evitar que un programa externo se cargue mós de una vez. Un ejemplo sencillo es el de la calculadora de Windows.

Imaginemos que en nuestra aplicación demos la posibilidad de utilizar la calculadora. Pondríamos una línea come esta:

RUN /N CALC.EXE

Pero si esta línea la ejecutamos más de una vez, se cargarás la calcuadora una y otra vez.

* Antes de activar la calculadora:
IF NOT F_ActivaWin("Calculadora")
    * La calculadora no está cargada:
    RUN /N CALC.EXE
ENDIF

* Y ESTA ES LA FUNCION QUE LO HACE TODO:
*-----------------------------
FUNCTION F_ActivaWin(cCaption)
*-----------------------------
LOCAL nHWD
DECLARE INTEGER FindWindow IN WIN32API ;
STRING cNULL, ;
STRING cWinName

DECLARE SetForegroundWindow IN WIN32API ;
INTEGER nHandle

DECLARE SetActiveWindow IN WIN32API ;
INTEGER nHandle

DECLARE ShowWindow IN WIN32API ;
INTEGER nHandle, ;
INTEGER nState

nHWD = FindWindow(0, cCaption)
IF nHWD > 0
    * VENTANA YA ACTIVA
    * LA "LLAMAMOS":
    ShowWindow(nHWD,9)

    * LA PONEMOS ENCIMA
    SetForegroundWindow(nHWD)

    * LA ACTIVAMOS
    SetActiveWindow(nHWD)
    RETURN .T.
ELSE
    * VENTANA NO ACTIVA
    RETURN .F.
ENDIF

Pablo Roca

9 de julio de 2018

Evitar que una aplicación se cargue más de una vez y visualizarla en tal caso

En muchos casos es importante que nuestras aplicaciones puedan estar cargadas una sola vez. Los motivos pueden ser muchos: un programa VFP ocupa muchos recursos del sistema, en algunos casos puedo necesitar abrir los archivos en modo exclusivo, etc.

Utilizando las APIs que Windows pone a disposición, se puede controlar si existe una ventana con un nombre determinado. Si nosotros controlamos esto antes de asignar el título a la ventana de nuestro programa, podemos saber nuestra aplicación ya estaba cargada desde antes.

Lo úmico que necesitamos hacer es lo siguiente:

En nuestras primeras líneas de programa ponemos estas líneas de código:

* Antes de ponerle el título a nuestra ventana:
IF F_ActivaWin("Mi programa")
    * El programa ya estaba activo:
    RETURN && Termina el programa
ENDIF

* Empezamos a definir las características de la ventana principal
* siempre y cuando sea necesario visualizarla.
WITH _SCREEN
    * PREPARO LA VENTANA PRINCIPAL
    * .WIDTH = ...
    * .HEIGHT = ...
    * ETC, ETC
    * 
    *
    .CAPTION = "Mi programa"    && Título de la ventana
    .VISIBLE = .T.
ENDWITH

* Y ESTA ES LA FUNCION QUE LO HACE TODO:
*-----------------------------
FUNCTION F_ActivaWin(cCaption)
*-----------------------------
LOCAL nHWD
DECLARE INTEGER FindWindow IN WIN32API ;
STRING cNULL, ;
STRING cWinName

DECLARE SetForegroundWindow IN WIN32API ;
INTEGER nHandle

DECLARE SetActiveWindow IN WIN32API ;
INTEGER nHandle

DECLARE ShowWindow IN WIN32API ;
INTEGER nHandle, ;
INTEGER nState

nHWD = FindWindow(0, cCaption)
IF nHWD > 0
    * VENTANA YA ACTIVA
    * LA "LLAMAMOS":
    ShowWindow(nHWD,9)

    * LA PONEMOS ENCIMA
    SetForegroundWindow(nHWD)

    * LA ACTIVAMOS
    SetActiveWindow(nHWD)
    RETURN .T.
ELSE
    * VENTANA NO ACTIVA
    RETURN .F.
ENDIF

Pablo Roca