Cara paling umum untuk memindahkan jendela adalah dengan menariknya melalui bilah judulnya. Baca terus untuk mengetahui bagaimana Anda dapat menyediakan kemampuan menyeret Delphsaya membentuk tanpa bilah judul, sehingga pengguna dapat memindahkan formulir dengan mengklik di mana saja di area klien.
Misalnya, perhatikan kasus a Aplikasi Windows yang tidak memiliki bilah judul, bagaimana kita bisa memindahkan jendela seperti itu? Bahkan, dimungkinkan untuk membuat jendela dengan bilah judul tidak standar dan bahkan bentuk non-persegi panjang. Dalam hal ini, bagaimana Windows bisa tahu di mana perbatasan dan sudut-sudut jendela?
Pesan Windows WM_NCHitTest
Itu Sistem operasi Windows sangat didasarkan pada menangani pesan. Misalnya, ketika Anda mengklik pada jendela atau kontrol, Windows mengirimkannya pesan wm_LButtonDown, dengan informasi tambahan tentang di mana kursor mouse berada dan tombol kontrol mana yang saat ini ditekan. Kedengarannya asing? Ya, ini tidak lebih dari acara OnMouseDown di Delphi.
Demikian pula, Windows mengirim pesan wm_NCHitTest setiap kali a acara mouse terjadi, yaitu ketika kursor bergerak, atau ketika tombol mouse ditekan atau dilepaskan.
Kode untuk Input
Jika kita dapat membuat Windows berpikir bahwa pengguna menyeret (telah mengklik) bilah judul daripada area klien, maka pengguna dapat menyeret jendela dengan mengklik di area klien. Cara termudah untuk melakukan ini adalah "membodohi" Windows dengan berpikir bahwa Anda benar-benar mengklik bilah judul formulir. Inilah yang harus Anda lakukan:
1. Masukkan baris berikut ke bagian "Pernyataan pribadi" formulir Anda (deklarasi prosedur penanganan pesan):
prosedur WMNCHitTest (var Msg: TWMNCHitTest); pesan WM_NCHitTest;
2. Tambahkan kode berikut ke bagian "implementasi" dari unit formulir Anda (di mana Form1 adalah nama formulir yang diasumsikan):
prosedur TForm1.WMNCHitTest (var Msg: TWMNCHitTest);
mulai
mewarisi;
jika Msg. Hasil = htClient kemudian Msg. Hasil: = htCaption;
akhir;
Baris kode pertama dalam penangan pesan memanggil metode yang diwarisi untuk mendapatkan penanganan default untuk pesan wm_NCHitTest. Bagian Jika dalam prosedur memotong dan mengubah perilaku jendela Anda. Inilah yang sebenarnya terjadi: ketika sistem operasi mengirim pesan wm_NCHitTest ke jendela, bersama dengan koordinat tetikus, jendela mengembalikan kode yang menyatakan bagian mana dari yang dimilikinya dipukul. Sepotong informasi penting, untuk tugas kita, adalah nilai Msg. Bidang hasil. Pada titik ini, kami memiliki kesempatan untuk mengubah hasil pesan.
Inilah yang kami lakukan: jika pengguna telah mengklik area klien formulir, kami membuat Windows berpikir bahwa pengguna mengklik bilah judul. Di Obyek Pascal "words": jika nilai pengembalian pesan adalah HTCLIENT, kami cukup mengubahnya ke HTCAPTION.
Tidak Ada Lagi Acara Mouse
Dengan mengubah perilaku default formulir kami, kami menghapus kemampuan Windows untuk memberi tahu Anda ketika mouse melewati area klien. Salah satu efek samping dari trik ini adalah bentuk Anda tidak akan lagi menghasilkan acara untuk mouse pesan.
Jendela Tanpa Teks Tanpa Batas
Jika Anda ingin jendela tanpa batas tanpa teks yang mirip dengan bilah alat mengambang, atur Keterangan Bentuk ke string kosong, nonaktifkan semua BorderIcons, dan atur BorderStyle ke bsNone.
Formulir dapat diubah dengan berbagai cara dengan menerapkan kode khusus dalam metode CreateParams.
Lebih Banyak Trik WM_NCHitTest
Jika Anda melihat lebih hati-hati pada pesan wm_NCHitTest Anda akan melihat bahwa nilai pengembalian fungsi menunjukkan posisi hot spot kursor. Ini memungkinkan kami untuk bermain lebih banyak dengan pesan untuk menciptakan hasil yang aneh.
Fragmen kode berikut akan mencegah pengguna untuk menutup formulir Anda dengan mengklik tombol Tutup.
jika Msg. Hasil = htClose kemudian Msg. Hasil: = htNowhere;
Jika pengguna mencoba untuk memindahkan formulir dengan mengklik bilah judul dan menyeret, kode tersebut menggantikan hasil pesan dengan hasil yang menunjukkan pengguna mengklik pada area klien. Ini mencegah pengguna untuk menggerakkan jendela dengan mouse (berlawanan dengan apa yang kami lakukan di mengemis artikel).
jika Msg. Hasil = htCaption kemudian Msg. Hasil: = htClient;
Memiliki Komponen Pada Formulir
Dalam kebanyakan kasus, kami akan memiliki beberapa komponen pada formulir. Katakanlah, misalnya, bahwa satu objek Panel ada di formulir. Jika properti Align panel diatur ke alClient, Panel mengisi seluruh area klien sehingga tidak mungkin untuk memilih formulir induk dengan mengkliknya. Kode di atas tidak akan berfungsi - mengapa? Itu karena mouse selalu bergerak di atas komponen Panel, bukan form.
Untuk memindahkan formulir kami dengan menyeret panel pada formulir, kami harus menambahkan beberapa baris kode di prosedur acara OnMouseDown untuk komponen Panel:
prosedur TForm1.Panel1MouseDown
(Pengirim: TObject; Tombol: TMouseButton;
Shift: TShiftState; X, Y: Integer);
mulai
ReleaseCapture;
SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);
akhir;
Catatan: Kode ini tidak akan berfungsi dengan kontrol non-jendela seperti Komponen TLabel.