Delphi-PRAXiS
Seite 1 von 2  1 2      

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 Panel automatisch schließen (https://www.delphipraxis.net/138551-panel-automatisch-schliessen.html)

Roaster 12. Aug 2009 12:57


Panel automatisch schließen
 
Hi,

ich bastle gerade an einem neuen Control, dass im Wesentlichen aus einem Button besteht, der beim Klick darauf ein TPanel mit einer TTrackbar öffnet.

Das funktioniert bereits einwandfrei, nur möchte ich jetzt, dass dieses Panel wieder automatisch schließt, sobald ich bspw. mit der Maus die Größe des Hauptformulars ändere, oder einfach nur irgendwo mit der Maus hinklicke, und zwar nicht auf das Panel oder die TrackBar). Was natürlich bereits geht, ist das Schließen durch einen erneuten Klick auf den Button.

Im Prinzip ist es eigentlich das gleiche Verhalten, dass eine Standard ComboBox zeigt: Nachdem der Button angeklickt wurde, klappt die Liste auf und wieder zu, sobald man irgendwo ausserhalb des Controls/der Liste klickt.

In meinem Fall besteht das neue Control aber aus mehreren einzelnen, so dass bspw. die Nachricht WM_KILLFOCUS oder CM_FOCUSCHANGED hier nicht weiterhilft, zumindest verliert der Button ja bereits den Focus sobald das Panel angezeigt wird. Genau in diesem Fall macht es natürlich noch keinen Sinn das Panel wieder zu schließen.

Wie könnte man dies jetzt lösen?

guidok 12. Aug 2009 13:15

Re: Panel automatisch schließen
 
Das Panel hat doch ein Ereignis OnExit, das aufgerufen wird, wenn es den Fokus verliert (und das macht es, wenn du auf ein anderes Element klickst).

Roaster 13. Aug 2009 07:55

Re: Panel automatisch schließen
 
Hi,

du hast recht, dies funktioniert solang der User auf ein neues Control wie ein TEdit oder eine TCheckbox klickt. Es funktioniert hingegen nicht, wenn der User auf einen freien Platz im Formular klickt, oder die Größe des Formulars verändert.

Gibt's da auch etwas Entsprechendes dafür. WM_SIZE wird ja nur gesendet, wenn sich das Control, in meinem Fall der neue Button, in der Größe ändert, nicht aber, wenn das Formular in der Größe geändert wird.

xZise 13. Aug 2009 11:31

Re: Panel automatisch schließen
 
Naja dann kannst du doch gucken mit OnMouseDown/Up ob auf das Formular geklickt wurde?

MfG
xZise

Roaster 13. Aug 2009 11:38

Re: Panel automatisch schließen
 
Ja,

das könnte ich schon, allerdings regt sich da ein wenig Widerstand in mir, da diese Funktionalität ja das Control mitbringen und nicht vom Programmierer von ausserhalb des Controls gelöst werden soll.

Ich muss ja auch keine ComboBox manuell schließen,indem ich jedesmal nach einem Mausklick prüfe, ob es nicht das Control selbst war, zum Zeitpunkt des Mausklicks. Ich denke da muss es noch irgendetwas anderes geben.

OnExit funktioniert bereits in meinem neuen Control, lediglich für den Klick auf das Formular suche ich noch eine Lösung.

Edit: OnExit funktioniert für fast alle Standard Controls, wenn ich jedoch ein TUpDown Control noch auf's Formular lege und dann bei geöffnetem Panel auf das TUpDown klicke, dann wird komischerweise das OnExit Event nicht aufgerufen und logischerweise auch nicht das Panel geschlossen - sehr seltsam das Ganze.

Optiplex 14. Aug 2009 11:39

Re: Panel automatisch schließen
 
Hallo, ich weis nicht ob dir das hilft aber mit GetParentForm kann man auf das Formular zugreifen und eventuell die Ereignisse auf eigene Methoden umleiten. Weis allerdings nicht ob das so funktioniert, war nur so eine Idee.

Gruß
Dieter

Guido Eisenbeis 16. Aug 2009 00:53

Re: Panel automatisch schließen
 
Probier mal SetCapture.

Starthilfe:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Panel1.Visible := false;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Panel1.Visible := true;
  SetCapture(Panel1.Handle);
end;

procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Pnt: TPoint;
  Rct: TRect;
begin
  GetCursorPos(Pnt);
  GetWindowRect(Panel1.Handle, Rct);
  if not PtInRect(Rct, Pnt) then
    Panel1.Visible := false
  else
    SetCapture(Panel1.Handle);
end;
Das ist nun zunächst mal ein Rundumschlag, der dir den systemweiten Mouseinput sichert, bis ein MouseUp oder -Down eintrifft. Den Feinschliff kannst du vielleicht mit PtInRect durchführen.

Guido.

Edit:
Beispiel-Code verbessert.

jaenicke 16. Aug 2009 03:45

Re: Panel automatisch schließen
 
SetCapture funktioniert aber nur solange der Benutzer in das angegebene Control geklickt hat und dann die Maus außerhalb zieht. Wenn die linke Maustaste nicht gedrückt bleibt, klappt das nicht... ;-)

Guido Eisenbeis 16. Aug 2009 03:55

Re: Panel automatisch schließen
 
Hallo Sebastian,

ich kann dir gerade nicht folgen. Hast du den Code oben getestet? Der Ablauf wurde von Roaster vorgegeben und funktioniert in meinem Beispiel oben (halt im Ansatz). Zum Starten wird der Button geklickt, dadurch wird das Beispiel-Panel angezeigt und erhält das nächste MouseEvent, egal wo geklickt wird.

Ich weiß jetzt nicht, wie du auf das Ziehen und Festhalten kommst. Oder hab ich was falsch verstanden.

Guido.

jaenicke 16. Aug 2009 03:59

Re: Panel automatisch schließen
 
Nein, ich habe den Code oben nicht getestet, aber SetCapture funktioniert so nicht. Hast du es getestet? Siehe Dokumentation:
Zitat:

SetCapture captures mouse input either when the mouse is over the capturing window, or when the mouse button was pressed while the mouse was over the capturing window and the button is still down. [...]

If the mouse cursor is over a window created by another thread, the system will direct mouse input to the specified window only if a mouse button is down.
Heißt: Zumindest, wenn man mit der Maus über ein anderes Programm geht, bekommt das Programm das Mausereignis nicht.

// EDIT:
Aber es funktioniert trotzdem. Tut mir leid, damit hatte ich nicht gerechnet. :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:43 Uhr.
Seite 1 von 2  1 2      

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