Bir pencereyi taşımanın en yaygın yolu, pencereyi başlık çubuğundan sürüklemektir. Sürükleme özelliklerini nasıl sağlayabileceğinizi öğrenmek için okumaya devam edin Delphi başlık çubuğu olmadan formlar, böylece kullanıcı istemci alanı üzerinde herhangi bir yere tıklayarak bir form taşıyabilirsiniz.
Örneğin, bir Windows uygulaması başlık çubuğu olmayan böyle bir pencereyi nasıl taşıyabiliriz? Aslında, standart olmayan bir başlık çubuğuna ve hatta dikdörtgen olmayan formlara sahip pencereler oluşturmak mümkündür. Bu durumda, Windows pencerenin kenarlarının ve köşelerinin nerede olduğunu nasıl bilebilir?
WM_NCHitTest Windows İletisi
Windows işletim sistemi ağırlıklı olarak mesajları işleme. Örneğin, bir pencereyi veya denetimi tıklattığınızda, Windows ona bir wm_LButtonDown iletisi gönderir, fare imlecinin nerede olduğu ve şu anda hangi kontrol tuşlarının bulunduğu hakkında ek bilgi bastırdı. Tanıdık geliyor? Evet, bu Delphi'deki bir OnMouseDown olayından başka bir şey değildir.
Benzer şekilde, Windows her zaman bir wm_NCHitTest iletisi gönderir
fare olayı yani, imleç hareket ettiğinde veya bir fare düğmesine basıldığında veya bırakıldığında meydana gelir.Girilecek Kod
Windows'un, istemci alanı yerine başlık çubuğunu sürüklediğini (tıkladığını) düşündürürsek, kullanıcı istemci alanını tıklatarak pencereyi sürükleyebilir. Bunu yapmanın en kolay yolu, Windows'u bir formun başlık çubuğuna tıkladığınızı düşünerek "kandırmak" tır. Yapmanız gerekenler:
1. Aşağıdaki satırı formunuzun "Özel bildirimler" bölümüne (ileti işleme prosedürü bildirimi) ekleyin:
prosedür WMNCHitTest (var Msg: TWMNCHitTest); İleti WM_NCHITTEST;
2. Formunuzun biriminin "uygulama" bölümüne aşağıdaki kodu ekleyin (burada Form1 varsayılan form adıdır):
prosedür TForm1.WMNCHitTest (var Msg: TWMNCHitTest);
başla
miras;
Eğer Msg. Sonuç = htClient sonra Msg. Sonuç: = htCaption;
son;
İleti işleyicisindeki ilk kod satırı, wm_NCHitTest iletisinin varsayılan işlemesini elde etmek için devralınan yöntemi çağırır. Yordamdaki If bölümü pencerenizin davranışını durdurur ve değiştirir. Aslında olan budur: işletim sistemi pencereye bir wm_NCHitTest mesajı gönderdiğinde, fare koordinatları ile birlikte, pencere hangi bölümünün bulunduğunu belirten bir kod döndürür vuruldu. Görevimiz için önemli bilgi parçası Msg'nin değerindedir. Sonuç alanı. Bu noktada, mesaj sonucunu değiştirme fırsatımız var.
Yaptığımız şey budur: kullanıcı formun istemci alanını tıkladıysa, Windows'un başlık çubuğunu tıkladığını düşünmesini sağlarız. İçinde Nesne Pascal "words": mesajın dönüş değeri HTCLIENT ise, sadece HTCAPTION olarak değiştiririz.
Fare Etkinliği Yok
Formlarımızın varsayılan davranışını değiştirerek, fare istemci alanının üzerindeyken Windows'un size bildirme yeteneğini kaldırırız. Bu hilenin bir yan etkisi, formunuzun artık üretmeyeceği fare için olaylar mesajlar.
Altyazısız Kenarlıksız Pencere
Kayan araç çubuğuna benzer bir resim yazısı olmayan kenarlıksız pencere istiyorsanız, Form'un Resim Yazısını boş bir dizeye ayarlayın, tüm BorderIcons'ları devre dışı bırakın ve BorderStyle'ı bsNone olarak ayarlayın.
Bir form, CreateParams yönteminde özel kod uygulanarak çeşitli şekillerde değiştirilebilir.
Diğer WM_NCHitTest Hileleri
Wm_NCHitTest iletisine daha dikkatli bakarsanız, işlevin dönüş değerinin imleç etkin noktasının konumunu gösterdiğini görürsünüz. Bu, garip sonuçlar oluşturmak için mesajla biraz daha oynamamızı sağlar.
Aşağıdaki kod parçası, Kapat düğmesini tıklatarak kullanıcıların formlarınızı kapatmasını önleyecektir.
Eğer Msg. Sonuç = htKapat sonra Msg. Sonuç: = htNowhere;
Kullanıcı, altyazı çubuğunu tıklatıp sürükleyerek formu taşımaya çalışıyorsa, kod iletinin sonucunu kullanıcının istemci alanını tıklattığını gösteren bir sonuçla değiştirir. Bu, kullanıcının pencereyi fareyle hareket ettirmesini önler (makalenin dilenmesinde yaptığımızın tersi).
Eğer Msg. Sonuç = htCaption sonra Msg. Sonuç: = htClient;
Formdaki Bileşenlere Sahip Olma
Çoğu durumda, bir form üzerinde bazı bileşenlerimiz olur. Diyelim ki bir Panel nesnesi bir form üzerinde. Panelin Hizala özelliği alClient olarak ayarlanırsa, Panel tüm istemci alanını doldurarak üst formu tıklatarak seçilemez hale gelir. Yukarıdaki kod çalışmaz - neden? Bunun nedeni, farenin form üzerinde değil Panel bileşeninin üzerinde hareket etmesidir.
Formumuzdaki bir paneli sürükleyerek formumuzu taşımak için Panel bileşeni için OnMouseDown olay yordamına birkaç satır kod eklememiz gerekir:
prosedür TForm1.Panel1MouseDown
(Gönderen: TObject; Düğme: TMouseButton;
Shift: TShiftState; X, Y: Tam sayı);
başla
ReleaseCapture;
SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);
son;
Not: Bu kod, aşağıdaki gibi pencere olmayan denetimlerle çalışmaz TLabel bileşenleri.