Arşiv Anasayfa Delphi ipuçları
Sayfalar: 1
Title bar olmadan "sürükle-bırak" Gönderen: Akrep Tarih: 18 January 2008 12:43:27
Windows işletim sistemi, ağırlıklı olarak mesaj yönetimi ve algılaması (message handling)  üzerine kuruludur. Bir pencere veya kontrol üzerinde fare ile tıkladığınızda Windows ona imlecin tam olarak nerede olduğunu ve hangi anahtara tıklandığını bildiren bir "wm_LButtonDown" mesajı gönderir.

Bu size tanıdık geldi mi? Evet bu "OnMouseDown" olayından başka birşey değildir.

Windows aynı şekilde kursor hareket ettiğinde yada farenin bir düğmesine basıldığında veya düğme serbest bırkıldığında "wm_NCHitTest" isminde bir mesaj gönderir.

Eğer Windows'u formumuzun başlık çubuğuna (tittle bar) tıklanarak sürükleme yapılmak istendiği yönünde kandırabilirsek, başlık çubuğuna değil de gövde üzerindeki herhangi bir yere tıklamış olsak dahi formda sürükle-bırak işlemi yapabiliriz. Bunu yaparak Windows'u kandırmanın en kolay yolu;

1- Aşağıdaki kodu formun "Private declarations" başlığı altında deklare edin.
 procedure WMNCHitTest(var Msg: TWMNCHitTest) ; message WM_NCHitTest;


2- Aşağıdaki kodu "implementation" başlığı altına yazın.
procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest) ;
begin
  inherited;
  if Msg.Result = htClient then Msg.Result := htCaption;
end;

Kodların ilk satırında "inherited" metoduyla, yordamın "wm_NCHitTest" mesajını elde etmek için varsayılan özellikleri çağrılıyor. Yordamın "if" bölümünde ise Windows'un bir davranışına müdahale edilederek değiştiriliyor. Daha açık bir ifadeyle, işletim sistemi pencereye fare imleci koordinatlarıyla birlikte bir "wm_NCHitTest " mesajı gönderdiğinde, pencere kendi üzerindeki hangi nesneye tıklandığını işletim sistemine geri bildiriyor. Yordamımızdaki en can alıcı kısım Msg.Result bölümüdür. Bu bölüm sayesinde işletim sistemine geri gönderilen mesajı değiştirme şansı yakalıyoruz.

Yukarıdaki yordam ile basitçe, gövde bölümüne tıklanmış olan bir formdan HTCLIENT şeklinde gitmesi gerekmekte olan mesajı HTCAPTION şeklinde değiştirerek  Windows'u yanılttık.

Tabi bu şekilde bir kullanımın yan etkisi olarak artık formun gövdesi üzerindeyken "Mouse events" yani fare ile ilgili olayların algılanmasını devre dışı bırakmış oluyoruz. Gövde üzerinde nereye tıklarsak tıklayalım Windows'a göre başlık çubuğu "tittle bar"a tıklamış sayılacağız.

Birkaç hile daha;

Formun X tuşuna basıldığında kapanmasını önlemek için yukarıdaki yordamın "if" bloğunu ;
if Msg.Result = htClose then Msg.Result := htNowhere;

şeklinde değiştirin.

Başlık çubuğuna tıklansa bile sürükle-bırak yapılamaması için;
if Msg.Result = htCaption then Msg.Result := htClient;

Örneğin sadece bir panele tıklanarak sürükle-bırak işleminin yapılabilmesi için;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
  SendMessage(Form1.Handle, WM_SYSCOMMAND, 61458, 0) ;
end;

Not: Yukarıdaki yordam, fokus alamayan ve windows handle özellikleri bulunmayan (non-windowed) kontrollerde çalışmaz. (örn. TLabel, TSpeedButton vs.)


Çeviri: Akrep
Orijinali: http://delphi.about.com/od/windowsshellapi/a/dragnocaption.htm