Avatar billede nop Nybegynder
13. juni 2003 - 09:04 Der er 4 kommentarer og
1 løsning

Send en msg til anden instance af samme application.

Det skulle vel sige det hele meeen:
Programmet skal sende en msg til alle instance af sig selv, undtagen sig selv. Messagen skal fx være en integer. Hvordan gør man det ?
Avatar billede doctorseb Nybegynder
16. juni 2003 - 21:04 #1
Check RegisterWindowMessage() og PostMessage med HWND_BROADCAST. De holder, hvis du kun vil bruge integers (evt. to). Du er sæføli' nødt til selv at holde styr hvem der har sendt.

Hvis du vil sende større data, ville Shared Memory ovenpå ovenstående teknik være en mulig vej. Check CreateFileMapping()-familien.
Avatar billede nop Nybegynder
17. juni 2003 - 09:37 #2
Jeg kan godt få programmet til at sende(?), men jeg modtager aldrig noget, er det ikke sådan her man gør:

const
  wm_close = 401;

TfrmMain = class(Tform)
...
private
  FCustMsg:    THandle;
  FinMutex:    boolean;
  procedure WMclose(var Message: TMessage); message WM_close;
  procedure WndProc(var Message: TMessage); override;
...
end;


procedure TfrmMain.WMclose(var Message: TMessage);
begin
    info('i wm close');
    if not FinMutex then close;
end;

procedure TfrmMain.WndProc(var Message: TMessage);
begin
  if Message.Msg <> FCustMsg then
    inherited
  else begin
    info('i wnd proc FcustMsg');
    PostMessage(HWND_BROADCAST ,FcustMsg, Message.LParam, 0);
        Message.Result:= 0;
  end;
end;

Jeg sender på følgende måde:

procedure TfrmMain.FormCreate(sender: tobject);

  procedure testMutex;
  begin
    FCustMsg:= RegisterWindowMessage(MUTEX_NAME);
    FMutex:= CreateMutex(nil, false, MUTEX_NAME);
    FFirstMutex:= (GetLastError = 0);
    if not FFirstMutex then begin
      info('sender luk');
      PostMessage(HWND_BROADCAST, FcustMsg,
                  WM_close,0); //sender luk til alle
    end;
  end;

begin
  FinMutex:=true;
  testMutex;
  FinMutex:=false;
  ...
end;

Jeg forstår ikke hvorfor man skal have wndproc'en (stjålet fra andet prog), og desuden kommer den aldrig til info'en i wndproc'en, så msg'en kommer vel aldrig ud af programmet ?
Kan du se hvad jeg gør galt, ellers må du give en lidt mere komplet løsning.
--nop
Avatar billede doctorseb Nybegynder
17. juni 2003 - 20:51 #3
Hejsa,

Der er lidt problemer med din kode.

1) WM_CLOSE redefineres til LB_GETSELITEMS(!). Hvorfor nu det? Hvis du bare inkluderer "messages.pas" i din uses er du home free.

2) Du skal bruge wndproc fordi du benytter en på runtime bestemt message (din FCustMsg). Compileren kan ikke mappe disse med de sædvanlige "message"-direktiver.

3) Du bruger samme navn til RegisterWindowMessage() og CreateMutex() - jeg er ikke klar over hvorvidt det er sundt eller ej (jeg ville aldrig gøre det).

4) I følgende kode:
  FMutex:= CreateMutex(nil, false, MUTEX_NAME);
  FFirstMutex:= (GetLastError = 0);
  if not FFirstMutex then begin
    info('sender luk');
    PostMessage(HWND_BROADCAST, FcustMsg, WM_close,0); //sender luk til alle
  end;

mangler du et check på om FFirstMutex er oprettet korrekt (CreateMutex returnere != NULL).

Men det alt overskyggende problem er følgende fælde: PostMessage sammen med HWND_BROADCAST fungerer kun med top-level vinduer. Delphi forms har TApplication som owner, hvorfor de ikke er top-level.

Mulige løsninger er, at bruge SendMessage i stedet (ikke videre kønt), at fjerne TApplication som owner, eller på forhånd at finde ud af hvem du skal post'e til (f.eks. med EnumWindows()-familien) og så poste til dem en ad gangen.


Held og lykke - det er lidt af en mundfuld :o)
Avatar billede nop Nybegynder
18. juni 2003 - 09:11 #4
1: Hvad mener du ?
2: ok, mapping !
3: Nej ok, men måske er det i to forskellige context'te, men vælger bare et andet navn.
4: Jeg bruger vel getLastError til netop at teste om oprettet, fordi der kun kan oprettes én mutex med et givent navn, det må være rigtigt det jeg har lavet.

Jeg synes at din enumwindows lyder som om at jeg kan bruge den, jeg kender jo navnet på windows'ene og når jeg så looper alle de fundene igennem kan jeg teste om handlet er det samme som application.handle og dermed undlade at sende til denne instance (mySelf !). Du får pointene måske gider du alligevel svare på nr 1 ? Tak for hjælpen men en dag vil jeg altså have check på msg'es.
--nop
Avatar billede doctorseb Nybegynder
18. juni 2003 - 21:53 #5
Du definere WM_CLOSE = 401 i toppen. WM_CLOSE er allerede defineret til dens korrekt værdi (16) i messages.pas.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester