Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Schliessen eines Kontextmenüs


HawkLUED - Di 09.11.04 13:36
Titel: Schliessen eines Kontextmenüs
Hallo,

noch eine Frage zu einem Kontextmenü!

Ich habe ein Kontextmenü, welches ein Abbrechen beinhaltet, womit das Kontextmenü geschlossen wird ohne das eine Aktion ausgeführt wird! Gleiches Verhalte natürlich auch, wenn ESC gedrückt wird! Aber, ein Kontextmenü verschwindet ja auch, wenn irgendwo anders hin geklickt wurde! Kann man dieses irgendwie mitbekommen??

Danke!

Gruß


Sprint - Di 09.11.04 21:02

Windows sendet dazu die Nachricht WM_EXITMENULOOP. Bei TMainMenu kannst du die ohne weiters abfangen, weil dort die Nachricht an die Form geschickt wird. Bei TPopupMenu's musst du das Fensterhandle von TPopupList subclassen. Das kannst du zum Beispiel so machen...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
   
  ...

type
  TForm1 = class(TForm)
  ...
  private
    { Private-Deklarationen }
    OldPopupListWndProc: TFNWndProc;
    NewPopupListWndProc: TFNWndProc;
    procedure PopupListWndProc(var Message: TMessage);
  ...
  end;

  ...

{--------------------------------------------------------------------------------------------------}

procedure TForm1.FormCreate(Sender: TObject);
begin
  NewPopupListWndProc := MakeObjectInstance(PopupListWndProc);
  OldPopupListWndProc := TFNWndProc(GetWindowLong(PopupList.Window, GWL_WNDPROC));
  SetWindowLong(PopupList.Window, GWL_WNDPROC, Longint(NewPopupListWndProc));
end;

{--------------------------------------------------------------------------------------------------}

procedure TForm1.FormDestroy(Sender: TObject);
begin
  SetWindowLong(PopupList.Window, GWL_WNDPROC, Longint(OldPopupListWndProc));
end;

{--------------------------------------------------------------------------------------------------}

procedure TForm1.PopupListWndProc(var Message: TMessage);
begin
  with Message do
  begin
    case Msg of
      WM_ENTERMENULOOP:; // PopupMenu wird geöffnet
      WM_EXITMENULOOP:;  // PopupMenu wird geschlossen
    end;
    Result := DefWindowProc(PopupList.Window, Msg, WParam, LParam);
  end;
end;

{--------------------------------------------------------------------------------------------------}

  ...


Motzi - Di 09.11.04 21:23

@Sprint: ist dir eigentlich bewusst, dass du da ein Speicherleck drin hast? Ich seh zumindest keinen Aufruf von FreeObjectInstance..


Sprint - Di 09.11.04 21:47

Das liegt wohl daran, das ich die Funktionen MakeObjectInstance/FreeObjectInstance zu selten benutze.


HawkLUED - Mi 10.11.04 09:29
Titel: Danke!
Hi Sprint,

danke für Deine Antwort1 Leider hat sich meine Problemstellung ein wenig geändert, so daß dDein Vorschla wahrschenlich mir nichts mehr nützt! Ode vielleicht dort.

Ih habe ein Programm gescrieben, welches über eine Explorer-Artige Darstellung mehrere Datenbanken verwaltet! Dort habe ich jetzt as Drag&Drop so umgeaut, daß wenn ein Anwender ein Element in einen Ordner draggen will OHNE strg oder SHIFT gedrückt zu haben ein Konextmenü erhält, in dem er auswählen kann, ob er kopieren oder verschieben möchte (Wie im WinExplorer draggen über rechte Maustaste)! Problem ist jetzt, das ich die gewählte Aktion nicht zurückbekomme, wenn sich das PopUpMenü schliesst! Es würde ein Application.ProcessMessages helfen, aber dann bekomme ich andere üble Exceptions in VCL70.bpl!

Gibts eine andere Möglichkeit, an den gewählten Eintrag zu kommen???

P.S. die Meneinträge sind mit Action verknüpft, die aber nicht gerufen werden, bzw. die entpsrechende Message wird wohl "hinten" angehängt!

Gruß

Andreas