Klicken und ziehen Sie ein Delphi-Formular ohne Beschriftungsleiste

click fraud protection

Die häufigste Methode zum Verschieben eines Fensters besteht darin, es an der Titelleiste zu ziehen. Lesen Sie weiter, um herauszufinden, wie Sie Drag-Funktionen für bereitstellen können Delphi Formulare ohne Titelleiste, sodass der Benutzer ein Formular verschieben kann, indem er auf eine beliebige Stelle im Kundenbereich klickt.

Betrachten Sie zum Beispiel den Fall von a Windows-Anwendung das hat keine Titelleiste, 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 WM_NCHitTest Windows-Nachricht

Das Windows-Betriebssystem basiert stark auf Umgang mit 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 Steuertasten sich derzeit befinden gedrückt. Klingt vertraut? Ja, dies ist nichts weiter als ein OnMouseDown-Ereignis in Delphi.

instagram viewer

In ähnlicher Weise sendet Windows eine wm_NCHitTest-Nachricht, wenn a Mausereignis tritt auf, 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):

Verfahren WMNCHitTest (var Nachricht: TWMNCHitTest); Botschaft WM_NCHitTest; 

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

Verfahren TForm1.WMNCHitTest (var Nachricht: TWMNCHitTest);

Start

vererbt;

wenn Nachricht. Ergebnis = htClient dann Nachricht. Ergebnis: = 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 eine wm_NCHitTest-Nachricht an das Fenster sendet, Zusammen mit den Mauskoordinaten gibt das Fenster einen Code zurück, der angibt, welchen Teil von sich selbst hat wurde getroffen. Die wichtige Information für unsere Aufgabe ist der Wert der Nachricht. Ergebnisfeld. Zu diesem Zeitpunkt haben wir die Möglichkeit, das Nachrichtenergebnis zu ändern.

Dies tun wir: Wenn der Benutzer in den Clientbereich des Formulars geklickt hat, lässt er Windows glauben, dass der Benutzer auf die Titelleiste geklickt hat. Im Objekt 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 nicht mehr generiert wird Ereignisse für die Maus Mitteilungen.

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 Nachricht. Ergebnis = htClose dann Nachricht. Ergebnis: = 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 Nachricht. Ergebnis = htCaption dann Nachricht. Ergebnis: = 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:

Verfahren TForm1.Panel1MouseDown

(Absender: TObject; Schaltfläche: 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.

instagram story viewer