本帖最后由 ceoguang 于 2011-3-27 12:50 编辑
#cs
我来解释下楼主的代码进入死循环的原因.
默认情况下,窗口是不会产生WM_MOUSELEAVE消息的.
要接收此消息,必须在光标离开之前通过TrackMouseEvent来激活(RACKMOUSEEVENT结构里dwFlags成员设置为TME_LEAVE,TME_LEAVE = 2)。注:光标移动到控件上也会产生WM_MOUSELEAVE
激活后,一但光标离开窗口WM_MOUSELEAVE消息才会产生.
楼主的代码中,WM_MOUSEMOVE消息产生后激活了WM_MOUSELEAVE,此时WM_MOUSELEAVE消息并未产生.
但上面说到,光标移动到控件上也会产生WM_MOUSELEAVE。
若光标移动到控件,WM_MOUSELEAVE就会被发送到窗口,__wm_mouseleave函数开始工作,函数内又让光标回到窗口并持续移动,移动的过程中WM_MOUSEMOVE就已经工作,移动到最后的时候,光标又到了控件上.
WM_MOUSELEAVE再被发送........
最后附上在楼上代码上修改的消息跟踪代码
#ce
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <GuiConstantsEx.au3>
#include <winapi.au3>
Global $is_tracking = False
Global $iteration = 1
Global $sTrackMouseEvent = DllStructCreate('dword;dword;hwnd;dword')
Global $sTME_size = DllStructGetSize($sTrackMouseEvent)
Global $form1 = GUICreate('Form1', 400, 500, -1, 0, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
$hCallback = DllCallbackRegister("My_WindowProc", "int", "hWnd;uint;wparam;lparam")
$tCallback = DllCallbackGetPtr($hCallback)
$button = GUICtrlCreateButton("test", 100, 100)
$CallProc = _WinAPI_SetWindowLong(GUICtrlGetHandle(-1), -4, $tCallback)
DllStructSetData($sTrackMouseEvent, 1, $sTME_size)
DllStructSetData($sTrackMouseEvent, 2, 0x00000002)
DllStructSetData($sTrackMouseEvent, 3, $form1)
DllStructSetData($sTrackMouseEvent, 4, 0xFFFFFFFF)
Global $sTME_POINTER = DllStructGetPtr($sTrackMouseEvent)
GUISetState()
GUIRegisterMsg(0x0200, 'WM_MOUSEMOVE')
GUIRegisterMsg(0x02A3, '__wm_mouseleave')
While GUIGetMsg() <> -3
WEnd
GUIDelete()
Func WM_MOUSEMOVE($hWndGUI, $MsgID, $wParam, $lParam)
;If Not $is_tracking Then
; $is_tracking = True
;Local $win_pos = WinGetPos("Form1")
DllCall('user32.dll', 'bool', 'TrackMouseEvent', 'ptr', $sTME_POINTER) ; We're calling the tracking function
;ConsoleWrite('Starting tracking...' & $win_pos[1] & @CRLF)
;For $i = $win_pos[1] To $win_pos[3] Step 10
; ConsoleWrite($win_pos[1] & @CRLF)
; If $i >= 5 Then ExitLoop
; WinMove("Form1", "", $win_pos[0], $i, $win_pos[2], $win_pos[3])
; Sleep(10)
;Next
;ConsoleWrite($i)
;EndIf
Return "GUI_RUNDEFMSG"
EndFunc ;==>WM_MOUSEMOVE
Func __wm_mouseleave($hwnd, $msg, $wParam, $lParam)
;$is_tracking = False
;$iteration += 1
;Local $win_pos = WinGetPos("Form1")
;ConsoleWrite('YOUR MOUSE HAS JUST LEAVED YOUR GUI WINDOW FOR THE ' & $iteration & ' TIME!' & @CRLF)
;If $win_pos[1] >= 0 Then
; For $i = $win_pos[1] To $win_pos[3] - 5 Step 10
; ConsoleWrite($win_pos[1] & @CRLF)
; WinMove("Form1", "", $win_pos[0], -$i, $win_pos[2], $win_pos[3])
; Sleep(10)
; Next
; ConsoleWrite($i)
;EndIf
ConsoleWrite("__wm_mouseleave 0x" & Hex($Msg,6) &@LF)
Return "GUI_RUNDEFMSG"
EndFunc ;==>__wm_mouseleave
Func My_WindowProc($hwnd, $iMsg, $iwParam, $ilParam)
Switch $iMsg
Case 0x200;WM_MOUSEMOVE
Case 0x2A3;WM_MOUSELEAVE
ConsoleWrite("My_WindowProc 0x" & Hex($iMsg,6) &@LF)
Case 0x20;WM_SETCURSOR
EndSwitch
Return _WinAPI_CallWindowProc($CallProc, $hwnd, $iMsg, $iwParam, $ilParam)
EndFunc ;==>My_WindowProc
|