Komunikaty i wskaźniki...

0

Witam wszystkich !

W swojej aplikacji chciałbym zrobić takie cudo, aby można było uruchomić tylko jedną instancję programu, a przy próbie uruchomienia drugiej, gdyby ta duga uruchamiana była z parametrem (konkretnie to ze ścieżką do pliku), to ta ścieżka wysyłana byłaby do tej pierwszej instancji i ona właśnie otwierałaby wskazany plik.

Prawie wszytsko już jest gotowe, wybrałem takie rozwiązanie, że jeśli druga instancja jest uruchomiona, to wysyłany jest do niej komunikat (WM_USER+120), a jako wParam podaję ścieżkę wskaźnik do ścieżki do pliku (Integer(ParamStr(1)).

Problem w tym, że jak chcę odebrać ten komunikat (przez komponent AppEvent >> zdarzenie OnMessage), to zaczynają sioę schody.
Kod przy zdarzeniu :

procedure TfrmMain.AppEventsMessage(var Msg: tagMSG;
  var Handled: Boolean);
var FName:string;
begin
  if Msg.message = WM_USER+120 then
  begin
   FName:=PChar(msg.wParam);
   ShowMessage(FName);
   if FileExists(FName) then
      OpenFile(FName);
  end;
end;

Aha, wysyłam komunikat poprzez taką instrukcję :

PostMessage(PrevInstHandle,WM_USER+120,Integer(ParamStr(1)),Length(ParamStr(1)));

Cóż się dzieje ??
Przy zdarzeniu OnMessage, wszytsko jest OK, poza jedną dziwną rzeczą. Zmienna FName powinna być pierwszym parametrem przekazanym do drugiej instancji, a okazuje się (wiem to z ShowMesage(FName)), że jest to ścieżka do aplikacji (ParamStr(0));

Co jest więc grane ???
Miał ktoś podobny problem ???
Z góry dzięki za podpowiedzi...

0

jest prostsze rozwiazanie tego problemu w FAQ, poszukaj.

0

Heh, podobnego kodu ja używam, ale ja chcę jeszcze przesłać do pierwszej instancji komunikat, aby obsłużyła ona nowy plik do załadowania...

0

Teraz wiem więcej.
Gdy pierwszą instancję uruchamiam z jakimś parametrem (paramstr(1)), to jeśli w drugiej chcę pobrać pierwszy parametr ale tej drugiej instancji, to niestety, ale delphi szaleje i podaje mi pierwszy parametr, ale z pierwszej instancji...
Co robić, aby pobrać parametr z aktualnej instancji programu ???
Czy jest jakaś funkcja typu GetParameter(hInstane:hWND;nParam:integer):string; ???

0

Cześć! Nie zabardzo rozumiem Twojego problemu, po co sobie utrudniasz? Ale jeżeli ma być ten sposób, to jeżeli dobrze zrozumiałem, to podczas włączania drugiej kopii tego samego programu, to tamten ma być zamykany. Zrób tak, że program, przy odpaleniu szukał okna o takich parametrach, jak ma sam, bądź wysłał do wszystkich okien komunikat, np. WM_USER + 123. Jeżeli jest już odpalony jakiś taki Twój program, to niech odczyta ten komunikat i prześle kopii komunikat np. WM_USER + 234, po którym ma się ta kopia wyłączyć. Czy nie zabardzo zamieszłam?? :P

  1. Włączasz program
  2. Wysyłasz komunikat do wszystkich okien, np. WM_USER + 123 (czyli, że się ten program włączył)
  3. Jeżeli jest już odpalony ten sam program, to niech mu wyśle inny komunikat, np. WM_USER + 234, po którym ta kopia musi się wyłączyć i przekazać mu informacje, np przez rejestr.
    Mam nadzieję, że pomogłem :)
0

Dzięki za podpowiedź, poradziłem już sobie, ale chyba jednak mój sposób jest prostszy.
Wystarczy tylko wysłać drugiej instancji ścieżkę do otwieranego pliku.

Procedura wysyłająca powinna wyglądać tak:

    var
       aAtom:TAtom;

    ...

    if FileExists(ParamStr(1)) then
       begin
         aAtom := GlobalAddAtom(PChar(ParamStr(1)));
         if aAtom<>0 then
              PostMessage(PrevInstHandle, WM_USER+120, aAtom, 0);
       end

zaś kod komponentu AppEvent.OnMessage tak:

  if Msg.message = WM_USER+120 then
  begin
   SetLength(FName, MAX_PATH);
   Len := GlobalGetAtomName(Msg.wParam, PChar(FName), MAX_PATH);
  if Len <> 0 then
    begin
      SetLength(FName, Len);
      if FileExists(FName) then
         OpenFile(FName);
    end;
     GlobalDeleteAtom(msg.wParam);
  end;

To wszystko. Jeszcze raz dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0