Computerwissenschaften

Klicken und ziehen Sie ein Delphi-Formular ohne Beschriftungsleiste

Die häufigste Methode zum Verschieben eines Fensters besteht darin, es an der Titelleiste zu ziehen. Lesen Sie weiter, um herauszufinden, wie Sie Ziehfunktionen für Delph i-Formulare ohne Titelleiste bereitstellen können , damit der Benutzer ein Formular verschieben kann, indem Sie auf eine beliebige Stelle im Clientbereich klicken.

Stellen Sie sich zum Beispiel den Fall einer Windows-Anwendung ohne Titelleiste vor. Wie können wir ein solches Fenster verschieben? Tatsächlich ist es möglich, Fenster mit einer nicht standardmäßigen Titelleiste und sogar nicht rechteckigen Formularen zu erstellen. Wie kann Windows in diesem Fall wissen, wo sich die Ränder und Ecken des Fensters befinden?

 

Die Windows-Nachricht WM_NCHitTest

Das Windows-Betriebssystem basiert stark auf der Verarbeitung von Nachrichten. Wenn Sie beispielsweise auf ein Fenster oder ein Steuerelement klicken, sendet Windows eine wm_LButtonDown-Nachricht mit zusätzlichen Informationen darüber, wo sich der Mauszeiger befindet und welche Steuerelementtasten derzeit gedrückt werden. Klingt vertraut? Ja, dies ist nichts weiter als ein OnMouseDown-Ereignis in Delphi.

In ähnlicher Weise sendet Windows eine wm_NCHitTest-Nachricht, wenn ein Mausereignis auftritt, dh wenn sich der Cursor bewegt oder wenn eine Maustaste gedrückt oder losgelassen wird.

 

Code zur Eingabe

Wenn wir Windows glauben lassen können, dass der Benutzer die Titelleiste und nicht den Clientbereich zieht (darauf geklickt hat), kann der Benutzer das Fenster durch Klicken in den Clientbereich ziehen. Der einfachste Weg, dies zu tun, besteht darin, Windows zu „täuschen“, dass Sie tatsächlich auf die Titelleiste eines Formulars klicken. Folgendes müssen Sie tun:

1. Fügen Sie die folgende Zeile in den Abschnitt „Private Deklarationen“ Ihres Formulars ein (Deklaration des Nachrichtenbehandlungsverfahrens):


 Prozedur WMNCHitTest ( var Msg: TWMNCHitTest); Nachricht WM_NCHitTest;

2. Fügen Sie den folgenden Code in den Abschnitt „Implementierung“ der Formulareinheit ein (wobei Form1 der angenommene Formularname ist):


 Prozedur TForm1.WMNCHitTest ( var Msg: TWMNCHitTest);

 

Start

 

geerbt ;

 

wenn Msg.Result=htClient, dann Msg.Result:=htCaption;

 

Ende ;

Die erste Codezeile im Nachrichtenhandler ruft die geerbte Methode auf, um die Standardbehandlung für die Nachricht wm_NCHitTest zu erhalten. Der If-Teil in der Prozedur fängt das Verhalten Ihres Fensters ab und ändert es. Dies ist, was tatsächlich passiert: Wenn das Betriebssystem zusammen mit den Mauskoordinaten eine wm_NCHitTest-Nachricht an das Fenster sendet, gibt das Fenster einen Code zurück, der angibt, welcher Teil von sich selbst getroffen wurde. Die wichtige Information für unsere Aufgabe liegt im Wert des Felds Msg.Result. Zu diesem Zeitpunkt haben wir die Möglichkeit, das Nachrichtenergebnis zu ändern.

Dies ist, was wir tun: Wenn der Benutzer in den Clientbereich des Formulars geklickt hat, lässt er Windows glauben, dass der Benutzer auf die Titelleiste geklickt hat. In Object Pascal „words“: Wenn der Nachrichtenrückgabewert HTCLIENT ist, ändern wir ihn einfach in HTCAPTION.

 

Keine Mausereignisse mehr

Durch Ändern des Standardverhaltens unserer Formulare entfernen wir die Möglichkeit von Windows, Sie zu benachrichtigen, wenn sich die Maus über dem Clientbereich befindet. Ein Nebeneffekt dieses Tricks ist, dass Ihr Formular keine Ereignisse mehr für Mausnachrichten generiert .

 

Bildunterschrift-Randloses Fenster

Wenn Sie ein randloses Fenster ohne Untertitel möchten, das einer schwebenden Symbolleiste ähnelt, setzen Sie die Beschriftung des Formulars auf eine leere Zeichenfolge, deaktivieren Sie alle BorderIcons und setzen Sie den BorderStyle auf bsNone.

Ein Formular kann auf verschiedene Arten geändert werden, indem benutzerdefinierter Code in der CreateParams-Methode angewendet wird.

 

Weitere WM_NCHitTest-Tricks

Wenn Sie sich die Nachricht wm_NCHitTest genauer ansehen, sehen Sie, dass der Rückgabewert der Funktion die Position des Cursor-Hotspots angibt. Dies ermöglicht es uns, mehr mit der Nachricht zu spielen, um seltsame Ergebnisse zu erzielen.

Das folgende Codefragment verhindert, dass Benutzer Ihre Formulare schließen, indem Sie auf die Schaltfläche Schließen klicken.


 wenn Msg.Result=htClose, dann Msg.Result:=htNowhere;

Wenn der Benutzer versucht, das Formular durch Klicken auf die Beschriftungsleiste und Ziehen zu verschieben, ersetzt der Code das Ergebnis der Nachricht durch ein Ergebnis, das angibt, dass der Benutzer auf den Clientbereich geklickt hat. Dies verhindert, dass der Benutzer das Fenster mit der Maus bewegt (im Gegensatz zu dem, was wir beim Betteln des Artikels getan haben).


 wenn Msg.Result=htCaption, dann Msg.Result:=htClient;

 

Komponenten auf einem Formular haben

In den meisten Fällen befinden sich einige Komponenten in einem Formular. Angenommen, ein Panel-Objekt befindet sich in einem Formular. Wenn die Align-Eigenschaft eines Bedienfelds auf alClient festgelegt ist, füllt das Bedienfeld den gesamten Clientbereich aus, sodass das übergeordnete Formular nicht durch Klicken ausgewählt werden kann. Der obige Code funktioniert nicht – warum? Dies liegt daran, dass sich die Maus
immer über die Panel-Komponente bewegt, nicht über das Formular.

Um unser Formular durch Ziehen eines Bedienfelds auf das Formular zu verschieben, müssen Sie in der OnMouseDown-Ereignisprozedur für die Bedienfeldkomponente einige Codezeilen hinzufügen:


 Prozedur TForm1.Panel1MouseDown

(Absender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);

Start

 

ReleaseCapture;

 

SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);

 

 Ende ;

Hinweis : Dieser Code funktioniert nicht mit Nicht-Fenster-Steuerelementen wie TLabel-Komponenten .

Similar Posts

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.