Gianni Posted August 9, 2015 Share Posted August 9, 2015 (edited) this is a draft snippet about using windows GUI as draggable "cards".what I'm trying to achieve is a way to know on what "card" (on what window) the dragged card has been dropped.I would prefer not to have to use an array to store all the windows "cards", and have to search through that array to see if the dropped card is on one of that stored in the array, but a way (a function) that will return "directly" the handle of the "card" that received the dropped "window" that is the window(s) below the dropped window. (maybe ther is a _WinAPI* for that?).Any suggestion is welcome.(sorry for my bad attempt at this English explanation)expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstants.au3> #include <APISysConstants.au3> #include <WinAPI.au3> #include <GUIMenu.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> ; https://www.autoitscript.com/forum/topic/164271-detect-when-any-and-all-windows-have-moved/?do=findComment&comment=1198129 Global $hEventProc = DllCallbackRegister(_EventProc, "none", "ptr;dword;hwnd;long;long;dword;dword") Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_MIN, $EVENT_MAX, DllCallbackGetPtr($hEventProc)) OnAutoItExitRegister(OnAutoItExit) ; clear the hook on exit Global $hMainWin = GUICreate('My main GUI', 400, 250, 50, 50) GUISetState(@SW_SHOW) $hGUI_Child0 = GUICreate('hand', 100, 100, 10, 0, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child0) ; a 2-element array containing Width and Height of window's client area (inner area excluding borders). GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) ; this allow dragging of the "card" by click on "card" and drag. GUICtrlCreateIcon("shell32.dll", 29, 0, 0, $aHostDim[0], $aHostDim[1]) ; put something to see on the card GUISetState(@SW_SHOW, $hGUI_Child0) _WinAPI_SetParent($hGUI_Child0, $hMainWin) ; trap this child gui within the main gui ; $hGUI_Child1 = GUICreate('tree', 100, 100, 25, 15, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child1) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 42, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child1) _WinAPI_SetParent($hGUI_Child1, $hMainWin) ; $hGUI_Child2 = GUICreate('star', 100, 100, 40, 30, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 44, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child2) _WinAPI_SetParent($hGUI_Child2, $hMainWin) MsgBox(0, "Pause", "Drag images on the Main GUI" & @CRLF & "Click OK to end") Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime ; Static $lastevent ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066%28v=vs.85%29.aspx Switch $iEvent Case $EVENT_SYSTEM_MOVESIZESTART ; ConsoleWrite("Start:" & @TAB & $iEvent & @TAB & $hWnd & @TAB & $iObjectID & @TAB & $iChildID & @CRLF) Case $EVENT_SYSTEM_MOVESIZEEND ; to be used as drop if _WinAPI_GetAncestor($hWnd) = $hMainWin Then ConsoleWrite(WinGetTitle($hWnd) & " dropped on.... ???" & @CRLF) EndIf Case Else #cs If $iEvent <> $lastevent Then ConsoleWrite("event:" & @TAB & $iEvent & @CRLF) $lastevent = $iEvent #ce EndIf EndSwitch EndFunc ;==>_EventProc Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) EndFunc ;==>OnAutoItExit Edited August 9, 2015 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
mikell Posted August 10, 2015 Share Posted August 10, 2015 ?_WinAPI_GetWindow($hWnd, $GW_HWNDNEXT) Gianni 1 Link to comment Share on other sites More sharing options...
KaFu Posted August 10, 2015 Share Posted August 10, 2015 (edited) Maybe you can use something like this. It might be necessary to exclude the window being dragged from the list. expandcollapse popup#include <misc.au3> HotKeySet("{ESC}", "_Exit") Local $aMousePos, $_hWnd_OnPos While 1 Sleep(10) If _IsPressed("01") Then $aMousePos = MouseGetPos() $_hWnd_OnPos = _hWnd_Visible_AtPos($aMousePos[0], $aMousePos[1]) ConsoleWrite($_hWnd_OnPos & @TAB & WinGetTitle($_hWnd_OnPos) & @CRLF) While _IsPressed("01") Sleep(10) WEnd EndIf WEnd Func _hWnd_Visible_AtPos($x, $y) Local $aWinlist = WinList() Local $aWinlist_Final[100][6], $iEnum, $aPos For $i = 1 To $aWinlist[0][0] If BitAND(WinGetState($aWinlist[$i][1]), 2) Then ; is visible $aWinlist_Final[$iEnum][0] = $aWinlist[$i][0] $aWinlist_Final[$iEnum][1] = $aWinlist[$i][1] $aPos = WinGetPos($aWinlist[$i][1]) $aWinlist_Final[$iEnum][2] = $aPos[0] ; x $aWinlist_Final[$iEnum][3] = $aPos[1] ; y $aWinlist_Final[$iEnum][4] = $aPos[2] ; w $aWinlist_Final[$iEnum][5] = $aPos[3] ; h $iEnum += 1 If Not Mod($iEnum, 100) Then ReDim $aWinlist_Final[UBound($aWinlist_Final) + 100][6] EndIf Next ReDim $aWinlist_Final[$iEnum - 1][6] For $i = 0 To $iEnum - 1 If $x >= $aWinlist_Final[$i][2] And $x <= ($aWinlist_Final[$i][2] + $aWinlist_Final[$i][4]) And _ $y >= $aWinlist_Final[$i][3] And $y <= ($aWinlist_Final[$i][3] + $aWinlist_Final[$i][5]) Then Return $aWinlist_Final[$i][1] Next Return 0 EndFunc ;==>_hWnd_Visible_AtPos Func _Exit() Exit EndFunc ;==>_Exit Edited August 10, 2015 by KaFu Gianni and Aelc 2 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
UEZ Posted August 10, 2015 Share Posted August 10, 2015 (edited) You can try thisCase $EVENT_SYSTEM_MOVESIZEEND ; to be used as drop If _WinAPI_GetAncestor($hWnd) = $hMainWin Then Local $hTop = _WinAPI_GetWindow($hMainWin, $GW_CHILD) Local $hNext = _WinAPI_GetWindow ($hTop, $GW_HWNDNEXT) ConsoleWrite(WinGetTitle($hTop) & " dropped on " & WinGetTitle($hNext) & @CRLF) EndIf But it will only display the next on z order! Edited August 10, 2015 by UEZ Gianni 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
junkew Posted August 10, 2015 Share Posted August 10, 2015 Not sure if I am getting it right.Wouldn't this be just a https://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_WindowFromPoint.htmThen define what the definition is of dropping a card on another one.1. Its the mouse cursor position where you release the moved card2. Its any of the boundarypoints of the moved card3. ......and maybe this gives another solution directionit looks easy over here ;-) but to difficult for mehttps://msdn.microsoft.com/en-us/library/windows/desktop/ms678405(v=vs.85).aspx Gianni 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Danyfirex Posted August 10, 2015 Share Posted August 10, 2015 If I got what you meant I edit your code and Got this: expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstants.au3> #include <APISysConstants.au3> #include <WinAPI.au3> #include <GUIMenu.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <GDIPlus.au3> #include <WinAPIShellEx.au3> Global Const $hOLEACC = DllOpen("oleacc.dll") Global Const $hOleAut = DllOpen("oleaut.dll") Global Const $stagVARIANT = "ushort vt;ushort r1;ushort r2;ushort r3;ptr data; ptr" Global $tVar = DllStructCreate($stagVARIANT) Global $pvarChild = DllStructGetPtr($tVar) Global Const $sIID_IAccessible = "{618736e0-3c3d-11cf-810c-00aa00389b71}" ; https://www.autoitscript.com/forum/topic/164271-detect-when-any-and-all-windows-have-moved/?do=findComment&comment=1198129 Global $hEventProc = DllCallbackRegister(_EventProc, "none", "ptr;dword;hwnd;long;long;dword;dword") Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_MIN, $EVENT_MAX, DllCallbackGetPtr($hEventProc)) OnAutoItExitRegister(OnAutoItExit) ; clear the hook on exit Global $oMyError = ObjEvent("AutoIt.Error", "_ErrFunc") Global $hMainWin = GUICreate('My main GUI', 400, 250, 50, 50) GUISetState(@SW_SHOW) _GDIPlus_Startup() $hGUI_Child0 = GUICreate('Notepad', 100, 100, 10, 0, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child0) ; a 2-element array containing Width and Height of window's client area (inner area excluding borders). $hIcon0 = _WinAPI_ShellExtractIcon('notepad.exe', 0, $aHostDim[0], $aHostDim[1]) $hBitmap0 = _GDIPlus_BitmapCreateFromHICON($hIcon0) Global $g_hGraphic0 = _GDIPlus_GraphicsCreateFromHWND($hGUI_Child0) GUISetState(@SW_SHOW, $hGUI_Child0) _WinAPI_SetParent($hGUI_Child0, $hMainWin) ; trap this child gui within the main gui ; $hGUI_Child1 = GUICreate('Folder', 100, 100, 25, 15, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child1) $hIcon1 = _WinAPI_ShellExtractIcon('explorer.exe', 0, $aHostDim[0], $aHostDim[1]) $hBitmap1 = _GDIPlus_BitmapCreateFromHICON($hIcon1) Global $g_hGraphic1 = _GDIPlus_GraphicsCreateFromHWND($hGUI_Child1) GUISetState(@SW_SHOW, $hGUI_Child1) _WinAPI_SetParent($hGUI_Child1, $hMainWin) $hGUI_Child2 = GUICreate('Calc', 100, 100, 40, 30, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $hIcon2 = _WinAPI_ShellExtractIcon('Calc.exe', 0, $aHostDim[0], $aHostDim[1]) $hBitmap2 = _GDIPlus_BitmapCreateFromHICON($hIcon2) Global $g_hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($hGUI_Child2) GUISetState(@SW_SHOW, $hGUI_Child2) _WinAPI_SetParent($hGUI_Child2, $hMainWin) GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT") GUIRegisterMsg($WM_LBUTTONDOWN, "_WinMove") ;~ Paint first _GDIPlus_GraphicsDrawImage($g_hGraphic0, $hBitmap0, 0, 0) _GDIPlus_GraphicsDrawImage($g_hGraphic1, $hBitmap1, 0, 0) _GDIPlus_GraphicsDrawImage($g_hGraphic2, $hBitmap2, 0, 0) VariantInit($pvarChild) MsgBox(0, "Pause", "Drag images on the Main GUI" & @CRLF & "Click OK to end") _GDIPlus_GraphicsDispose($g_hGraphic0) _GDIPlus_GraphicsDispose($g_hGraphic1) _GDIPlus_GraphicsDispose($g_hGraphic2) _GDIPlus_BitmapDispose($hBitmap0) _GDIPlus_BitmapDispose($hBitmap1) _GDIPlus_BitmapDispose($hBitmap2) _GDIPlus_Shutdown() DllClose($hOleAut) DllClose($hOLEACC) ;~ Just for Move Func _WinMove($HWnd, $Command, $wParam, $lParam) If BitAND(WinGetState($HWnd), 32) Then Return $GUI_RUNDEFMSG DllCall("user32.dll", "long", "SendMessage", "hwnd", $HWnd, "int", $WM_SYSCOMMAND, "int", 0xF009, "int", 0) EndFunc ;==>_WinMove ; Draw PNG image Func MY_WM_PAINT($HWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam _WinAPI_RedrawWindow($hMainWin, 0, 0, $RDW_UPDATENOW) _GDIPlus_GraphicsDrawImage($g_hGraphic0, $hBitmap0, 0, 0) _GDIPlus_GraphicsDrawImage($g_hGraphic1, $hBitmap1, 0, 0) _GDIPlus_GraphicsDrawImage($g_hGraphic2, $hBitmap2, 0, 0) _WinAPI_RedrawWindow($hMainWin, 0, 0, $RDW_VALIDATE) Return $GUI_RUNDEFMSG EndFunc ;==>MY_WM_PAINT Func _EventProc($hEventHook, $iEvent, $HWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime ; Static $lastevent ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066%28v=vs.85%29.aspx Local $aWin = 0 Switch $iEvent Case $EVENT_SYSTEM_MOVESIZESTART ; ConsoleWrite("Start:" & @TAB & $iEvent & @TAB & $hWnd & @TAB & $iObjectID & @TAB & $iChildID & @CRLF) Case $EVENT_SYSTEM_MOVESIZEEND ; to be used as drop If _WinAPI_GetAncestor($HWnd) = $hMainWin Then $aWin = WinGetPos($HWnd) If IsArray($aWin) Then ConsoleWrite(WinGetTitle($HWnd) & " dropped on " & _GetWindows($aWin) & @CRLF) EndIf EndIf Case Else #cs If $iEvent <> $lastevent Then ConsoleWrite("event:" & @TAB & $iEvent & @CRLF) $lastevent = $iEvent #ce EndIf EndSwitch EndFunc ;==>_EventProc Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) EndFunc ;==>OnAutoItExit Func _GetWindows($aArray) Local $pIAccesible = 0 Local $oIAccesible = 0 Local $aRet = 0 Local $x = 0, $y = 0 Local $sWindows = "" Local $aMain = WinGetPos($hMainWin) Local $iBarheight = 0 For $i = 0 To 4 - 1 ;check 4 object(Child window) corners Switch $i Case 0 $x = $aArray[0] - 1 $y = $aArray[1] - 1 Case 1 $x = $aArray[0] + $aArray[2] + 1 $y = $aArray[1] - 1 Case 2 $x = $aArray[0] + $aArray[2] + 1 $y = $aArray[1] + $aArray[3] + 1 Case 3 $x = $aArray[0] - 1 $y = $aArray[1] + $aArray[3] + 1 Case Else EndSwitch $iBarheight = _WinAPI_GetSystemMetrics($SM_CYCAPTION) If $x < $aMain[0] Or $y < ($aMain[1] + $iBarheight) Then ContinueLoop If $x > ($aMain[0] + $aMain[2]) Or $y > ($aMain[1] + $aMain[3]) Then ContinueLoop $aRet = DllCall($hOLEACC, "int", "AccessibleObjectFromPoint", _ "int", $x, _ "int", $y, _ "ptr*", 0, _ "ptr", $pvarChild) If @error Or $aRet[0] <> 0 Then ContinueLoop $pIAccesible = $aRet[3] $oIAccesible = ObjCreateInterface($pIAccesible, $sIID_IAccessible) If (WinGetTitle($hMainWin) <> $oIAccesible.accName) Then $sWindows &= (($sWindows <> "") ? " and " : "") & $oIAccesible.accName EndIf If $aRet[0] = 0 Then VariantClear($pvarChild) $oIAccesible = 0 $aRet=0 Next If $sWindows = "" Then $sWindows = WinGetTitle($hMainWin) Return $sWindows EndFunc ;==>_GetWindows Func VariantClear($pvariant) Local $aRet = DllCall($hOleAut, "long", "VariantClear", "ptr", $pvariant) If @error Then Return SetError(1, 0, 1) Return $aRet[0] EndFunc ;==>VariantClear Func VariantInit($pvariant) Local $aRet = DllCall($hOleAut, "long", "VariantInit", "ptr", $pvariant) If @error Then Return SetError(1, 0, 1) Return $aRet[0] EndFunc ;==>VariantInit Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFuncSaludos UEZ 1 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
junkew Posted August 10, 2015 Share Posted August 10, 2015 @Danyfirex: Nice piece of code @CHIMP: It depends on your definition of drop on another window, if you now select the bottom one to become in foreground its dropped on the top window whereas probably thats not the definition of a drop (suggestion if mouse moves more then n pixels from starting point its a drag/drop operation whereas n>=5 but 5 is an arbitrary choice) Danyfirex 1 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Gianni Posted August 12, 2015 Author Share Posted August 12, 2015 (edited) Thanks all for the good suggestions and interesting solutions, very appreciated!Sorry for the delay on answering, I'm not around on this days.I will elaborate on this nice answers and will report here about results.Thanks everybody (for now). Edited August 12, 2015 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Danyfirex Posted August 12, 2015 Share Posted August 12, 2015 (edited) I was thinking why not use collision detection so a wrote this:expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstants.au3> #include <APISysConstants.au3> #include <WinAPI.au3> #include <GUIMenu.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <Array.au3> ; https://www.autoitscript.com/forum/topic/164271-detect-when-any-and-all-windows-have-moved/?do=findComment&comment=1198129 Global $hEventProc = DllCallbackRegister(_EventProc, "none", "ptr;dword;hwnd;long;long;dword;dword") Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_MIN, $EVENT_MAX, DllCallbackGetPtr($hEventProc)) OnAutoItExitRegister(OnAutoItExit) ; clear the hook on exit Global $hMainWin = GUICreate('My main GUI', 400, 400, 50, 50) GUISetState(@SW_SHOW) $hGUI_Child0 = GUICreate('hand', 100, 100, 10, 0, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child0) ; a 2-element array containing Width and Height of window's client area (inner area excluding borders). GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) ; this allow dragging of the "card" by click on "card" and drag. GUICtrlCreateIcon("shell32.dll", 29, 0, 0, $aHostDim[0], $aHostDim[1]) ; put something to see on the card GUISetState(@SW_SHOW, $hGUI_Child0) _WinAPI_SetParent($hGUI_Child0, $hMainWin) ; trap this child gui within the main gui ; $hGUI_Child1 = GUICreate('tree', 100, 100, 25, 15, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child1) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 42, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child1) _WinAPI_SetParent($hGUI_Child1, $hMainWin) ; $hGUI_Child2 = GUICreate('star', 100, 100, 40, 30, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 44, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child2) _WinAPI_SetParent($hGUI_Child2, $hMainWin) $hGUI_Child3 = GUICreate('folder', 100, 100, 55, 45, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 39, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child3) _WinAPI_SetParent($hGUI_Child3, $hMainWin) $hGUI_Child4 = GUICreate('key', 100, 100, 70, 60, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 45, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child4) _WinAPI_SetParent($hGUI_Child4, $hMainWin) $hGUI_Child5 = GUICreate('locker', 100, 100, 85, 75, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 48, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child5) _WinAPI_SetParent($hGUI_Child5, $hMainWin) MsgBox(0, "Pause", "Drag images on the Main GUI" & @CRLF & "Click OK to end") Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime ; Static $lastevent ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066(v=vs.85).aspx Local $aAllChildWindows = 0 Local $aChildWindows = 0 Local $sWindows = "" Switch $iEvent Case $EVENT_SYSTEM_MOVESIZESTART ; ConsoleWrite("Start:" & @TAB & $iEvent & @TAB & $hWnd & @TAB & $iObjectID & @TAB & $iChildID & @CRLF) Case $EVENT_SYSTEM_MOVESIZEEND ; to be used as drop If _WinAPI_GetAncestor($hWnd) = $hMainWin Then $aAllChildWindows = _WinAPI_EnumChildWindows($hMainWin) $aChildWindows = _GetJustChildWindow($aAllChildWindows, $hMainWin, $hWnd) If IsArray($aChildWindows) Then $sWindows = _GetWindowBycollision($aChildWindows, $hWnd) ConsoleWrite(WinGetTitle($hWnd) & " dropped on " & $sWindows & @CRLF) EndIf EndIf Case Else #cs If $iEvent <> $lastevent Then ConsoleWrite("event:" & @TAB & $iEvent & @CRLF) $lastevent = $iEvent #ce EndIf EndSwitch EndFunc ;==>_EventProc Func _GetWindowBycollision($aWindow, $hWinMoving) Local $aWin1 = WinGetPos($hWinMoving) Local $aWin2 = 0 Local $sWindows = "" For $i = 0 To UBound($aWindow) - 1 $aWin2 = WinGetPos($aWindow[$i]) If $aWin1[0] < $aWin2[0] + $aWin2[2] And $aWin1[0] + $aWin1[2] > $aWin2[0] And $aWin1[1] < $aWin2[1] + $aWin2[3] And $aWin1[3] + $aWin1[1] > $aWin2[1] Then $sWindows &= (($sWindows <> "") ? ", " : "") & WinGetTitle($aWindow[$i]) EndIf Next If $sWindows = "" Then $sWindows = WinGetTitle($hMainWin) if StringInStr($sWindows,",",0,-1) Then $sWindows=StringReplace($sWindows,StringMid($sWindows,StringInStr($sWindows,",",0,-1))," and" & StringMid($sWindows,StringInStr($sWindows,",",0,-1)+1)) EndIf Return $sWindows EndFunc ;==>_GetWindowBycollision Func _GetJustChildWindow($aArray, $hParentWindow, $hWinToAvoid) Local $aNewArray[0] If IsArray($aArray) Then For $i = 1 To $aArray[0][0] If $aArray[$i][1] = _WinAPI_GetClassName($hParentWindow) And $hWinToAvoid <> $aArray[$i][0] Then ReDim $aNewArray[UBound($aNewArray) + 1] $aNewArray[UBound($aNewArray) - 1] = $aArray[$i][0] ConsoleWrite($i & $aNewArray[UBound($aNewArray) - 1] & @CRLF) EndIf Next Return $aNewArray EndIf Return 0 EndFunc ;==>_GetJustChildWindow Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) EndFunc ;==>OnAutoItExit Saludos Edited August 12, 2015 by Danyfirex Edit Gianni 1 Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
Gianni Posted August 15, 2015 Author Share Posted August 15, 2015 Hi, I'm back on this topic,well, after done some testing, I have seen that to establish which card is below the one dropped, I have to define some criteria, as already pointed out in post #5 by @junkew, that is:1) the target is the card below the dropped card pointed by the arrow pointer2) the target is the first z-order card encountered by the dropping card3) the target is the card that underlies and that has the major percentage of surface covered by the dropped card (regardless the z-order).now:point 1 can be essentially achieved as from post #3 by @kafu (thank you)point 2 can be essentially achieved as from post #9 by @Danyfirex (thank you)point 3 still not achieved... I have to think a good way to do it (suggestions are welcome)I mainly used portion of code from post #3 and #9 (and also from other posts as well) to implement points 1 and 2, all has been concentrated in the GetBelow() function that I will try to enhance by adding feature of point 3.Thanks a lot everybody againhere the new draft:expandcollapse popup#include <GUIConstants.au3> #include <APISysConstants.au3> #include <WinAPI.au3> #include <WinAPISys.au3> ; https://www.autoitscript.com/forum/topic/164271-detect-when-any-and-all-windows-have-moved/?do=findComment&comment=1198129 Global $hEventProc = DllCallbackRegister(_EventProc, "none", "ptr;dword;hwnd;long;long;dword;dword") Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_MIN, $EVENT_MAX, DllCallbackGetPtr($hEventProc)) OnAutoItExitRegister(OnAutoItExit) ; clear the hook on exit ; Global $hMainWin = GUICreate('My main GUI', 400, 400, 50, 50) GUISetState(@SW_SHOW) ; $hGUI_Child0 = GUICreate('hand', 100, 100, 10, 0, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child0) ; a 2-element array containing Width and Height of window's client area (inner area excluding borders). GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) ; this allow dragging of the "card" by click on "card" and drag. GUICtrlCreateIcon("shell32.dll", 29, 0, 0, $aHostDim[0], $aHostDim[1]) ; put something to see on the card GUISetState(@SW_SHOW, $hGUI_Child0) _WinAPI_SetParent($hGUI_Child0, $hMainWin) ; trap this child gui within the main gui ; $hGUI_Child1 = GUICreate('tree', 100, 100, 25, 15, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child1) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 42, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child1) _WinAPI_SetParent($hGUI_Child1, $hMainWin) ; $hGUI_Child2 = GUICreate('star', 100, 100, 40, 30, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child2) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 44, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child2) _WinAPI_SetParent($hGUI_Child2, $hMainWin) $hGUI_Child3 = GUICreate('folder', 100, 100, 55, 45, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child3) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 39, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child3) _WinAPI_SetParent($hGUI_Child3, $hMainWin) ; $hGUI_Child4 = GUICreate('key', 100, 100, 70, 60, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child4) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 45, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child4) _WinAPI_SetParent($hGUI_Child4, $hMainWin) ; $hGUI_Child5 = GUICreate('locker', 100, 100, 85, 75, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child5) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 48, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child5) _WinAPI_SetParent($hGUI_Child5, $hMainWin) ; Local $hStaticDropArea = GUICreate("static drop area", 380, 90, 10, 290, 0x40000000, $WS_EX_CLIENTEDGE, $hMainWin) ; 0x40000000 -> $WS_CHILD Local $Dummy = GUISetBkColor(0xFF7733, $hStaticDropArea) + GUICtrlCreateLabel("static drop area", 5, 50, 230) + GUICtrlSetFont(-1, 12, "", "", "Courier New") + GUISetState(@SW_SHOW, $hStaticDropArea) ; ; --- console window --- Local $hConsoleGUI = GUICreate('Console', 400, 200, 50, 490, $WS_CAPTION) GUISetBkColor(0x000000, $hConsoleGUI) Local $hConsole = GUICtrlCreateLabel("", 5, 5, 390, 290) $Dummy = GUICtrlSetFont(-1, 9, 0, 0, "Courier New") + GUICtrlSetBkColor(-1, 0x000000) + GUICtrlSetColor(-1, 0x00ff00) + GUISetState(@SW_SHOW) ; ---------------------- MsgBox(0, "Pause", "Drag images on the Main GUI" & @CRLF & "Click OK to end") Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) ; https://msdn.microsoft.com/en-us/library/dd373885(v=vs.85).aspx #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066(v=vs.85).aspx Switch $iEvent Case $EVENT_SYSTEM_MOVESIZESTART Case $EVENT_SYSTEM_MOVESIZEEND ; to be used as drop If $hMainWin = _WinAPI_GetAncestor($hWnd, $GA_PARENT) Then ; $GA_PARENT = 1 $aResults = GetBelow($hWnd) ; returns 3 element array with handles of: [0]Dragged card, [1] card below pointer, [2] first z-order card below the dragged card If Not $aResults[1] Then ; [1] -> below pointer ConsolePrint("by Arrow: " & WinGetTitle($aResults[0]) & " dropped on empty area" & @CRLF, $hConsole) Else ConsolePrint("by Arrow: " & WinGetTitle($aResults[0]) & " dropped on " & WinGetTitle($aResults[1]) & @CRLF, $hConsole) EndIf ; If Not $aResults[2] Then ; [2] -> layer below ConsolePrint("by Layer: " & WinGetTitle($aResults[0]) & " dropped on empty area" & @CRLF, $hConsole) Else ConsolePrint("by Layer: " & WinGetTitle($aResults[0]) & " dropped on " & WinGetTitle($aResults[2]) & @CRLF, $hConsole) EndIf EndIf ; If $hWnd = $hMainWin Then ; if main window was moved then snap console to main win Local $aMainWin = WinGetPos($hMainWin) WinMove($hConsoleGUI, "", $aMainWin[0], $aMainWin[1] + $aMainWin[3] + 11) EndIf Case Else #cs If $iEvent <> $lastevent Then ConsoleWrite("event:" & @TAB & $iEvent & @CRLF) $lastevent = $iEvent #ce EndIf EndSwitch EndFunc ;==>_EventProc Func GetBelow(ByRef $hDropped) Local $hFoundByArrow = 0, $hFoundByLayer = 0 Local $hPullChild = _WinAPI_GetWindow($hMainWin, $GW_CHILD) ; get the first child from the child's stack (the one being dragged) Local $aWin1 = WinGetPos($hPullChild) ; <-- Retrieves the position and size of the dropped "card" Do ; scan all the child windows (child "cards") $hPullChild = _WinAPI_GetWindow($hPullChild, $GW_HWNDnext) ; pull next child from the z-order stack (returns 0 if no more cards) If $hPullChild Then ; if there are still cards in the stack to be checked $aPos = WinGetPos($hPullChild) ; position and size of "card" being checked $aMxy = MouseGetPos() ; Mouse x and y positions If Not $hFoundByArrow Then ; if not already found the "card" pointed by mouse pointer If $aMxy[0] >= $aPos[0] And $aMxy[0] <= $aPos[0] + $aPos[2] And $aMxy[1] >= $aPos[1] And $aMxy[1] <= $aPos[1] + $aPos[3] Then $hFoundByArrow = $hPullChild EndIf ; If Not $hFoundByLayer Then; if not already found the "card" layered below the dropped If $aWin1[0] < $aPos[0] + $aPos[2] And $aWin1[0] + $aWin1[2] > $aPos[0] And $aWin1[1] < $aPos[1] + $aPos[3] And $aWin1[3] + $aWin1[1] > $aPos[1] Then $hFoundByLayer = $hPullChild EndIf EndIf Until Not $hPullChild Or ($hFoundByArrow And $hFoundByLayer) Local $aResults[3] = [$hDropped, $hFoundByArrow, $hFoundByLayer] Return $aResults EndFunc ;==>GetBelow Func ConsolePrint($sMSG, ByRef $hConsole) If StringInStr(GUICtrlRead($hConsole) & $sMSG, @LF, 0, -12) Then GUICtrlSetData($hConsole, StringRight(GUICtrlRead($hConsole) & $sMSG, StringLen(GUICtrlRead($hConsole) & $sMSG) - StringInStr(GUICtrlRead($hConsole), @LF, 0, -12))) Else GUICtrlSetData($hConsole, GUICtrlRead($hConsole) & $sMSG) EndIf EndFunc ;==>ConsolePrint Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) EndFunc ;==>OnAutoItExit Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
KaFu Posted August 17, 2015 Share Posted August 17, 2015 For 3), how about using "IntersectRect" to calculated a cover percentage in something like this?Currently Array is sorted by Z-Order (Col 0), cover percentage is in Col 8, resort array on that column to receive hwnds with max. cover percentage.expandcollapse popup#include <Array.au3> #include <Misc.au3> Global $h_Ref_GUI = GUICreate("Ref-Gui") GUISetState() HotKeySet("{ESC}", "_Exit") Local $aMousePos, $_a_hWnd_OnPos While 1 Sleep(10) If _IsPressed("7B") Then ; F12 $aMousePos = MouseGetPos() $_a_hWnd_OnPos = _hWnd_AtPos($aMousePos[0], $aMousePos[1], $h_Ref_GUI) _ArrayDisplay($_a_hWnd_OnPos) EndIf WEnd Func _hWnd_AtPos($x, $y, $hWnd_to_Test) Local $aWinlist = WinList() Local $aWinlist_Final[100][9], $iEnum = 1, $aPos For $i = 1 To $aWinlist[0][0] If BitAND(WinGetState($aWinlist[$i][1]), 2) Then ; is visible $aWinlist_Final[$iEnum][0] = $iEnum ; Z-Order $aWinlist_Final[$iEnum][1] = $aWinlist[$i][0] $aWinlist_Final[$iEnum][2] = $aWinlist[$i][1] $aPos = WinGetPos($aWinlist[$i][1]) $aWinlist_Final[$iEnum][3] = $aPos[0] ; x $aWinlist_Final[$iEnum][4] = $aPos[1] ; y $aWinlist_Final[$iEnum][5] = $aPos[2] ; w $aWinlist_Final[$iEnum][6] = $aPos[3] ; h $iEnum += 1 If Not Mod($iEnum, 100) Then ReDim $aWinlist_Final[UBound($aWinlist_Final) + 100][9] EndIf Next ReDim $aWinlist_Final[$iEnum - 1][9] $aWinlist_Final[0][0] = $iEnum - 2 ; No. of Win found For $i = 1 To $iEnum - 1 If $x >= $aWinlist_Final[$i][3] And $x <= ($aWinlist_Final[$i][3] + $aWinlist_Final[$i][5]) And _ $y >= $aWinlist_Final[$i][4] And $y <= ($aWinlist_Final[$i][4] + $aWinlist_Final[$i][6]) Then $aWinlist_Final[0][1] = $aWinlist_Final[$i][2] ; Window under x,y $aWinlist_Final[0][2] = WinGetTitle($aWinlist_Final[$i][2]) ExitLoop EndIf Next Local $t_RECT_Intersection = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") Local $t_RECT_Var = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") Local $t_RECT_Test = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") Local $a_Pos_hWnd_to_Test = WinGetPos($hWnd_to_Test) DllStructSetData($t_RECT_Test, 1, $a_Pos_hWnd_to_Test[0]) DllStructSetData($t_RECT_Test, 2, $a_Pos_hWnd_to_Test[1]) DllStructSetData($t_RECT_Test, 3, $a_Pos_hWnd_to_Test[0] + $a_Pos_hWnd_to_Test[2]) DllStructSetData($t_RECT_Test, 4, $a_Pos_hWnd_to_Test[1] + $a_Pos_hWnd_to_Test[3]) Local $i_Res, $i_Pixel_hWnd_to_Test = $a_Pos_hWnd_to_Test[2] * $a_Pos_hWnd_to_Test[3] For $i = 1 To $aWinlist_Final[0][0] DllStructSetData($t_RECT_Var, 1, $aWinlist_Final[$i][3]) DllStructSetData($t_RECT_Var, 2, $aWinlist_Final[$i][4]) DllStructSetData($t_RECT_Var, 3, $aWinlist_Final[$i][3] + $aWinlist_Final[$i][5]) DllStructSetData($t_RECT_Var, 4, $aWinlist_Final[$i][4] + $aWinlist_Final[$i][6]) $iRes = DllCall("user32.dll", "bool", "IntersectRect", "ptr", DllStructGetPtr($t_RECT_Intersection), "ptr", DllStructGetPtr($t_RECT_Var), "ptr", DllStructGetPtr($t_RECT_Test)) If $iRes[0] Then ; Intersection $aWinlist_Final[$i][7] = (DllStructGetData($t_RECT_Intersection, 3) - DllStructGetData($t_RECT_Intersection, 1)) * (DllStructGetData($t_RECT_Intersection, 4) - DllStructGetData($t_RECT_Intersection, 2)) ; Percentage of hWnd_to_Test intersecting with hWnd $aWinlist_Final[$i][8] = Round($aWinlist_Final[$i][7] / $i_Pixel_hWnd_to_Test, 2) EndIf Next Return $aWinlist_Final EndFunc ;==>_hWnd_AtPos Func _Exit() Exit EndFunc ;==>_Exit OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Gianni Posted August 17, 2015 Author Share Posted August 17, 2015 Thanks @KafuI will make some tests on your code....see you later... Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Gianni Posted August 18, 2015 Author Share Posted August 18, 2015 hi KaFu, thanks again for your suggestion.I've included your dll* stuff into my template so to be able to show what I noticed about results. (I was also on a similar way more geometric coded than relied on dll, anyway I'm testing your way now). I've also changed the dimensions of the windows (the cards) so to better view what I mean (at least I hope so)the % of overlap related to only 2 windows is ok, but if for example 3 (or more) windows are stacked, the routine returns the % of overlap for each window not considering how they hide each other. For example, if you move the "lock" card on an empty area and then you cover it only partially with the "key" card, the "lock" will be visible now only partially, so, if now I move the "tree" card above both cards (the lock and the key), I would get the overlap percentage for the lock for only the "visible" part and not for the whole surface (that is the part visible and the part hidden).expandcollapse popup#include <GUIConstants.au3> #include <APISysConstants.au3> #include <WinAPI.au3> #include <WinAPISys.au3> #include <Math.au3> ; https://www.autoitscript.com/forum/topic/164271-detect-when-any-and-all-windows-have-moved/?do=findComment&comment=1198129 Global $hEventProc = DllCallbackRegister(_EventProc, "none", "ptr;dword;hwnd;long;long;dword;dword") Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_MIN, $EVENT_MAX, DllCallbackGetPtr($hEventProc)) OnAutoItExitRegister(OnAutoItExit) ; clear the hook on exit ; Global $hMainWin = GUICreate('My main GUI', 400, 400, 50, 50) GUISetState(@SW_SHOW) ; $hGUI_Child0 = GUICreate('hand', 110, 110, 10, 0, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child0) ; a 2-element array containing Width and Height of window's client area (inner area excluding borders). GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) ; this allow dragging of the "card" by click on "card" and drag. GUICtrlCreateIcon("shell32.dll", 29, 0, 0, $aHostDim[0], $aHostDim[1]) ; put something to see on the card GUISetState(@SW_SHOW, $hGUI_Child0) _WinAPI_SetParent($hGUI_Child0, $hMainWin) ; trap this child gui within the main gui ; $hGUI_Child1 = GUICreate('tree', 100, 150, 25, 15, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child1) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 42, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child1) _WinAPI_SetParent($hGUI_Child1, $hMainWin) ; $hGUI_Child2 = GUICreate('star', 100, 100, 40, 30, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child2) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 44, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child2) _WinAPI_SetParent($hGUI_Child2, $hMainWin) $hGUI_Child3 = GUICreate('folder', 100, 100, 55, 45, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child3) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 39, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child3) _WinAPI_SetParent($hGUI_Child3, $hMainWin) ; $hGUI_Child4 = GUICreate('key', 100, 100, 70, 60, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child4) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 45, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child4) _WinAPI_SetParent($hGUI_Child4, $hMainWin) ; $hGUI_Child5 = GUICreate('locker', 50, 50, 85, 75, $WS_POPUPWINDOW, BitOR($WS_EX_DLGMODALFRAME, $WS_EX_CLIENTEDGE)) $aHostDim = WinGetClientSize($hGUI_Child5) GUICtrlCreatePic("", 0, 0, $aHostDim[0], $aHostDim[1], -1, $GUI_WS_EX_PARENTDRAG) GUICtrlCreateIcon("shell32.dll", 48, 0, 0, $aHostDim[0], $aHostDim[1]) GUISetState(@SW_SHOW, $hGUI_Child5) _WinAPI_SetParent($hGUI_Child5, $hMainWin) ; Local $hStaticDropArea = GUICreate("static drop area", 380, 130, 10, 250, 0x40000000, $WS_EX_CLIENTEDGE, $hMainWin) ; 0x40000000 -> $WS_CHILD Local $Dummy = GUISetBkColor(0xFF7733, $hStaticDropArea) + GUICtrlCreateLabel("static drop area", 5, 50, 230) + GUICtrlSetFont(-1, 12, "", "", "Courier New") + GUISetState(@SW_SHOW, $hStaticDropArea) ; ; --- console window --- Local $hConsoleGUI = GUICreate('Console', 400, 200, 50, 490, $WS_CAPTION) GUISetBkColor(0x000000, $hConsoleGUI) Local $hConsole = GUICtrlCreateLabel("", 5, 5, 390, 290) $Dummy = GUICtrlSetFont(-1, 9, 0, 0, "Courier New") + GUICtrlSetBkColor(-1, 0x000000) + GUICtrlSetColor(-1, 0x00ff00) + GUISetState(@SW_SHOW) ; ---------------------- MsgBox(0, "Pause", "Drag images on the Main GUI" & @CRLF & "Click OK to end") Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) ; https://msdn.microsoft.com/en-us/library/dd373885(v=vs.85).aspx #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime ; https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066(v=vs.85).aspx Switch $iEvent Case $EVENT_SYSTEM_MOVESIZESTART Case $EVENT_SYSTEM_MOVESIZEEND ; to be used as drop If $hMainWin = _WinAPI_GetAncestor($hWnd, $GA_PARENT) Then ; $GA_PARENT = 1 $aResults = GetBelow($hWnd) ; returns 3 element array with handles of: [0]Dragged card, [1] card below pointer, [2] first z-order card below the dragged card #cs If Not $aResults[1] Then ; [1] -> below pointer ConsolePrint("by Arrow: " & WinGetTitle($aResults[0]) & " dropped on empty area" & @CRLF, $hConsole) Else ConsolePrint("by Arrow: " & WinGetTitle($aResults[0]) & " dropped on " & WinGetTitle($aResults[1]) & @CRLF, $hConsole) EndIf ; If Not $aResults[2] Then ; [2] -> layer below ConsolePrint("by Layer: " & WinGetTitle($aResults[0]) & " dropped on empty area" & @CRLF, $hConsole) Else ConsolePrint("by Layer: " & WinGetTitle($aResults[0]) & " dropped on " & WinGetTitle($aResults[2]) & @CRLF, $hConsole) EndIf #ce EndIf ; If $hWnd = $hMainWin Then ; if main window was moved then snap console to main win Local $aMainWin = WinGetPos($hMainWin) WinMove($hConsoleGUI, "", $aMainWin[0], $aMainWin[1] + $aMainWin[3] + 11) EndIf Case Else #cs If $iEvent <> $lastevent Then ConsoleWrite("event:" & @TAB & $iEvent & @CRLF) $lastevent = $iEvent #ce EndIf EndSwitch EndFunc ;==>_EventProc Func GetBelow(ByRef $hDropped) Local $hFoundByArrow = 0, $hFoundByLayer = 0 Local $hPullChild = _WinAPI_GetWindow($hMainWin, $GW_CHILD) ; get the first child from the child's stack (the one being dragged) Local $hDragged = $hPullChild Local $aWin1 = WinGetPos($hPullChild) ; <-- Retrieves the position and size of the dropped "card" $aWin1[2] += $aWin1[0] $aWin1[3] += $aWin1[1] ; Local $t_RECT_Intersection = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") Local $t_RECT_Var = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") Local $t_RECT_Test = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") ; dragged window ; ; Local $a_Pos_hWnd_to_Test = WinGetPos($hWnd_to_Test) ; the dropped window (see $aWin1 above) DllStructSetData($t_RECT_Test, 1, $aWin1[0]) ; x1 upper left DllStructSetData($t_RECT_Test, 2, $aWin1[1]) ; y1 upper left DllStructSetData($t_RECT_Test, 3, $aWin1[2]) ; x2 lower right DllStructSetData($t_RECT_Test, 4, $aWin1[3]) ; y2 lower right Do ; scan all the child windows (child "cards") $hPullChild = _WinAPI_GetWindow($hPullChild, $GW_HWNDnext) ; pull next child from the z-order stack (returns 0 if no more cards) If $hPullChild Then ; if there are still cards in the stack to be checked $aPos = WinGetPos($hPullChild) ; position and size of "card" being checked Local $iAreaOfWinBelow = $aPos[2] * $aPos[3] ; area of the below window $aPos[2] += $aPos[0] $aPos[3] += $aPos[1] $aMxy = MouseGetPos() ; Mouse x and y positions If Not $hFoundByArrow Then ; if not already found the "card" pointed by mouse pointer If $aMxy[0] >= $aPos[0] And $aMxy[0] <= $aPos[2] And $aMxy[1] >= $aPos[1] And $aMxy[1] <= $aPos[3] Then $hFoundByArrow = $hPullChild EndIf ; If $aWin1[0] < $aPos[2] And $aWin1[2] > $aPos[0] And $aWin1[1] < $aPos[3] And $aWin1[3] > $aPos[1] Then ; overlaps If Not $hFoundByLayer Then; if not already found the "card" layered below the dropped $hFoundByLayer = $hPullChild EndIf ; #cs $iOverlap = _Max(0, _Min($aWin1[2], $aPos[2]) - _Max($aWin1[0], $aPos[0])) * _Max(0, _Min($aWin1[3], $aPos[3]) - _Max($aWin1[1], $aPos[1])) $iUnion = (($aWin1[2] - $aWin1[0]) * ($aWin1[3] - $aWin1[1])) + (($aPos[2] - $aPos[0]) * ($aPos[3] - $aPos[1])) - $iOverlap $iRatio = $iOverlap / $iUnion ; $iPercent = Round($iOverlap * 100 / (($aWin1[2] - $aWin1[0]) * ($aWin1[3] - $aWin1[1]))) $iPercent = Round($iOverlap * 100 / (($aPos[2] - $aPos[0]) * ($aPos[3] - $aPos[1]))) ConsolePrint(WinGetTitle($hDragged) & " overlaps " & WinGetTitle($hPullChild) & " for the " & $iPercent & "%" & @CRLF, $hConsole) #ce Local $iRes, $iUnion, $iPercent1, $iPercent1 Local $i_Pixel_hWnd_to_Test = (($aWin1[2] - $aWin1[0]) * ($aWin1[3] - $aWin1[1])) ; full area of dragged window DllStructSetData($t_RECT_Var, 1, $aPos[0]) DllStructSetData($t_RECT_Var, 2, $aPos[1]) DllStructSetData($t_RECT_Var, 3, $aPos[2]) DllStructSetData($t_RECT_Var, 4, $aPos[3]) $iRes = DllCall("user32.dll", "bool", "IntersectRect", "ptr", DllStructGetPtr($t_RECT_Intersection), "ptr", DllStructGetPtr($t_RECT_Var), "ptr", DllStructGetPtr($t_RECT_Test)) If $iRes[0] Then ; the 2 windows overlaps ; Intersection (area of the overlapping portion) $iUnion = (DllStructGetData($t_RECT_Intersection, 3) - DllStructGetData($t_RECT_Intersection, 1)) * (DllStructGetData($t_RECT_Intersection, 4) - DllStructGetData($t_RECT_Intersection, 2)) ; Percentage of hWnd_to_Test intersecting with hWnd $iPercent1 = Round($iUnion / $i_Pixel_hWnd_to_Test, 2) $iPercent2 = Round($iUnion / $iAreaOfWinBelow, 2) ConsolePrint(WinGetTitle($hDragged) & " overlaps " & WinGetTitle($hPullChild) & " for the " & $iPercent1 * 100 & "%" & @CRLF, $hConsole) ConsolePrint(WinGetTitle($hPullChild) & " is covered by " & WinGetTitle($hDragged) & " for the " & $iPercent2 * 100 & "%" & @CRLF & @CRLF, $hConsole) EndIf EndIf EndIf Until Not $hPullChild ; Or ($hFoundByArrow And $hFoundByLayer) Local $aResults[3] = [$hDropped, $hFoundByArrow, $hFoundByLayer] Return $aResults EndFunc ;==>GetBelow Func ConsolePrint($sMSG, ByRef $hConsole) If StringInStr(GUICtrlRead($hConsole) & $sMSG, @LF, 0, -12) Then GUICtrlSetData($hConsole, StringRight(GUICtrlRead($hConsole) & $sMSG, StringLen(GUICtrlRead($hConsole) & $sMSG) - StringInStr(GUICtrlRead($hConsole), @LF, 0, -12))) Else GUICtrlSetData($hConsole, GUICtrlRead($hConsole) & $sMSG) EndIf EndFunc ;==>ConsolePrint Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) EndFunc ;==>OnAutoItExit Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now