Kliknij i przeciągnij formularz Delphi bez paska napisów

Najczęstszym sposobem przenoszenia okna jest przeciąganie go za pasek tytułu. Czytaj dalej, aby dowiedzieć się, w jaki sposób możesz zapewnić możliwości przeciągania DelphFormularze bez paska tytułu, aby użytkownik mógł przenieść formularz, klikając dowolne miejsce w obszarze klienta.

Na przykład rozważmy przypadek a Aplikacja Windows który nie ma paska tytułu, jak możemy przenieść takie okno? W rzeczywistości możliwe jest tworzenie okien z niestandardowym paskiem tytułu, a nawet formami nie prostokątnymi. W takim przypadku, skąd Windows może wiedzieć, gdzie są granice i rogi okna?

Komunikat Windows WM_NCHitTest

The System operacyjny Windows jest w dużej mierze oparty na obsługa wiadomości. Na przykład po kliknięciu okna lub kontrolki system Windows wysyła mu komunikat wm_LButtonDown, z dodatkowymi informacjami o tym, gdzie znajduje się kursor myszy i jakie klawisze sterujące są obecnie prasowany. Brzmi znajomo? Tak, to nic innego jak wydarzenie OnMouseDown w Delphi.

Podobnie system Windows wysyła komunikat wm_NCHitTest za każdym razem, gdy

instagram viewer
zdarzenie myszy występuje, gdy porusza się kursor lub gdy przycisk myszy jest naciśnięty lub zwolniony.

Kod do wprowadzenia

Jeśli możemy sprawić, że system Windows pomyśli, że użytkownik przeciąga (kliknął) pasek tytułu, a nie obszar klienta, użytkownik może przeciągnąć okno, klikając obszar klienta. Najłatwiej to zrobić, „oszukując” system Windows, aby pomyślał, że faktycznie klikasz pasek tytułowy formularza. Oto, co musisz zrobić:

1. Wstaw następujący wiersz do sekcji „Prywatne deklaracje” formularza (deklaracja procedury obsługi wiadomości):

procedura WMNCHitTest (var Msg: TWMNCHitTest); wiadomość WM_NCHitTest; 

2. Dodaj następujący kod do sekcji „Implementacja” jednostki formularza (gdzie Form1 to nazwa założonego formularza):

procedura TForm1.WMNCHitTest (var Msg: TWMNCHitTest);

zaczynać

dziedziczny;

gdyby Msg. Wynik = htClient następnie Msg. Wynik: = htCaption;

koniec; 

Pierwszy wiersz kodu w module obsługi komunikatów wywołuje odziedziczoną metodę w celu uzyskania domyślnej obsługi komunikatu wm_NCHitTest. Część If w procedurze przechwytuje i zmienia zachowanie twojego okna. Tak właśnie się dzieje: gdy system operacyjny wysyła komunikat wm_NCHitTest do okna, wraz ze współrzędnymi myszy okno zwraca kod określający, która jego część ma został trafiony. Ważną informacją dla naszego zadania jest wartość Msg. Pole wyniku. W tym momencie mamy możliwość zmodyfikowania wyniku wiadomości.

Oto co robimy: jeśli użytkownik kliknął w obszarze klienta formularza, sprawiamy, że Windows pomyśli, że kliknął na pasku tytułu. W Obiekt Pascal „słowa”: jeśli wartością zwracaną wiadomości jest HTCLIENT, po prostu zmieniamy ją na HTCAPTION.

Nigdy więcej zdarzeń myszy

Zmieniając domyślne zachowanie naszych formularzy, usuwamy zdolność systemu Windows do powiadamiania Cię, gdy mysz znajdzie się nad obszarem klienta. Jednym z efektów ubocznych tej sztuczki jest to, że formularz nie będzie już generowany wydarzenia dla myszy wiadomości.

Okno bez napisów

Jeśli chcesz okno bez napisów bez obramowania podobne do pływającego paska narzędzi, ustaw Tytuł formularza na pusty ciąg, wyłącz wszystkie BorderIcons i ustaw BorderStyle na bsNone.

Formularz można zmienić na różne sposoby, stosując niestandardowy kod w metodzie CreateParams.

Więcej sztuczek WM_NCHitTest

Jeśli przyjrzysz się uważniej komunikatowi wm_NCHitTest, zobaczysz, że zwracana wartość funkcji wskazuje pozycję punktu aktywnego kursora. To pozwala nam zagrać trochę więcej z wiadomością, aby uzyskać dziwne wyniki.

Poniższy fragment kodu uniemożliwi użytkownikom zamknięcie formularzy przez kliknięcie przycisku Zamknij.

gdyby Msg. Wynik = htClose następnie Msg. Wynik: = htNowhere; 

Jeśli użytkownik próbuje przenieść formularz, klikając pasek podpisu i przeciągając, kod zastępuje wynik wiadomości wynikiem, który wskazuje, że użytkownik kliknął obszar klienta. Zapobiega to przesuwaniu okna za pomocą myszy (w przeciwieństwie do tego, co robiliśmy na początku artykułu).

gdyby Msg. Wynik = htCaption następnie Msg. Wynik: = htClient; 

Posiadanie komponentów na formularzu

W większości przypadków będziemy mieć pewne składniki w formularzu. Powiedzmy na przykład, że jeden obiekt panelu znajduje się w formularzu. Jeśli właściwość Align panelu jest ustawiona na alClient, panel wypełnia cały obszar klienta, tak że nie można wybrać formularza nadrzędnego poprzez kliknięcie go. Powyższy kod nie zadziała - dlaczego? To dlatego, że mysz zawsze przesuwa się po komponencie Panel, a nie w formie.

Aby przenieść nasz formularz poprzez przeciągnięcie panelu na formularz, musimy dodać kilka wierszy kodu w procedurze zdarzenia OnMouseDown dla komponentu Panel:

procedura TForm1.Panel1MouseDown

(Nadawca: TObject; Przycisk: TMouseButton;
Shift: TShiftState; X, Y: liczba całkowita);
zaczynać

 ReleaseCapture;

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

koniec; 

Uwaga: Ten kod nie działa z kontrolkami innymi niż okno, takimi jak Komponenty TLabel.