Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi MouseUp in Popupmenu (https://www.delphipraxis.net/212938-mouseup-popupmenu.html)

osbos 26. Apr 2023 20:35

MouseUp in Popupmenu
 
Beim Gedrückthalten der Maus auf einen Button öffnet sich ein Popupmenu neben dem Button.
Nun soll der Benutzer meim Loslassen der Maus die Procedure auslösen, die dem entsprechendem MenuItem zugewiesen ist.
Leider hat das TMenuItem aber kein OnMouseUp Event, sondern nur ein OnClick Event. Das bedeutet, dass der Benutzer die Maustaste erst loslassen und dan erneut clicken muss.
Z.B. in der Toolleiste bei Photoshop funktioniert das direkt.
Wie könnte man solch ein Verhalten in Delphi realisieren?
Ich verwende Delphi 10.4 von 2021.

Vielen Dank im Voraus!

ConnorMcLeod 27. Apr 2023 10:33

AW: MouseUp in Popupmenu
 
Ist vllt mit Kanonen auf Spatzen zu schießen, aber auf Form-Ebene kann man die MouseMessages abfangen.

PaPaNi 27. Apr 2023 11:18

AW: MouseUp in Popupmenu
 
Wenn ich die Beschreibung richtig verstanden habe, dann fällt mir als Erstes so was ein...(vielleicht hilft das weiter)

1. Form-Constructor
Delphi-Quellcode:
  FMyPopupMenu := TPopupMenu.Create(Self);

  mi := TMenuItem.Create(Self);
  mi.Caption := 'Say YES';
  mi.OnClick := MyMenuClick;
  FMyPopupMenu.Items.Add(mi);

  mi := TMenuItem.Create(Self);
  mi.Caption := 'Say NO';
  mi.OnClick := MyMenuClick;
  FMyPopupMenu.Items.Add(mi);
2. OnMouseDown vom Button
Delphi-Quellcode:
var
  P: TPoint;
begin
  GetCursorPos(P);
  FMyPopupMenu.Popup(P.X, P.Y);
end;
3. procedure MyMenuClick(Sender: TObject);
Delphi-Quellcode:
var
  mi: TMenuItem;
begin
  mi := (Sender as TMenuItem);
  ShowMessage(mi.Caption);
end;

osbos 27. Apr 2023 18:06

AW: MouseUp in Popupmenu
 
Die MouseMessage abfangen habe ich auch schon versucht.
Mithilfe der ApplicationEvent Componente.
Delphi-Quellcode:
procedure TButVersForm.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
if msg.message=WM_LBUTTONUP then showmessage('UP');
end;
Das funktioniert bei allen Controls im Formular, aber nicht beim PopupMenu.
Vermutlich weil das aufgepopte Menu-Control kein Child des Hauptformulars ist, oder?
Gibt es noch eine Möglichkeit, alle Messages der Application abzufangen, egal welches Fenster/Control gemeint ist?

himitsu 27. Apr 2023 18:23

AW: MouseUp in Popupmenu
 
Beim Application.OnMessage kommen ausschließlich PostMessage vorbei, welche in der Haupt-Messagebehandlung (TApplication.ProcessMessage und .HandleMessage) abgerufen und behandelt werden.
Auch SendMessage werden direkt im PeakMessage/GetMessage verarbeitet und kommen ebenfalls nichts bis zum OnMessage raus.
Und Form.WndProc bekommt auch nichts mit, da Menüs und Popups eigenständige Fenster sind.

Das Menu.Popup ist wie ein MessageBox, welches im Windows seine eigene Messageloop benutzt und das Hauptprogramm so lange stoppt.

Hier kommt man ausschlielich über einen MessageHook dran,
oder z.B. wenn man das Popup ableitet und sich ins WndProc hängt.

Mal die VCLStyles für's Popup aktivieren ... vielleicht hat Emba da bereits einen perversen passenden Hook implementiert und leitet ihn zur VCL (Application) um.

ConnorMcLeod 27. Apr 2023 20:37

AW: MouseUp in Popupmenu
 
Mglw ist das hier ein Ansatz: ein alter Sourcecode vom echten Peter Below, der auf Github konserviert wurde. Die Idee ist erkennbar, für aktuelle Delphine muß das "nur" neu geschrieben werden.
Ich habe die Entsprechung in Vcl.Menus gefunden.

Uwe Raabe 27. Apr 2023 22:31

AW: MouseUp in Popupmenu
 
Zitat:

Zitat von osbos (Beitrag 1521598)
Beim Gedrückthalten der Maus auf einen Button öffnet sich ein Popupmenu neben dem Button.
Nun soll der Benutzer meim Loslassen der Maus die Procedure auslösen, die dem entsprechendem MenuItem zugewiesen ist.

Ein kurzes Beispiel zeigt, dass das (zumindest in 11.3.1) ohne weiteres Zutun funktioniert. Dazu habe ich im OnMouseDown-Event des Controls folgenden Code:
Delphi-Quellcode:
  if (Button = TMouseButton.mbRight) and (Shift = [ssRight]) then begin
    var P := (Sender as TControl).ClientToScreen(TPoint.Create(X, Y));
    PopupMenu1.Popup(P.X, P.Y);
  end;
Beim Loslassen der rechten Maustaste wird dann der OnClick-Event ausgeführt.

Das funktioniert aber nur mit der rechten Maustaste, weil es für das PopupMenu ein WM_MENURBUTTONUP aber kein WM_MENULBUTTONUP gibt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz