![]() |
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? |
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).
|
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. |
Re: Panel automatisch schließen
Naja dann kannst du doch gucken mit OnMouseDown/Up ob auf das Formular geklickt wurde?
MfG xZise |
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. |
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 |
Re: Panel automatisch schließen
Probier mal SetCapture.
Starthilfe:
Delphi-Quellcode:
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.
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; Guido. Edit: Beispiel-Code verbessert. |
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... ;-)
|
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. |
Re: Panel automatisch schließen
Nein, ich habe den Code oben nicht getestet, aber SetCapture funktioniert so nicht. Hast du es getestet? Siehe
![]() Zitat:
// EDIT: Aber es funktioniert trotzdem. Tut mir leid, damit hatte ich nicht gerechnet. :gruebel: |
Re: Panel automatisch schließen
Ich habe die Dokumentation gelesen und den Code getestet. Es funktioniert. Ich verstehe nicht, warum das nicht gehen soll.
Guido. Edit: Ups, hast es schon gemerkt. :wink: |
Re: Panel automatisch schließen
Ja, es geht, habe ich eben auch editiert. Der Punkt ist, dass ein MouseUp gesendet wird, wenn die Maus woanders gedrückt wird. Das heißt es ist nicht wie in der Dokumentation beschrieben, dass dann gar nichts gesendet wird, es wird nur kein MouseDown gesendet, sondern stattdessen ein MouseUp. :shock:
|
Re: Panel automatisch schließen
Zitat:
Guido. |
Re: Panel automatisch schließen
Dann hast du das vermutlich unter einem anderen Betriebssystem getestet? Bei mir ist es Vista. Und da kam das MouseUp an als ich die Maustaste nur über einem fremden Fenster gedrückt habe. //EDIT: Und das MouseDown auch, stimmt. Beides kommt beim Drücken an.
XP habe ich nicht mehr direkt da, kann ich aber in einer VM einmal testen. // EDIT: Grade getan, dort ist es genauso. Von einem fremden Fenster kommt beides zugleich an. Dein ShowMessage verursacht, dass das bei dir nicht passiert, nehme ich an. ;-) |
Re: Panel automatisch schließen
Rofl ... :oops: ShowMessage ist für solch einen Test natürlich ziemlich ungeeignet. *ablenk-und-pfeif*
Ich hab jetzt zum Testen (auf XP) eine ListBox genommen und siehe da, es kommen beide Events an (MouseUp und -Down). Wenn man jedoch, wie in deinem Test, auf ein fremdes Fenster klickt, werden die beiden Events so schnell gefeuert, dass man das nur mit ListBox...Add o. ä. mitkriegen kann. Ich hoffe, dass Roaster jetzt überhaupt noch den Faden von SetCapture mitbekommt. :gruebel: Ansonsten gehen wir halt einen :cheers: Guido. Edit: Verflixt, haben sich unsere Postings schon wieder überschnitten. :wall: Ich glaube, ich sollte mir mit dem Antworten mehr Zeit lassen, dann schreibst du von selbst alles, was ich auch sagen will. :-D |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:57 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-2025 by Thomas Breitkreuz