Thứ Tư, 8 tháng 4, 2009

Di chuyển một cửa sổ mà không đụng đến thanh tiêu đề

Thông thường, bạn nhấn và giữ chuột trên thanh tiêu đề của một cửa sổ rồi kéo chuột để di chuyển cửa sổ đó. Trong VB6, bạn có thể viết những chương trình mà trong đó Form được di chuyển khi người dùng nhấn và kéo chuột ở bất kỳ vị trí nào trên Form chứ không nhất thiết phải là vị trí trên thanh tiêu đề. Điều này rất ích lợi trong một số trường hợp, chẳng hạn như khi bạn tạo một Form không có thanh tiêu đề (thuộc tính BorderStyle của Form là 0 - None), hoặc là tạo Form với hình dạng bất kỳ, bạn vẫn có thể di chuyển các Form đặc biệt này.

Làm thế nào để di chuyển một cửa số mà không đụng đến thanh tiêu đề của cửa sổ?

Hệ điều hành Windows sử dụng rất nhiều các thông điệp (Message). Mỗi khi có một sự kiện xảy ra (ví dụ như di chuyển chuột, nhấn phím, hay mở một cửa sổ…), thì một thông điệp được gửi đi. Mỗi giây, Windows gửi hàng ngàn thông điệp đến các cửa sổ. Bạn cũng có thể thay thế Windows gửi các thông điệp bằng cách dùng hàm API SendMessage. Hàm SendMessage được khai báo:

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Ý nghĩa các tham số của hàm SendMessage:
* hwnd: Xác định cửa sổ nhận thông điệp
* wMsg: Thông điệp được gửi đi
* wParam, lParam: Những thông tin bổ sung thêm cho thông điệp

Khi người dùng nhấn chuột ở một vị trí bất kỳ trong cửa sổ, bạn phải làm cho Windows “lầm tưởng” rằng chuột được nhấn ở trên thanh tiêu đề của cửa sổ. Để làm điều này, bạn dùng hàm SendMessage gửi cho Windows thông điệp WM_NCLBUTTONDOWN khi xảy ra sự kiện Form_MouseDown. Thông điệp WM_NCLBUTTONDOWN được Windows hiểu là chuột trái đang được nhấn ở vùng cửa sổ mà người dùng không thao tác trên đó (như là thanh tiêu đề, thanh thực đơn, thanh công cụ, thanh trạng thái, viền cửa sổ…). Trước khi gửi cho cửa sổ một thông điệp mới, bạn phải hủy bỏ thông điệp mà cửa sổ đã nhận được khi bạn vừa bắt đầu di chuyển chuột. Hàm API ReleaseCapture()giúp bạn làm điều này.


Thực hành

Bạn tạo một Project mới dạng Standard EXE. Bạn dùng API Text Viewer hoặc tự đánh vào để khai báo các hàm API SendMessage, ReleaseCapture và các hằng WM_NCLBUTTONDOW, HPCAPTION trong phần mã của biểu mẫu:

Option Explicit
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const HTCAPTION = 2
Tiếp theo là viết mã cho sự kiện Form_MouseDown:
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
ReleaseCapture
SendMessage Me.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0
End Sub

Xong xuôi, bạn nhấn Ctrl - F5 và thử nghiệm chương trình. Tuy không đụng đến thanh tiêu đề nhưng bạn vẫn có thể di chuyển cửa sổ phải không? Chúc bạn thành công!

Ngô Bảo Khoa
Thế giới @ số 100 ra ngày 5/1/2006

Không có nhận xét nào:

Đăng nhận xét