Thema: Delphi WMContextMenu-Apokalpse

Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.015 Beiträge
 
Delphi 12 Athens
 
#2

AW: WMContextMenu-Apokalpse

  Alt 6. Jul 2021, 14:14
Das scheint in der Tat ein Designfehler zu sein. Das angeklickte Control gibt in TWinControl.DefaultHandler erstmal an den jeweiligen Parent weiter (Panel10, Panel9, ... Panel1, Form2).
Delphi-Quellcode:
      if (Msg = WM_CONTEXTMENU) and (Parent <> nil) then
      begin
        Result := Parent.Perform(Msg, WParam, LParam);
        if Result <> 0 then Exit;
      end;
Bis auf Form2, bei dem es ja keinen Parent gibt, wird danach aber noch ein CallWindowProc-Aufuf durchgeführt, der aber am Ende wiederum im WMContextMenu des Controls landet und dort wieder die Leiter der Controls hinaufklettert, was dann zu diesem exponentiellen Wachstum der Durchläufe führt.
Delphi-Quellcode:

          Result := CallWindowProc(FDefWndProc, WindowHandle, Msg, WParam, LParam);
Beispielhaft hier mal die Liste der Aufrufe für einen Klick in Panel3:
Panel3, Panel2, Panel1, Form2, Form2, Panel1, Form2, Form2, Panel2, Panel1, Form2, Form2, Panel1, Form2, Form2

Eigentlich sollte das anfängliche Hochhängeln zum Form ausreichen und die Überprüfung auf Result <> 0 vor dem Exit entfallen. Mit dieser Code-Änderung in TWinControl.DefaultHandler wird das Laufzeitverhalten auch wieder akzeptabel.
Delphi-Quellcode:
      if (Msg = WM_CONTEXTMENU) and (Parent <> nil) then
      begin
        Result := Parent.Perform(Msg, WParam, LParam);
        Exit;
      end;
Als Workaround kannst du z.B. im Form die WM_CONTEXTMENU Message abfangen und den Result auf 1 setzen.
Delphi-Quellcode:
    procedure WMContextMenu(var Message: TWMContextMenu); message WM_CONTEXTMENU;
...

procedure TForm2.WMContextMenu(var Message: TWMContextMenu);
begin
  inherited;
  Message.Result := 1;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming

Geändert von Uwe Raabe ( 6. Jul 2021 um 21:42 Uhr) Grund: inherited vergessen
  Mit Zitat antworten Zitat