Ver Mensaje Individual
  #6  
Antiguo 13-06-2014
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is online now
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 19.441
Reputación: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Hola a todos.
Gracias por las respuestas. Bueno, están bastante cerca de lo que tenía en mente, así que veo que no voy mal encaminado...


Cita:
Empezado por egostar Ver Mensaje
Yo pensaría en algo sencillito, usaría un socket en cada aplicación para enviarla
Gracias Egostar. Pensaba aun en algo más sencillo que sockets.

Cita:
Empezado por roman Ver Mensaje
Memory mapped files.
Cita:
Empezado por Al González Ver Mensaje
Hola Germán.
Creo que parte de la solución sería con lo que dice Román:
De lo cual por cierto, no sé si recuerdas, se desprende aquel tema de los objetos superglobales.
Esa era una de las opciones. En concreto ya hay otros mensajes en el club que hablan de ellos (Román ya sales en algunos):
http://www.clubdelphi.com/foros/showthread.php?t=22626
http://www.clubdelphi.com/foros/showthread.php?t=24659

Al, no recordaba la unidad mencionada. Ahora que me lo has dicho le he echado un vistazo y como el resto de la librería tiene una pinta fantástica.

Finalmente no es la opción escogida, tal vez por simplicidad, he acabado usando mensajes (WM_COPYDATA).

Cita:
Empezado por dec Ver Mensaje
Yo uso con buenos resultados el componente cyAppInstances de Cindy Components[/url]. Creo que hace lo que necesitas y se trata de un proyecto de código abierto (apoyado por donaciones) así que puedes al menos echar un vistazo y hasta tal vez usarlo directamente.
Gracias David. He oído hablar en varias ocasiones de estos componentes, pero nunca me los había mirado en detalle.
Para el tema de la instancia se puede usar el componente cyAppInstances, como comentas, aunque he preferido utilizar la unit (UIApp) que Román tiene en su web, que hace el mismo trabajo (de esa forma me evito instalar un componente más).

Cuando miraba en enlace, he visto que justo debajo hay otro componente que se llama TCyCommunicate y que va más encaminado a la solución que finalmente he adoptado. La de utilizar Mensajes. En concreto WM_COPYDATA.

También hemos hablado otras veces en el club y hay buenos ejemplos de este método aquí:
http://clubdelphi.com/foros/showthread.php?t=81589
http://clubdelphi.com/foros/showthread.php?t=82410

Además de los hilos comentados había llegado a este enlace que también describe este sistema:
http://voiceofgeek.blogspot.com.es/2...in-delphi.html

Finalmente he añadido a la unit de Román un procedimiento más, que justo después de activar la "instancia previa" de la aplicación que ya está ejecutándose, le envía un mensaje con el parámetro (el path del fichero).
Algo así:

Código Delphi [-]
// Le envía el primer parámetro por mensaje (si existe)
procedure SendMessageParam;
var
  copyDataStruct: TCopyDataStruct;
  str:string;
  receiverHandle: THandle;
  res : integer;
begin
  // Si no hay parámetros, salimos...
  if (ParamCount <= 0) then Exit;

  // rellenar la estructura con los datos
  Str := ParamStr(1);
  copyDataStruct.dwData := 9999;  // Por seguridad para detectar que es el mensaje correcto
  copyDataStruct.cbData := 1 + Length(Str) ;
  copyDataStruct.lpData := PChar(Str);

  // Buscar la aplicación para enviar datos
  receiverHandle := FindWindow(PChar('TFormMainQC'), nil) ;
  if receiverHandle = 0 then begin
    Exit;
  end;

  // DEBUG!!!!
  MessageDlg('Enviando Mensaje ' + IntToStr(receiverHandle), mtInformation, [mbOK], 0);

  // enviar los datos
  res := SendMessage(receiverHandle, WM_COPYDATA, Integer(Application.Handle),
          Integer(@copyDataStruct)) ;
end;

Para completar el código, os pongo el de recepción:

Código Delphi [-]
// procedimiento para recibir mensajes (parametros)
procedure TFormMainQC.WMCopyData(var Msg: TWMCopyData);
var
  str:string;
begin
  // Recuperamos la parte de la cadena
  str := PChar(Msg.CopyDataStruct.lpData);

  // Si no es la misma aplicaciones, salimos...
  if (Msg.CopyDataStruct.dwData <> 9999) then begin
    Exit;
  end;
  
  // Ejecutar la acción necesaria
  ...

Finalmente me ha parecido la más sencilla y rápida.
Si le veís algun problema comentadlo, aun estoy a tiempo... ;-)

AÑADIDO: Antes de preguntar estuve realizando algunas búsquedas en el foro (y fuera de él) y llegué a bastantes hilos (algunos de ellos los he colocado arriba). No hice mal la búsqueda, pero está claro que no la hice bien al 100%.
Hoy revisando otra vez, he encontrado un hilo al que no llegué ayer y que habla justamente de este problema.
"Abrir fichero asociado si la aplicacion ya esta activa."
http://clubdelphi.com/foros/showthread.php?t=64015
Lo mejor de todo es que Román es justo quien da la solución uilizando el mensaje WM_COPYDATA
Y aporta este link como complemento:
http://www.delphidabbler.com/article...part=2#cmdline
Donde ya está programado un procedimiento justo para lo que necesito (SendParamsToPrevInst)...


Código Delphi [-]
function SendParamsToPrevInst(Wdw: HWND): Boolean;
var
  CopyData: TCopyDataStruct;
  I: Integer;
  CharCount: Integer;
  Data: PChar;
  PData: PChar;
begin
  CharCount := 0;
  for I := 1 to ParamCount do
    Inc(CharCount, Length(ParamStr(I)) + 1);
  Inc(CharCount);
  Data := StrAlloc(CharCount);
  try
    PData := Data;
    for I := 1 to ParamCount do
    begin
      StrPCopy(PData, ParamStr(I));
      Inc(PData, Length(ParamStr(I)) + 1);
    end;
    PData^ := #0;
    CopyData.lpData := Data;
    CopyData.cbData := CharCount * SizeOf(Char);
    CopyData.dwData := cCopyDataWaterMark;
    Result := SendMessage(
      Wdw, WM_COPYDATA, 0, LPARAM(@CopyData)
    ) = 1;
  finally
    StrDispose(Data);
  end;
end;

Un saludo a todos.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.

Última edición por Neftali [Germán.Estévez] fecha: 13-06-2014 a las 09:52:49.
Responder Con Cita