Faceți clic și glisați un formular Delphi fără bara de legendă

click fraud protection

Cel mai obișnuit mod de a muta o fereastră este să o trageți de bara de titlu. Citiți mai departe pentru a afla cum puteți oferi funcții de glisare pentru DelphFormularez fără o bară de titlu, astfel încât utilizatorul să poată muta un formular făcând clic oriunde pe zona clientului.

De exemplu, ia în considerare cazul a Aplicația Windows care nu are o bară de titlu, cum putem muta o astfel de fereastră? De fapt, este posibil să se creeze ferestre cu o bară de titlu non-standard și chiar forme ne-dreptunghiulare. În acest caz, cum ar putea Windows să știe unde se află marginile și colțurile ferestrei?

Mesajul Windows WM_NCHitTest

Sistem de operare Windows este puternic bazat pe manipularea mesajelor. De exemplu, când faceți clic pe o fereastră sau un control, Windows îi trimite un mesaj wm_LButtonDown, cu informații suplimentare despre locul în care se află cursorul mouse-ului și care sunt tastele de control în prezent presat. Sună cunoscut? Da, acesta nu este decât un eveniment OnMouseDown din Delphi.

instagram viewer

În mod similar, Windows trimite un mesaj wm_NCHitTest ori de câte ori a eveniment de mouse adică când cursorul se mișcă sau când este apăsat sau eliberat un buton de mouse.

Cod la intrare

Dacă putem face ca Windows să creadă că utilizatorul trage (a făcut clic pe) bara de titlu în loc de zona clientului, atunci utilizatorul ar putea trage fereastra făcând clic în zona clientului. Cel mai simplu mod de a face acest lucru este să „păcăliți” Windows în a crede că faceți clic pe bara de titlu a unui formular. Iată ce trebuie să faci:

1. Introduceți următoarea linie în secțiunea „Declarații private” din formularul dvs. (declarație privind procedura de gestionare a mesajelor):

procedură WMNCHitTest (var Msg: TWMNCHitTest); mesaj WM_NCHitTest; 

2. Adăugați următorul cod în secțiunea „implementare” a unității formularului dvs. (unde Form1 este numele formularului presupus):

procedură TForm1.WMNCHitTest (var Msg: TWMNCHitTest);

începe

mostenit;

dacă Msg. Rezultat = htClient apoi Msg. Rezultat: = htCaption;

Sfârșit; 

Prima linie de cod din handlerul de mesaje apelează la metoda moștenită pentru a obține gestionarea implicită pentru mesajul wm_NCHitTest. Partea If în procedură interceptează și schimbă comportamentul ferestrei. Acest lucru se întâmplă de fapt: când sistemul de operare trimite un mesaj wm_NCHitTest la fereastră, împreună cu coordonatele mouse-ului, fereastra returnează un cod care precizează ce porțiune de sine are a fost lovit. Informațiile importante, pentru sarcina noastră, sunt în valoarea Msg. Câmpul rezultat. În acest moment, avem posibilitatea de a modifica rezultatul mesajului.

Asta facem: dacă utilizatorul a făcut clic în zona clientului formularului, facem ca Windows să creadă că utilizatorul a făcut clic pe bara de titlu. În Obiect Pascal „cuvinte”: dacă valoarea returnării mesajului este HTCLIENT, o schimbăm pur și simplu la HTCAPTION.

Nu mai există evenimente pentru mouse

Modificând comportamentul implicit al formularelor noastre, eliminăm posibilitatea Windows-ului de a vă notifica atunci când mouse-ul este peste zona clientului. Un efect secundar al acestui truc este că forma dvs. nu va mai genera evenimente pentru mouse mesaje.

Fereastră fără margini

Dacă doriți o fereastră fără margini de legendă similară cu o bară de instrumente plutitoare, setați Legenda formularului pe un șir gol, dezactivați toate BorderIcons și setați BorderStyle pe bsNone.

Un formular poate fi modificat în diverse moduri prin aplicarea codului personalizat în metoda CreateParams.

Mai multe trucuri WM_NCHitTest

Dacă te uiți mai atent la mesajul wm_NCHitTest, vei vedea că valoarea returnată a funcției indică poziția punctului fierbinte al cursorului. Acest lucru ne permite să jucăm ceva mai mult cu mesajul pentru a crea rezultate ciudate.

Următorul fragment de cod va împiedica utilizatorii să vă închidă formularele făcând clic pe butonul Închidere.

dacă Msg. Rezultat = htÎnchide apoi Msg. Rezultat: = htUnaunde; 

Dacă utilizatorul încearcă să mute formularul făcând clic pe bara de subtitrare și glisând, codul înlocuiește rezultatul mesajului cu un rezultat care indică că utilizatorul a făcut clic pe zona clientului. Acest lucru împiedică utilizatorul să mute fereastra cu mouse-ul (opus celor făcute în cerșirea articolului).

dacă Msg. Rezultat = htCaption apoi Msg. Rezultat: = htClient; 

Având componente pe o formă

În cele mai multe cazuri, vom avea unele componente pe un formular. Să spunem, de exemplu, că un obiect al Panoului se află pe un formular. Dacă proprietatea Align a unui panou este setată pe alClient, Panoul umple întreaga zonă de client, astfel încât este imposibil să selectați formularul părinte făcând clic pe el. Codul de mai sus nu va funcționa - de ce? Se datorează faptului că mouse-ul se deplasează întotdeauna peste componenta Panoului, nu din formular.

Pentru a muta formularul prin glisarea unui panou pe formular, trebuie să adăugăm câteva linii de cod în procedura evenimentului OnMouseDown pentru componenta Panoul:

procedură TForm1.Panel1MouseDown

(Expeditor: TObject; Buton: TMouseButton;
Shift: TShiftState; X, Y: Integer);
începe

 ReleaseCapture;

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

Sfârșit; 

Notă: Acest cod nu va funcționa cu controale non-window, cum ar fi Componente TLabel.

instagram story viewer