Gibt es eine "globale Message" um ein Popup zu schließen
-
- Beiträge: 30
- Registriert: Mi 31. Jan 2018, 11:54
- OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
- CPU-Target: 64Bit
Gibt es eine "globale Message" um ein Popup zu schließen
Moin,
ich habe eine Art von PopUp-Info kreiert, also einfach nur ein TPanel, das sichtbar wird, wenn man auf einer Schaltfläche einer rechten (nicht politisch) Mausklick ausführt. Das Panel kann ich natürlich auch wieder verschwinden lassen, durch einen erneuten Mausklick oder durch eine Auswahl auf dem Panel.
Wie aber kann ich darauf reagieren, wenn der User sonstwo hinklickt? Woher bekommen TMainMenu und TPopupMenu in solchen Fällen die Nachricht geschickt, sich wieder zu schließen? Und wie kann ich das in meinem Programm verwenden? Die onClick Ereignisse von allen verbauten Komponenten auszuwerten erschient mir etwas aufwenig.
Besten Dank
Alex
ich habe eine Art von PopUp-Info kreiert, also einfach nur ein TPanel, das sichtbar wird, wenn man auf einer Schaltfläche einer rechten (nicht politisch) Mausklick ausführt. Das Panel kann ich natürlich auch wieder verschwinden lassen, durch einen erneuten Mausklick oder durch eine Auswahl auf dem Panel.
Wie aber kann ich darauf reagieren, wenn der User sonstwo hinklickt? Woher bekommen TMainMenu und TPopupMenu in solchen Fällen die Nachricht geschickt, sich wieder zu schließen? Und wie kann ich das in meinem Programm verwenden? Die onClick Ereignisse von allen verbauten Komponenten auszuwerten erschient mir etwas aufwenig.
Besten Dank
Alex
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Hi
Ich hatte soetwas damals für mein erstes Projekt(Terminplaner) realisieren müssen.
Jede Menge Panles mit unterschiedlichen Sachen, die aufpopen wenn sie benötigt werden.
Wie das genau das TMainMenu macht weis ich auch nicht.
Ich habe es so gelöst das im Panel im onExit-Event ein Panel.visible steht.
Sobald man nun eine andere Komponente auf der Form anklick, bekommt diese den Focus, und das Panel verschwindet.
Ich hatte soetwas damals für mein erstes Projekt(Terminplaner) realisieren müssen.
Jede Menge Panles mit unterschiedlichen Sachen, die aufpopen wenn sie benötigt werden.
Wie das genau das TMainMenu macht weis ich auch nicht.
Ich habe es so gelöst das im Panel im onExit-Event ein Panel.visible steht.
Sobald man nun eine andere Komponente auf der Form anklick, bekommt diese den Focus, und das Panel verschwindet.
-
- Beiträge: 30
- Registriert: Mi 31. Jan 2018, 11:54
- OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
- CPU-Target: 64Bit
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Hm, hört sich auf den ersten Blick plausibel an, funzt bei mir aber nicht.
Ich habe zur Kontrolle mal ein neues Projekt erstellt, ein TPanel und ein TMemo draufgezogen und im onEnter on onExit Event des Panels jeweils die Ausgabe einer Zeile im Memo eingetragen.
Passiert bei beiden nüscht.
onMouseEnter und -Exit funktionieren, die bringen hier aber nix.
Kann man ein TPanel überhaupt "entern" und wieder verlassen?
Wenn es bei dir funktioniert, wo stehe ich dann auf dem Schlauch?
Jedenfals danke für die Antwort.
Ich habe zur Kontrolle mal ein neues Projekt erstellt, ein TPanel und ein TMemo draufgezogen und im onEnter on onExit Event des Panels jeweils die Ausgabe einer Zeile im Memo eingetragen.
Passiert bei beiden nüscht.
onMouseEnter und -Exit funktionieren, die bringen hier aber nix.
Kann man ein TPanel überhaupt "entern" und wieder verlassen?
Wenn es bei dir funktioniert, wo stehe ich dann auf dem Schlauch?
Jedenfals danke für die Antwort.
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Also ich weiß konkret nicht, wie's geht. Aber du solltest dir mal den Quellcode der TEditButton-Komponente und ihrer Nachfahren ansehen - da ist genau das gelöst. Beim TimeEdit zum Beispiel ist das Popup ein simples Formular, allerdings mit einem speziellen OnDeactivate-Handler:
Möglicherweise ist das schon die Lösung.
Code: Alles auswählen
procedure TTimePopupForm.FormDeactivate(Sender: TObject);
begin
//Immediately hide the form, otherwise it stays visible while e.g. user is draging
//another form (Issue 0028441)
Hide;
if (not FClosed) then
Close;
endM
-
- Beiträge: 30
- Registriert: Mi 31. Jan 2018, 11:54
- OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
- CPU-Target: 64Bit
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Gut vielen Dank, das werde ich mir mal anschauen.
Es gibt wohl so etwas wie eine PopupList, zumindest unter Delphi. Da bin ich aber nicht weiter gekommen.
Es gibt wohl so etwas wie eine PopupList, zumindest unter Delphi. Da bin ich aber nicht weiter gekommen.
- kupferstecher
- Beiträge: 431
- Registriert: Do 17. Nov 2016, 11:52
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Das Panel muss ja erstmal den Focus haben um ihn verlieren zu koennen. Ich wuerde es mal mit Panel.SetFocus beim Anzeigen des Popups versuchen. Wenn das Panel keinen Focus annehmen kann, gibts sicher Moeglichkeiten, das zu aendern.
-
- Beiträge: 30
- Registriert: Mi 31. Jan 2018, 11:54
- OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
- CPU-Target: 64Bit
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Naja, eigentlich ist es schon komisch, dass ein Panel ein onEnter/onExit Event haben kann. Bei einem TEdit ist die Sache klar. Aber wann soll das bei einem Panel stattfinden? Wenn man drauf klickt? Das wäre onClick. In Prinzip ist es mit dem SetFocus genauso. Wann hat ein Panel den Focus? Hat übrigens bei einem schnellen Test nicht funktioniert.
Ich dachte wirklich, dass es da eine einfache Möglichkeit gibt, da der Fall ja nicht so selten auftaucht, wie man am Beitrag von hubblec4 sieht.
Wenn ich am WE dazu komme, werde ich mir den Vorschlag von wp_xyz genauer ansehen.
Ich dachte wirklich, dass es da eine einfache Möglichkeit gibt, da der Fall ja nicht so selten auftaucht, wie man am Beitrag von hubblec4 sieht.
Wenn ich am WE dazu komme, werde ich mir den Vorschlag von wp_xyz genauer ansehen.
-
- Beiträge: 2118
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Gibt es eine "globale Message" um ein Popup zu schließen
z.b. Wenn man Panel.SetFocus aufruftcle hat geschrieben:Naja, eigentlich ist es schon komisch, dass ein Panel ein onEnter/onExit Event haben kann. Bei einem TEdit ist die Sache klar. Aber wann soll das bei einem Panel stattfinden? Wenn man drauf klickt? Das wäre onClick. In Prinzip ist es mit dem SetFocus genauso. Wann hat ein Panel den Focus? Hat übrigens bei einem schnellen Test nicht funktioniert.
Der grund dafür ist wahrscheinlich weil ein panel ein WinControl ist, was den Fokus haben kann. Die gründe dafür stecken wahrscheinlich irgendwo in der grundstrutkur der Windows API, von der sich Delphi abgeleitet hat und zu dem die LCL kompatibel ist.
Das heist aber nicht das es nicht trozdem nützlich sein kann. Ich hab schon öfters mal wenn ich nen eigens designten button haben wollte einfach ein Panel genommen und mit dem Canvas ein bisschen drauf rumgemalt. Geht einfach und schnell, und da es ein TWinControl ist wie ein button, kann man sehr viel LCL funktionalität nutzen um einen button zu emulieren. Manchmal will man nicht eine neue komponente erstellen die man erst in Lazarus linken muss nur um einen einzigen button schön zu machen
- kupferstecher
- Beiträge: 431
- Registriert: Do 17. Nov 2016, 11:52
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Hab das mal kurz probiert, das geht schon. Problem ist, beim Click in den Hintergrund muss das Panel den Fokus auch wieder verlieren, sonst gibts kein OnExit-Event.
Die Form nimmt scheinbar keinen Focus an. Ich hab mal ein 'PanelForm' in den Hintergrund gelegt, die sich bei Click den Fokus gibt. So würde es gehen, ist aber natürlich nicht gerade schön. Code unten.
Was noch gehen könnte, ist das Popup-Element als eigene Form anlegen, dann dürfte das OnEnter/OnExit tatsächlich bei jedem Klick auftreten. Ist aber wieder ein Aufwand.
Die Form nimmt scheinbar keinen Focus an. Ich hab mal ein 'PanelForm' in den Hintergrund gelegt, die sich bei Click den Fokus gibt. So würde es gehen, ist aber natürlich nicht gerade schön. Code unten.
Was noch gehen könnte, ist das Popup-Element als eigene Form anlegen, dann dürfte das OnEnter/OnExit tatsächlich bei jedem Klick auftreten. Ist aber wieder ein Aufwand.
Code: Alles auswählen
procedure TForm1.Panel1Click(Sender: TObject);
begin
Panel1.SetFocus;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Panel1.Show;
Panel1.SetFocus;
end;
procedure TForm1.Panel1Enter(Sender: TObject);
begin
Writeln('Panel1Enter');
end;
procedure TForm1.Panel1Exit(Sender: TObject);
begin
Writeln('Panel1Exit');
Panel1.Hide;
end;
procedure TForm1.PanelFormClick(Sender: TObject);
begin
PanelForm.SetFocus;
end;
-
- Beiträge: 30
- Registriert: Mi 31. Jan 2018, 11:54
- OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
- CPU-Target: 64Bit
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Natürlich nicht, wahrscheinlich mit die nützlichste Komponente, von Container, Abstandshalter, Button, wie hier Menü und MenuItem etc.Warf hat geschrieben: Das heist aber nicht das es nicht trozdem nützlich sein kann.
@kupferstecher
Das mit dem 'PanelForm' hab ich nicht verstanden. Meinst du ein Panel über die ganze Form ziehen?
(...Momente des Nachdenkens...) Ah, okay, doch ich glaube jetzt klickt es langsam. Hm, in der Tat nicht sehr elegant.
Es müsste "einfach" analog zum KeyPreview ein ClickPreview geben ...
-
- Beiträge: 30
- Registriert: Mi 31. Jan 2018, 11:54
- OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
- CPU-Target: 64Bit
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Also, ausgehend von kupferstechers Idee, habe ich mal versucht ein durchsichtiges shape über das Formular zu ziehen:
Das funktioniert auf den ersten Blick ganz gut, bis auf die (nicht unwichtige) Tatsache, dass man ein shape scheinbar nicht in den Vordergrund bringen kann. D.h. alles, was sich sonst noch auf dem Fomular befindet, ist weiter anwählbar.
Also nix mit MacGyver-Programmierung.
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
begin
Shape1.Show;
Shape1.Align := alClient;
Panel1.Show;
Shape1.BringToFront;
Panel1.BringToFront;
end;
procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Panel1.Hide;
Shape1.Hide;
end;
Also nix mit MacGyver-Programmierung.
- kupferstecher
- Beiträge: 431
- Registriert: Do 17. Nov 2016, 11:52
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Shapes sind von TGraphicControl abgeleitet und nicht von TWinControl. GraphicControls sind immer hinter WinControls (zumindest unter WIndows).cle hat geschrieben:Das funktioniert auf den ersten Blick ganz gut, bis auf die (nicht unwichtige) Tatsache, dass man ein shape scheinbar nicht in den Vordergrund bringen kann.
Von TWinControl abgeleitete kennen allerdings keine Transparenz...
Du könntest es höchstens noch mit einer Form versuchen.
Insbesondere wenn sie in einem eigenen Fenster ist, sollte OnExit bei jedem Klick funktionieren, also auch ohne die OnClick-Tricks.
TPopUpMenu funktioniert wohl in der Art.
-
- Beiträge: 30
- Registriert: Mi 31. Jan 2018, 11:54
- OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
- CPU-Target: 64Bit
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Hier unter Linux eben auch.kupferstecher hat geschrieben: GraphicControls sind immer hinter WinControls (zumindest unter WIndows).
Mit onDeactivate funzt es auf den ersten Blick problemlos. Wobei wir wieder dort sind, was wp_xyz vorgeschlagen hatteDu könntest es höchstens noch mit einer Form versuchen.
Insbesondere wenn sie in einem eigenen Fenster ist, sollte OnExit bei jedem Klick funktionieren, also auch ohne die OnClick-Tricks.
TPopUpMenu funktioniert wohl in der Art.

