Di chuyển Form không cần thanh Caption
Như các bạn đã biết thông thường chúng ta di chuyển một cửa
sổ bằng cách kích chuột vào thanh tiêu đề caption và nắm kéo. Nếu cửa sổ không
có thanh tiêu đề ví dụ bạn tạo GUI với style là POPUP chẳng hạn thì sao? Hôm
nay mình sẽ hướng dẫn các bạn cách để di chuyển một cửa sổ mà không cần đến
thanh Caption bất kể cửa sổ đó có thanh Caption hay không :) Let’s go!
Cách 1: Sử dụng style: $GUI_WS_EX_PARENTDRAG
Tư duy của phương pháp này như sau: Tại những nơi mà bạn muốn
có thể kéo thả được thì bạn chỉ cần áp cho nó style: $GUI_WS_EX_PARENTDRAG. Áp
dụng style này với các đối tượng như Label, hoặc Picture. Khi đó khi bạn kích
và giữ chuột ở những vị trí này bạn sẽ có thể di chuyển Form như khi bạn kích
vào thanh Caption.
Bạn xem ví dụ sau:
#include <GuiconstantsEx.au3>
#include <WindowsConstants.au3>
HotKeySet("{ESC}", "On_Exit")
$hGUI = GUICreate("X", 100, 100, -1, -1, $WS_POPUP)
GUISetBkColor(0xFF0000, $hGUI)
$hLabel = GUICtrlCreateLabel("", 0, 0, 100, 50, -1, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetBkColor(-1, 0x00FF00)
;GUICtrlSetState(-1, $GUI_DISABLE)
$hButton = GUICtrlCreateButton("Test", 10, 35, 80, 30)
GUISetState()
While 1
Switch GUIGetMsg()
Case $hButton
On_Button()
EndSwitch
WEnd
Func On_Button()
MsgBox(0, "Hi", "Button Pressed")
EndFunc ;==>On_Button
Func On_Exit()
Exit
EndFunc ;==>On_Exit
Cách 2: Trả về kết quả $SC_DRAGMOVE lại cho windows
Ở đây chúng ta sẽ gửi lại cho windows 1 thông điệp khi mà chuột được nhấn giữ để thay đổi vị trí windows khi mà ta kéo chuột di chuyển. Ưu điểm của cách này là bạn có thể nhấn giữ chuột và thay đổi vị trí windows tại vị trí bất kỳ trên Form. Và theo mình đây cũng là cách nhanh nhất nhé! Tuy nhiên hằng số sử dụng trong này là số hexa: $F012 là một điểm rất đặc biệt đây là một hằng số không công bố trong bất cứ tài liệu nào của Microsoft trong các thư viện win32API và cũng chẳng ai hiểu được tại sao nó lại có tác dụng như vậy! :))
Code mẫu:
; Original code - martin #include <GuiconstantsEx.au3> #include <WindowsConstants.au3> #include <SendMessage.au3> Global Const $SC_DRAGMOVE = 0xF012 HotKeySet("{ESC}", "On_Exit") $hGUI = GUICreate("X", 100, 100, -1, -1, $WS_POPUP) GUISetBkColor(0x00FF00, $hGUI) $hButton = GUICtrlCreateButton("Test", 10, 35, 80, 30) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_PRIMARYDOWN _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0) Case $hButton On_Button() EndSwitch WEnd Func On_Button() MsgBox(0, "Hi", "Button Pressed") EndFunc ;==>On_Button Func On_Exit() Exit EndFunc ;==>On_Exit
Cách 3: Gửi thông điệp: $WM_NCLBUTTONDOWN
Trong cách này chúng ta sẽ phát hiện khi nào mà chuột trái được nhấn và chúng ta sẽ gửi lại thông điệp cho windows $WM_NCLBUTTONDOWN khiến cho widows nhầm tưởng rằng con trỏ chuột đang ở vị trí thanh Caption và sẽ di chuyển cửa sổ windows!
Code mẫu:
#include <GuiconstantsEx.au3> #include <WindowsConstants.au3> #include <SendMessage.au3> HotKeySet("{ESC}", "On_Exit") $hGUI = GUICreate("X", 100, 100, -1, -1, $WS_POPUP) GUISetBkColor(0x00FF00, $hGUI) $hButton = GUICtrlCreateButton("Test", 10, 35, 80, 30) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_PRIMARYDOWN On_Drag() Case $hButton On_Button() EndSwitch WEnd Func On_Drag() Local $aCurInfo = GUIGetCursorInfo($hGUI) If $aCurInfo[4] = 0 Then ; Mouse not over a control DllCall("user32.dll", "int", "ReleaseCapture") _SendMessage($hGUI, $WM_NCLBUTTONDOWN, $HTCAPTION, 0) EndIf EndFunc ;==>On_Drag Func On_Exit() Exit EndFunc ;==>On_Exit Func On_Button() MsgBox(0, "Hi", "Button Pressed") EndFunc ;==>On_Button
Cách 4: Gửi cho windows thông điệp: $WM_NCHITTEST
Như bạn đã biết khi chuột di chuyển vào các vị trí đặc biệt như trên caption, trên menu, trên nút nhấn min, max, close... Windows gửi thông điệp $WM_NCHITTEST để ta kiểm tra và xử lý. Nếu bạn kích chuột trái vào một điểm bất kì trên Form, đón bắt thông điệp $WM_NCHITTEST và trả về kết quả $HTCAPTION Windows sẽ lầm tưởng là bạn đang nắm chuột vào thanh tiêu đề caption cho nên sẽ tự động di chuyển Form theo ý của bạn. Trong code mẫu này có đoạn kiểm tra xem vị trí con trỏ chuột có đang nhỏ hơn 50 pixels nếu có thì sẽ trả về thông điệp $HTCAPTION nếu bạn muốn di chuyển ở vị trí nào cũng được thì hãy bỏ đoạn check này đi nhé!
Code mẫu:
#include <GuiconstantsEx.au3> #include <WindowsConstants.au3> #include <SendMessage.au3> HotKeySet("{ESC}", "On_Exit") $hGUI = GUICreate("X", 100, 100, -1, -1, $WS_POPUP) GUISetBkColor(0x00FF00, $hGUI) GUICtrlCreateLabel("", 0, 50, 100, 50) GUICtrlSetBkColor(-1, 0xFF0000) GUICtrlSetState(-1, $GUI_DISABLE) $hButton = GUICtrlCreateButton("Test", 10, 35, 80, 30) GUISetState() GUIRegisterMsg($WM_NCHITTEST, "_MY_NCHITTEST") While 1 Switch GUIGetMsg() Case $hButton On_Button() EndSwitch WEnd ; Original code - Prog@ndy Func _MY_NCHITTEST($hWnd, $uMsg, $wParam, $lParam) Switch $hWnd Case $hGUI Local $aPos = WinGetPos($hWnd) ; Check if mouse is over top 50 pixels If Abs(BitAND(BitShift($lParam, 16), 0xFFFF) - $aPos[1]) < 50 Then Return $HTCAPTION EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_MY_NCHITTEST Func On_Button() MsgBox(0, "Hi", "Button Pressed") EndFunc ;==>On_Button Func On_Exit() Exit EndFunc ;==>On_Exit
Trên đây là những kinh nhiệm mà mình thấy hay và mong muốn nó sẽ giúp ích cho các bạn!
Nguồn: https://www.autoitscript.com/wiki/Moving_and_Resizing_PopUp_GUIs
Pass giải nén(nếu có) :http://nothing1010.blogspot.comLưu ý với các bạn là blog của mình sử dụng WinRar 5 để nén nên các bạn phải dùng WinRar5 để giải nén nhé! Nếu bạn nào chưa có thì có thể vào ĐÂY để tải và cài đặt bản mới nhất nhé!
cảm ơn bạn
ReplyDelete