Den mest almindelige måde at flytte et vindue på er at trække det ved dens titellinje. Læs videre for at finde ud af, hvordan du kan levere trækfunktioner til Delphi formularer uden en titellinje, så brugeren kan flytte en formular ved at klikke hvor som helst på klientområdet.
Overvej for eksempel sagen om a Windows-applikation der ikke har en titellinje, hvordan kan vi flytte et sådant vindue? Det er faktisk muligt at oprette vinduer med en ikke-standard titellinje og endda ikke-rektangulære former. I dette tilfælde, hvordan kunne Windows vide, hvor grænserne og hjørnerne af vinduet er?
WM_NCHitTest Windows-meddelelsen
Det Windows-operativsystem er stærkt baseret på håndtering af beskeder. Når du f.eks. Klikker på et vindue eller en kontrol, sender Windows det en wm_LButtonDown-meddelelse, med yderligere oplysninger om hvor musemarkøren er, og hvilke kontroltaster der i øjeblikket er trykket. Lyder det velkendt? Ja, dette er intet andet end en OnMouseDown begivenhed i Delphi.
Tilsvarende sender Windows en wm_NCHitTest-meddelelse, hver gang a
mus begivenhed forekommer, det vil sige, når markøren bevæger sig, eller når der trykkes på en museknap eller frigøres.Kode, der skal indtastes
Hvis vi kan få Windows til at tro, at brugeren trækker (har klikket på) titellinjen i stedet for klientområdet, kan brugeren trække vinduet ved at klikke i klientområdet. Den nemmeste måde at gøre dette på er at "narre" Windows til at tro, at du faktisk klikker på titellinjen på en formular. Her er hvad du skal gøre:
1. Indsæt følgende linje i din formular sektion "Privat erklæringer" (erklæring om meddelelseshåndteringsprocedure):
procedure WMNCHitTest (Var Msg: TWMNCHitTest); besked WM_NCHitTest;
2. Tilføj følgende kode i afsnittet "implementering" på din formularenhed (hvor Form1 er det formodede formularnavn):
procedure TForm1.WMNCHitTest (Var Msg: TWMNCHitTest);
begynde
arvet;
hvis Msg. Resultat = htClient derefter Msg. Resultat: = htCaption;
ende;
Den første kodelinie i meddelelsesbehandleren kalder den arvelige metode til at få standardhåndtering for wm_NCHitTest-meddelelsen. If-delen i proceduren aflytter og ændrer dit vindues opførsel. Dette er hvad der faktisk sker: når operativsystemet sender en wm_NCHitTest-meddelelse til vinduet, sammen med musekoordinaterne returnerer vinduet en kode, der angiver, hvilken del af sig selv der har blevet ramt. Det vigtige stykke information til vores opgave er i værdien af Msg. Resultatfelt. På dette tidspunkt har vi en mulighed for at ændre meddelelsesresultatet.
Dette gør vi: Hvis brugeren har klikket på formularens klientområde, får vi Windows til at tro, at brugeren har klikket på titellinjen. I Objekt Pascal "ord": Hvis værdien af meddelelsesretur er HTCLIENT, ændrer vi den simpelthen til HTCAPTION.
Ingen flere musbegivenheder
Ved at ændre standardopførselen på vores formularer fjerner vi Windows 'evne til at underrette dig, når musen er over klientområdet. En bivirkning af dette trick er, at din form ikke længere genererer begivenheder for mus Beskeder.
Vindue uden billedtekst uden grænser
Hvis du vil have et billedfrit vindue uden billedtekst, der ligner en flydende værktøjslinje, skal du indstille formularens billedtekst til en tom streng, deaktivere alle grænseikoner og indstille BorderStyle til bsNone.
En form kan ændres på forskellige måder ved at anvende tilpasset kode i CreateParams-metoden.
Flere WM_NCHitTest-tricks
Hvis du ser mere omhyggeligt på wm_NCHitTest-meddelelsen, vil du se, at funktionens returværdi angiver placeringen af markørens hotspot. Dette gør det muligt for os at spille lidt mere med beskeden for at skabe underlige resultater.
Følgende kodefragment forhindrer brugere i at lukke dine formularer ved at klikke på knappen Luk.
hvis Msg. Resultat = htLuk derefter Msg. Resultat: = htNowhere;
Hvis brugeren forsøger at flytte formularen ved at klikke på billedtekstlinjen og trække, erstatter koden resultatet af meddelelsen med et resultat, der angiver, at brugeren har klikket på klientområdet. Dette forhindrer brugeren i at bevæge vinduet med musen (modsat hvad vi gjorde i tiggeriet til artiklen).
hvis Msg. Resultat = htCaption derefter Msg. Resultat: = htClient;
At have komponenter på en form
I de fleste tilfælde har vi nogle komponenter på en formular. Lad os sige, for eksempel, at et panelobjekt er på en formular. Hvis egenskaben Juster på et panel er indstillet til alClient, udfylder panelet hele klientområdet, så det er umuligt at vælge den overordnede form ved at klikke på den. Koden ovenfor fungerer ikke - hvorfor? Det skyldes, at musen altid bevæger sig over panelkomponenten, ikke formen.
For at flytte vores form ved at trække et panel på formularen skal vi tilføje et par kodelinjer i OnMouseDown-hændelsesproceduren for panelkomponenten:
procedure TForm1.Panel1MouseDown
(Afsender: TObject; Knap: TMouseButton;
Skift: TShiftState; X, Y: heltal);
begynde
ReleaseCapture;
SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);
ende;
Bemærk: Denne kode fungerer ikke med ikke-vindueskontroller som TLabel-komponenter.