pusofalse
发表于 2010-7-27 17:48:15
本帖最后由 pusofalse 于 2010-7-27 17:50 编辑
肯定是鼠标单击在前的,否则通过HOOK鼠标消息没什么意义。#include <WinAPI.au3>
#include <WindowsConstants.au3>
Global $hForeground
$hGUI = GUICreate("Test", 400, 300, -1, -1, Default, $WS_EX_TOPMOST)
GUICtrlCreateButton("Send ""a""", 40, 40, 150, 20)
GUICtrlSetCursor(-1, 0)
$hButton = GUICtrlGetHandle(-1)
$iThreadId = _WinAPI_GetCurrentThreadId()
$hInstance = _WinAPI_GetModuleHandle(0)
$hCBTProc = DllCallBackRegister("_CBTCallBack", "int", "uint;wparam;lparam")
$pCBTProc = DllCallBackGetPtr($hCBTProc)
$hCBTHook = _WinAPI_SetWindowsHookEx(5, $pCBTProc, $hInstance, $iThreadId)
$hMouseProc = DllCallBackRegister("_MouseProc", "int", "uint;wparam;lparam")
$pMouseProc = DllCallBackGetPtr($hMouseProc)
$hMouseHook = _WinAPI_SetWindowsHookEx(14, $pMouseProc, $hInstance, 0)
$hEventProc = DllCallBackRegister("_EventProc", "none", "ptr;dword;hWnd;long;long;dword;dword")
$pEventProc = DllCallBackGetPtr($hEventProc)
$hEventHook = _SetWinEventHook($pEventProc, 1)
GUISetState()
While GUIGetMsg() + 3
WEnd
GUIDelete($hGUI)
_WinAPI_UnhookWindowsHookEx($hCBTHook)
_WinAPI_UnhookWindowsHookEx($hMouseHook)
_UnhookWinEvent($hEventHook)
DllCallBackFree($hCBTProc)
DllCallBackFree($hMouseProc)
DllCallBackFree($hEventProc)
Func _CBTCallBack($iCode, $iwParam, $ilParam)
Switch $iCode
Case 5
If HWnd($iwParam) = $hGUI Then Return 1
EndSwitch
Return _WinAPI_CallNextHookEx($hCBTHook, $iCode, $iwParam, $ilParam)
EndFunc ;==>_CBTCallBack
Func _EventProc($hEventHook, $iEvent, $hWnd, $iObject, $iChild, $iEventThread, $iEventTime)
If ($iEvent = 0x8005) Then $hForeground = $hWnd
EndFunc ;==>_EventProc
Func _MouseProc($iCode, $iwParam, $ilParam)
If ($iCode < 0) Then
Return _WinAPI_CallNextHookEx($hMouseHook, $iCode, $iwParam, $ilParam)
EndIf
Switch $iwParam
Case $WM_LBUTTONDOWN, $WM_LBUTTONUP, $WM_RBUTTONDOWN, $WM_RBUTTONUP, $WM_MBUTTONDOWN, $WM_MBUTTONUP
Local $tBuffer, $hWindow
$tBuffer = DllStructCreate("int X;int Y", $ilParam)
$hWindow = _WinAPI_WindowFromPoint($tBuffer)
$tBuffer = 0
Switch $hWindow
Case $hGUI
Return 1
Case $hButton
If ($iwParam = $WM_LBUTTONUP) Then Send("a")
Return 1
EndSwitch
EndSwitch
Return _WinAPI_CallNextHookEx($hMouseHook, $iCode, $iwParam, $ilParam)
EndFunc ;==>_MouseProc
Func _SetWinEventHook($pCallBack, $iFlags, $iEventMin = 1, $iEventMax = 0x7FFFFFFF, $iProcessId = 0, $iThreadId = 0)
Local $iResult
$iResult = DllCall("User32.dll", "ptr", "SetWinEventHook", "uint", $iEventMin, _
"uint", $iEventMax, "ptr", 0, "ptr", $pCallBack, "dword", $iProcessId, _
"dword", $iThreadId, "uint", $iFlags)
Return $iResult
EndFunc ;==>_SetWinEventHook
Func _UnhookWinEvent($hEventHook)
Local $iResult
$iResult = DllCall("User32.dll", "int", "UnhookWinEvent", "ptr", $hEventHook)
Return $iResult
EndFunc ;==>_UnhookWinEvent
afan
发表于 2010-7-27 17:51:46
肯定是鼠标单击在前的,否则通过HOOK鼠标消息没什么意义。
pusofalse 发表于 2010-7-27 17:48 http://www.autoitx.com/images/common/back.gif
强大极了~!我就知道这对于P版来说只是小菜~~{:face (301):}
afan
发表于 2010-7-27 18:47:16
回复 16# pusofalse
我这3.3.6.1似乎无法退出,请P版再看看~
pusofalse
发表于 2010-7-27 19:02:22
回复 18# afan
我现在在用3.3.5.1,没遇到这样的问题。以前在用低版本的au3时,会出现如你所说的不能正常退出的情况,退出时会卡住,并且狂占CPU,我测试了多次,终于发现,对于带GUI界面的程序,如果代码中调用了DllCallBackRegister函数,在退出时必须先GUIDelete、DllCallBackFree才可以,上面的代码就是这样做的。
这是以前在用低版本时遇到的问题,但不知在高版本中也会出现如此情况,我不知道到底怎样做才能彻底解决这个问题,以前没弄明白原因时,总是在紧接着While GUIGetMsg()主循环之后加一句Opt("TrayIconHide", 1)、ProcessClose(@AutoItPid)来强制结束自身进程。如果不在意的话,可以使用这种方法退出。 - -|||
我再看一下。
afan
发表于 2010-7-27 19:07:14
回复 19# pusofalse
我这测试点击关闭按钮后主循环并未退出,难道GUIGetMsg()也被拦截了?
3mile
发表于 2010-7-27 19:07:36
P大厉害,佩服之极。
pusofalse
发表于 2010-7-27 19:14:14
回复 20# afan
在GUI主界面上点关闭按钮当然是不行的,鼠标单击被拦截并阻止了,GUIGetMsg根本获取不到GUI_EVENT_CLOSE这个消息。
在任务栏上选择右键关闭,这样不会阻止消息。
afan
发表于 2010-7-27 19:18:11
回复 22# pusofalse
确实如此,而且不用+强制结束进程,一切正常。谢谢啦~
奥斯丁
发表于 2010-7-27 21:49:38
先高兴一下,不过还有问题哦, 窗口弹出来在中间就不能移动了。
afan
发表于 2010-7-27 21:55:40
本帖最后由 afan 于 2010-7-27 21:57 编辑
先高兴一下,不过还有问题哦, 窗口弹出来在中间就不能移动了。
奥斯丁 发表于 2010-7-27 21:49 http://www.autoitx.com/images/common/back.gif
这个问题可以用判断鼠标位置的方式(或者专门建立一个控件以供点击)来决定是否Hook
奥斯丁
发表于 2010-7-27 22:27:15
这个问题可以用判断鼠标位置的方式(或者专门建立一个控件以供点击)来决定是否Hook
afan 发表于 2010-7-27 21:55 http://www.autoitx.com/images/common/back.gif
谢谢版主, 不过版主请送佛送到西吧, 俺刚学gui, pusofalse 大大的脚本看起来
有大半犹如天书,还好send(‘a’)还能看懂, 加加减减的修改一下还能应付, 版主
上述的能否把代码都贴上来, 不情之请.......
再次谢谢诸位的热心!
afan
发表于 2010-7-27 22:36:54
回复 26# 奥斯丁
P版的代码都是些高级货,我也看不大懂… 添加点功能进去也许还凑合,不过肯定没有原设计思路的味。。。
奥斯丁
发表于 2010-7-27 23:01:13
{:face (411):} 板凳 {:face (303):}
afan
发表于 2010-7-27 23:24:35
回复 28# 奥斯丁 #include <WinAPI.au3>
#include <WindowsConstants.au3>
Global $hForeground, $_exit = False, $_move = False, $hw_top
$hGUI = GUICreate('Test', 400, 300, -1, -1, 0, $WS_EX_TOPMOST)
GUICtrlCreateButton('Send "a"', 40, 40, 150, 20)
GUICtrlSetCursor(-1, 0)
$hButton = GUICtrlGetHandle(-1)
GUICtrlCreateButton('Exit', 200, 40, 150, 20)
GUICtrlSetCursor(-1, 0)
$hButton1 = GUICtrlGetHandle(-1)
GUICtrlCreateLabel(' 按住此处拖动窗口', 100, 80, 150, 15)
GUICtrlSetBkColor(-1, 0x00ff00)
GUICtrlSetCursor(-1, 9)
$hLabel = GUICtrlGetHandle(-1)
$iThreadId = _WinAPI_GetCurrentThreadId()
$hInstance = _WinAPI_GetModuleHandle(0)
$hCBTProc = DllCallbackRegister('_CBTCallBack', 'int', 'uint;wparam;lparam')
$pCBTProc = DllCallbackGetPtr($hCBTProc)
$hCBTHook = _WinAPI_SetWindowsHookEx(5, $pCBTProc, $hInstance, $iThreadId)
$hMouseProc = DllCallbackRegister('_MouseProc', 'int', 'uint;wparam;lparam')
$pMouseProc = DllCallbackGetPtr($hMouseProc)
$hMouseHook = _WinAPI_SetWindowsHookEx(14, $pMouseProc, $hInstance, 0)
$hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hWnd;long;long;dword;dword')
$pEventProc = DllCallbackGetPtr($hEventProc)
$hEventHook = _SetWinEventHook($pEventProc, 1)
GUISetState(@SW_SHOWNOACTIVATE)
While GUIGetMsg() + 3
If $_exit Then ExitLoop
If $_move = True Then
$hw_top = _WinAPI_GetForegroundWindow()
GuiMove($hGUI)
$_move = False
EndIf
WEnd
_exit()
Func _exit()
GUIDelete($hGUI)
_WinAPI_UnhookWindowsHookEx($hCBTHook)
_WinAPI_UnhookWindowsHookEx($hMouseHook)
_UnhookWinEvent($hEventHook)
DllCallbackFree($hCBTProc)
DllCallbackFree($hMouseProc)
DllCallbackFree($hEventProc)
GUIDelete($hGUI)
EndFunc ;==>_exit
Func _CBTCallBack($iCode, $iwParam, $ilParam)
Switch $iCode
Case 5
If HWnd($iwParam) = $hGUI Then Return 1
EndSwitch
Return _WinAPI_CallNextHookEx($hCBTHook, $iCode, $iwParam, $ilParam)
EndFunc ;==>_CBTCallBack
Func _EventProc($hEventHook, $iEvent, $hWnd, $iObject, $iChild, $iEventThread, $iEventTime)
If ($iEvent = 0x8005) Then $hForeground = $hWnd
EndFunc ;==>_EventProc
Func _MouseProc($iCode, $iwParam, $ilParam)
If $_move = False Then
If ($iCode < 0) Then Return _WinAPI_CallNextHookEx($hMouseHook, $iCode, $iwParam, $ilParam)
Switch $iwParam
Case $WM_LBUTTONDOWN, $WM_LBUTTONUP, $WM_RBUTTONDOWN, $WM_RBUTTONUP, $WM_MBUTTONDOWN, $WM_MBUTTONUP
Local $tBuffer = DllStructCreate('int X;int Y', $ilParam)
Local $hWindow = _WinAPI_WindowFromPoint($tBuffer)
$tBuffer = 0
Switch $hWindow
Case $hGUI
Return 1
Case $hButton
If ($iwParam = $WM_LBUTTONUP) Then Send('a')
Return 1
Case $hButton1
$_exit = True
Return 1
Case $hLabel
$_move = True
Return 1
EndSwitch
EndSwitch
EndIf
Return _WinAPI_CallNextHookEx($hMouseHook, $iCode, $iwParam, $ilParam)
EndFunc ;==>_MouseProc
Func _SetWinEventHook($pCallBack, $iFlags, $iEventMin = 1, $iEventMax = 0x7FFFFFFF, $iProcessId = 0, $iThreadId = 0)
Local $iResult
$iResult = DllCall('User32.dll', 'ptr', 'SetWinEventHook', 'uint', $iEventMin, _
'uint', $iEventMax, 'ptr', 0, 'ptr', $pCallBack, 'dword', $iProcessId, _
'dword', $iThreadId, 'uint', $iFlags)
Return $iResult
EndFunc ;==>_SetWinEventHook
Func _UnhookWinEvent($hEventHook)
Local $iResult
$iResult = DllCall('User32.dll', 'int', 'UnhookWinEvent', 'ptr', $hEventHook)
Return $iResult
EndFunc ;==>_UnhookWinEvent
Func GuiMove($hGUI)
MouseDown('left')
Local $PY, $a_R, $PM = MouseGetPos(), $PW = WinGetPos($hGUI, '')
$PY = $PW - $PM
$PY = $PW - $PM
While 1
$a_R = DllCall('user32.dll', "short", "GetAsyncKeyState", "int", '0x01')
If @error Then Return 0
If Not BitAND($a_R, 0x8000) Then ExitLoop
$PM = MouseGetPos()
WinMove($hGUI, '', $PM + $PY, $PM + $PY)
Sleep(5)
WEnd
WinActivate($hw_top)
EndFunc ;==>GuiMove
奥斯丁
发表于 2010-7-28 11:20:24
3q!完美。。。。。。。。。。。