Az ablak áthelyezésének leggyakoribb módja az, hogy azt a címsoron húzza. Olvassa tovább, hogy megtudja, hogyan nyújthat húzási képességeket Delphi címsáv nélkül formázom, így a felhasználó az űrlapot áthelyezheti az ügyfélterület bárhová kattintásával.
Vegyük például a Windows alkalmazás amelynek nincs címsor, hogyan tudjuk mozgatni egy ilyen ablakot? Valójában létrehozhat ablakokat egy nem szabványos címsorral és akár nem téglalap alakú formákkal is. Ebben az esetben hogyan tudná a Windows, hogy hol vannak az ablak szegélyei és sarkai?
A WM_NCHitTest Windows üzenet
Az Windows operációs rendszer erősen alapul üzenetek kezelése. Például, amikor egy ablakra vagy a vezérlőelemre kattint, a Windows egy wm_LButtonDown üzenetet küld, további információkkal arról, hogy hol van az egér kurzor, és mely vezérlőgombok vannak jelenleg sajtolt. Ismerősen hangzik? Igen, ez nem más, mint egy OnMouseDown esemény Delphiben.
Hasonlóképpen, a Windows wm_NCHitTest üzenetet küld, amikor a egér esemény akkor fordul elő, amikor a kurzor mozog, vagy amikor egy egérgombot megnyomnak vagy elengednek.
Beviteli kód
Ha arra késztethetjük a Windows-t, hogy a felhasználó úgy húzza (rákattintott) a címsávra, mint az ügyfélterületre, akkor a ablakot az ügyfélterületre kattintva húzhatja. Ennek legegyszerűbb módja az, hogy "becsapja" a Windows-ot arra, hogy azt gondolja, hogy valójában egy űrlap címsorára kattint. Itt van, mit kell tennie:
1. Helyezze be a következő sort az űrlap „Privát nyilatkozatok” szakaszába (üzenetkezelési eljárásnyilatkozat):
eljárás WMNCHitTest (var Üzenet: TWMNCHitTest); üzenet WM_NCHitTest;
2. Adja hozzá az alábbi kódot az űrlap egységének "megvalósítása" szakaszához (ahol az 1. forma az feltételezett űrlap neve):
eljárás TForm1.WMNCHitTest (var Üzenet: TWMNCHitTest);
kezdődik
örökölt;
ha Msg. Eredmény = htClient azután Msg. Eredmény: = htCaption;
vég;
Az üzenetkezelő első kódja meghívja az örökölt módszert, hogy megkapja a wm_NCHitTest üzenet alapértelmezett kezelését. Az eljárás If része elfogja és megváltoztatja az ablak viselkedését. Valójában ez történik: amikor az operációs rendszer wm_NCHitTest üzenetet küld az ablakhoz, az egér koordinátáival együtt az ablak egy olyan kódot ad vissza, amely kijelenti, hogy melyik része van megütötte. A feladatunk szempontjából fontos információ az üzenet értéke. Eredménymező. Ezen a ponton lehetőségünk van az üzenet eredményének módosítására.
Ezt csináljuk: ha a felhasználó rákattintott az űrlap ügyfélterületére, arra készteti a Windows-ot, hogy úgy gondolja, hogy a felhasználó rákattintott a címsorra. Ban ben Object Pascal "szavak": ha az üzenet visszatérési értéke HTCLIENT, akkor azt egyszerűen HTCAPTION-ra változtatjuk.
Nincs több egéresemény
Az űrlapok alapértelmezett viselkedésének megváltoztatásával megszüntetjük a Windows azon képességét, hogy értesítse Önt, ha az egér az ügyfél területén van. Ennek a trükknek az egyik mellékhatása az, hogy az űrlapod már nem generálódik események egér üzenetek.
Felirat nélküli szegély nélküli ablak
Ha egy lebegő eszköztárhoz hasonló feliratozás nélküli szegély nélküli ablakot szeretne, állítsa az Űrlap feliratát üres karakterláncra, tiltsa le az összes BorderIcon-ot, és állítsa a BorderStyle-t bsNone értékre.
Az űrlap különféle módon megváltoztatható egyéni kód alkalmazásával a CreateParams módszerben.
További WM_NCHitTest trükkök
Ha alaposabban megvizsgálja a wm_NCHitTest üzenetet, látni fogja, hogy a függvény visszatérési értéke jelzi a kurzor forró pontjának helyzetét. Ez lehetővé teszi számunkra, hogy tovább játsszunk az üzenettel, hogy furcsa eredményeket hozzunk létre.
A következő kódrészlet megakadályozza, hogy a felhasználók bezárják az űrlapjait a Bezárás gombra kattintva.
ha Msg. Eredmény = htClose azután Msg. Eredmény: = htNowhere;
Ha a felhasználó megkísérel mozgatni az űrlapot a képaláír-sávra kattintással és húzással, akkor a kód az üzenet eredményét helyettesíti egy olyan eredménnyel, amely azt jelzi, hogy a felhasználó az ügyfél területére kattintott. Ez megakadályozza a felhasználót, hogy az ablakot az egérrel mozgatja (ellentétben azzal, amit a cikk elindításakor tettünk).
ha Msg. Eredmény = htCaption azután Msg. Eredmény: = htClient;
Alkatrészek birtoklása űrlapon
A legtöbb esetben van néhány összetevő az űrlapon. Tegyük fel például, hogy az egyik Panel objektum van egy űrlapon. Ha a panel Align tulajdonsága alClient értékre van állítva, akkor a panel kitölti az ügyfél teljes területét, így lehetetlen kiválasztani a szülő űrlapot rákattintással. A fenti kód nem fog működni - miért? Ennek oka az, hogy az egér mindig a Panel összetevő felett mozog, nem az űrlapon.
Az űrlap áthelyezéséhez egy panelt az űrlapon húzva hozzá kell adni néhány sor sort az OnMouseDown esemény eljárásához a Panel összetevőhöz:
eljárás TForm1.Panel1MouseDown
(Feladó: TObject; Gomb: TMouseButton;
Shift: TShiftState; X, Y: egész szám);
kezdődik
ReleaseCapture;
SendMessage (Form1Handle, WM_SYSCOMMAND, 61458, 0);
vég;
jegyzet: Ez a kód nem működik az ablakon kívüli vezérlőkkel, például TLabel alkatrészek.