Ver Mensaje Individual
  #9  
Antiguo 10-06-2011
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 835
Reputación: 24
gatosoft Va camino a la fama
No se si ponerme a llorar o saltar de alegria.... Al, esto del Objeto superglobal era lo que estaba buscando hace años...!!! mi mundo de posibilidades acaba de cambiar... voy a tirar todos mis programas a la basura para re-escribirlos basados en tu implmentación del objeto superglobal... (es en serio)

pero bueno, para efectos de ilustración de lo que estoy diciendo les muestro como resolví el problema que nuestro amigo Spk2000ar plantea al inicio del hilo, y entenderán por que la solución de Al me hace sentir que en todos estos años no he aprendido nada de Delphi...


Hace mucho tuve la misma necesidad que Spk2000ar... entonces cree una clase llamada TSesionAPPL... para mi empresa, por lo cual no podré compartir todo el codigo pero si las ideas básicas...


1. Escogí la estrategia de enviar mensajes entre aplicaciones, para lo cual me documenté un poco sobre las funciones:

SendMessage
AllocateHWnd
DeallocateHWnd

2. Habia un módulo principal (MAIN) que funcionaba como barra de menú, que llamaba a los módulos operativos... y le pasaba como parametro un archivo que generaba el MAIN, el cual, despues de ser leido por el módulo que fue llamado se borraba... (No sabia de los archivos mapeados en memoria sino hast hace poco, asi que no me juzguen tan duro)

3. para la implementación: Cree unos códigos de mensaje
Código Delphi [-]
MsgBOSE_PING = 998;
MsgBOSE_PONG = 999;
MsgBOSE_ENTRA_APPL = 1000;
MsgBOSE_SALE_APPL = 1001;
MsgBOSE_TERMINAR = 1002;

(BOSE es una abreviatura de un módulo)

4. La función que procesa los mensjaes la definí como:

Código Delphi [-]
Procedure TSesionAPPL.WndProc(var Message: TMessage);
var intIndice : Integer;
begin

///////////////////////////////////////////////
// DESCRIPCION:
// Procesa los mensajes entre aplicaciones
///////////////////////////////////////////////

  if Message.Msg = WM_USER+100 then
  begin
      Case Message.LParam of
      MsgBOSE_ENTRA_APPL:
         Begin
            if FlstAplicaciones.IndexOf(IntToStr(Message.wParam))=-1 then
               FlstAplicaciones.Add(IntToStr(Message.wParam));
         end;
      MsgBOSE_SALE_APPL:
         Begin
           intIndice := FlstAplicaciones.IndexOf(IntToStr(Message.wParam));
           FlstAplicaciones.Delete(intIndice);
           if assigned(FOnActivarMain) then
              FOnActivarMain(nil);
         end;
      MsgBOSE_PING:
         Begin
             if self.blnPuntoDeEntrada then
                SendMessage(Message.wParam, WM_USER + 100, Self.FhwnMain, MsgBOSE_PONG)
             else
                SendMessage(Message.wParam, WM_USER + 100, Self.FhwnModulo, MsgBOSE_PING);
         end;
      MsgBOSE_PONG:
         Begin
           //OK
         end;
      end; //Case
  end else
      Begin
        if Self.blnPuntoDeEntrada then
           DefWindowProc(FhwnMain, Message.Msg, Message.wParam, Message.lParam)
        else
           DefWindowProc(FhwnModulo, Message.Msg, Message.wParam, Message.lParam);
      end;//if .. else
end;

La anterior función es mas o menos transparante asi que no voy a entrar en detalles sobre ella...

5. al crear el objeto sesion, registraba la función de procesamiento de mensjaes...

Código Delphi [-]
Constructor TSesionAPPL.Create(strRutaINI_p, strArchivoINI_p:string; blnPtoEntrada_p:Boolean=False);
Begin
  inherited Create;

  if blnPuntoDeEntrada then
  begin
    FhwnMain := AllocateHWnd(WndProc);
    FhwnModulo := 0;
  end else //if
     Begin
       FhwnMain := 0;
       FhwnModulo := AllocateHWnd(WndProc);
     end;

end;

//El "punto de entrada" es el módulo principal...

6. El destructor del objeto sesion "des-registraba" el procedimiento de escucha de mensajes..

Código Delphi [-]
Destructor TSesionAPPL.Destroy;
Begin

 if Self.blnPuntoDeEntrada then
    Begin
    //Le informa al Main que va de salida
      DeallocateHWnd(FhwnMain);
    end else
        Begin
        SendMessage(Self.FhwnMain, WM_USER + 100, Self.FhwnModulo, MsgBOSE_SALE_APPL);
        DeallocateHWnd(FhwnModulo);
        end;

 inherited Destroy;
end;

7. El archivo de interambio generado por el Main, le pasaba el Handle al módulo, e inmediatamente le enviaba un mensaje de "ingreso a la aplicación"

Código Delphi [-]
 Self.FhwnMain := StrToInt(ObtenerParametro(strRutaCoockie_p,';',4,'0')); //El Handle del Aplication (MAIN)
      if not blnError then
      Begin
         //Le informa al Main que acaba de entrar a la aplicación
         SendMessage(Self.FhwnMain, WM_USER + 100, Self.FhwnModulo, MsgBOSE_ENTRA_APPL);


8. El mensaje para cerrar forzadamente los módulos era:


Código Delphi [-]
Procedure TSesionAPPL.CerrarModulos;
Var i:Integer;
Begin
  For i:=0 to FlstAplicaciones.Count-1 do
  Begin
    SendMessage(StrToInt(FlstAplicaciones[i]), WM_USER + 100,Self.FhwnMain, MsgBOSE_TERMINAR);
  end;//for i
end;


9. Bueno como dije, no puedo publicar mucho de este codigo, peor la idea era mas o menos esta...

Esto fue hace mucho y precisamente en estos días estaba pensando en redefinir la clase de una manera mas óptima (utilizando archivos mapeados en memoria) para utlizarla en nuevos proyectos, pero como dije, el Objeto superglobal de AL, cambia el panorama....

Muchas gracias AL... y espero haber sido claro en mi explicación anterior, pues como dije, fue solo a manera ilustrativa por si a alguien le sirve...
Responder Con Cita