Entwickler-Ecke

Sonstiges (Delphi) - Windows Message - einmal gesendet, mehrmals bearbeitet !?


starsurfer - Mi 03.05.06 18:49
Titel: Windows Message - einmal gesendet, mehrmals bearbeitet !?
Ich verschicke zum Programmstart eine Windows Message

Delphi-Quelltext
1:
2:
unit1.ActivationMessage := RegisterWindowMessage(PChar(Unit1.MyGUID));
postMessage(HWND_BROADCAST, Unit1.ActivationMessage, 00);


ich habs mit Haltepunkt überprüft, das wird nur EINMAL angesteuert.

Mit folgendem Code überprüfe ich dann die Windows Message

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
var ActivationMessage: Cardinal;

const MyGUID = '{77123298-61B8-45AB-8DD3-3691B6BFF36C}';

...

application.onmessage:=ApplicationEvents1Message;

...

procedure TForm1.ApplicationEvents1Message(var Msg: TMSG;var Handled: Boolean);
begin
 if (Msg.message = ActivationMessage) then
  begin
    showmessage('da haben wir die sch***');//dieser
    Application.Restore;                    //ganze 
    SetForegroundWindow(Handle);            //Spaß wird
    Handled := true;                        //viermal abgearbeitet
  end;
end;


Nur wieso wird das immer 4 mal abgearbeitet?

ich dachte Handled := true; sorgt dafür das Windows gemeldet wird die Message ist bearbeitet.


starsurfer - Mi 03.05.06 23:29

ok, habe mir garde ne Test Anwendung geschrieben,

Ein komplett leere Projekt genommen und nur die Befehle die fürs senden und empfangen zuständig sind rein geschreiben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure tform1.nachrich(var nachricht:tmsg;var handled:boolean);
begin
if nachricht.message=1009 then
   begin
   showmessage('nachricht erhalten');
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
postmessage(HWND_BROADCAST,10090,0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
application.OnMessage:=nachrich;
end;


ES funktionier einwandfrei...

in meiner Hauptanwendung hab ich das Message senden auch auf das Maß an Befehlen reduziert(natürlich alle anderen Befehle die nich mit dem Message senden drinne gelassen)....

ER führt

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure tform1.nachrich(var nachricht:tmsg;var handled:boolean);
begin
if nachricht.message=1009 then
   begin
   showmessage('nachricht erhalten');
   end;
end;


wieder vier mal aus -_-

die zahl(1009) hab ich auch geändert, dynamisch erzeugt usw....

kann es irgendwas in meinem Programm geben was die Windowsmessage reflektiert/ abfängt und erneut sendet?


Simon Joker - Do 04.05.06 09:30

user profile iconstarsurfer hat folgendes geschrieben:

kann es irgendwas in meinem Programm geben was die Windowsmessage reflektiert/ abfängt und erneut sendet?


Ja, ohne weiteres kann das sein! Viele Componenten überschreiben den die WindowProc-Methode ihres ParentControl um sich in die Messageverarbeitung einzuklinken. Sie setzten sich sozusagen als "Man in the middle" ein, verarbeiten Messages für sich und rufen dann die überschriebene Methode wieder auf. Das kann manchmal zu seltsamen Ergebnissen führen.

Beispiel für das Überschreiben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
  ...
  //das im Constructor
  FControl := Control; //Control speichern
  FDefWindowProc := FControl.WindowProc; //Orginale WindowProc speichern
  FControl.WindowProc := WndProc; //eigene WindowProc zuweisen
  ...
  procedure TMyClass.WndProc(var Message: TMessage);
  begin
    //Messages verarbeiten
    ...
    //Orginale WinProc aufrufen
    FWindowProc(Message, FDefWindowProc);
  end;


Die "property WindowProc: TWndMethod;" hat keinen Handled-Parameter, deshalb läuft die Kaskade der Verarbeitung immer durch alle WindowProc's.

OB du soche Komponenten hast .. tja Keine Ahnung. :-)

MfG Simon


starsurfer - Do 04.05.06 10:34

ok, ich hab mal n paar Komponenten aus meinem Projekt raus gelöscht, und hab die Schuldigen gefunden.

TTimer :motz:
TPopupMenu :motz:


kann ich dafür sorgen das die die mein unschuldige Message nicht in ihre dreckigen schmierigen Griffeln :evil: bekommen oder muss ich die Komponenten am Ende weg machen?(bei TTimer wärs kein Problem, aba das PopupMenu brauch ich schon...)