Scheint also die Lösung zu sein.
Nochmals Danke.
-
- Beiträge: 30
- Registriert: Mi 31. Jan 2018, 11:54
- OS, Lazarus, FPC: Winux (L trunc FPC 3.3.1)
- CPU-Target: 64Bit
Re: Gibt es eine "globale Message" um ein Popup zu schließen
Nachtrag, da es wahrscheinlich der eine oder andere gebrauchen kann.
Zunächst hat sich die 'Lösung' mit dem Formular doch nicht als praktikabel herausgestellt. Wie kupferstecher schon festgestellt hatte, funktioniert das nur, wenn das Formular sich in einem eigenen Fenster befindet. Das hat zur Folge, dass das Hauptfenster dann natürlich deaktiviert wird, was die meisten Desktop-Umgebungen mit einem Farbwechsel der Fensterdekoration oder sogar mit einem Abdunkeln des Fensters signalisieren. Sieht beim Öffnen eines Popups natürlich bescheuert aus.
Da aber noch mehr Leute nach so etwas wie einem 'ClickPreview' gesucht haben, bin ich im englischen Lazarus-Forum fündig geworden.
Link
Hier mal der entscheidende Schnipsel aus dem Thread:
Wenn ich Msg auf LM_LBUTTONUP prüfe (und da gibt es noch einen Haufen anderer Möglichkeiten) erreiche genau das, was ich in dem ThreadTitel gefragt hatte.
Unerwünschte Nebenwirkungen habe ich bisher nicht festgestellt.
[gelöst] passt nicht mehr vor den Titel
Zunächst hat sich die 'Lösung' mit dem Formular doch nicht als praktikabel herausgestellt. Wie kupferstecher schon festgestellt hatte, funktioniert das nur, wenn das Formular sich in einem eigenen Fenster befindet. Das hat zur Folge, dass das Hauptfenster dann natürlich deaktiviert wird, was die meisten Desktop-Umgebungen mit einem Farbwechsel der Fensterdekoration oder sogar mit einem Abdunkeln des Fensters signalisieren. Sieht beim Öffnen eines Popups natürlich bescheuert aus.
Da aber noch mehr Leute nach so etwas wie einem 'ClickPreview' gesucht haben, bin ich im englischen Lazarus-Forum fündig geworden.
Link
Hier mal der entscheidende Schnipsel aus dem Thread:
Code: Alles auswählen
uses
..., Forms, LMessages;
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.AddOnUserInputHandler(@MouseHook);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
// To prevent possible system resource leaks
Application.RemoveOnUserInputHandler(@MouseHook);
end;
procedure TForm1.MouseHook(Sender: TObject; Msg: Cardinal);
begin
if (Msg <> LM_MOUSEMOVE) and (Msg <> LM_NCMOUSEMOVE) then Exit;
// Do stuff
end;
Unerwünschte Nebenwirkungen habe ich bisher nicht festgestellt.
[gelöst] passt nicht mehr vor den Titel