Sign in to follow this  
Followers 0
ChrisL

Limiting Child Drag using $GUI_WS_EX_PARENTDRAG

6 posts in this topic

#1 ·  Posted (edited)

Here is a reproducer script of my problem.

Drag the little Merlins around and they are bound to the inner cell.

Drag left right up and down and all seems to work.

Now, drag the little merlin up and Keep going up with your mouse then release the mouse when it is way above the main gui.

The Cell window shrinks in height, it never does it with left, right or down only when you drag up.

(I'm using Win7 this may not be relevant!)

Any ideas?

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

Opt("GuiOnEventMode",1)
Opt("MustDeclareVars",1)

Global $HWNDMAIN, $GUI_W = 800, $GUI_H = 600
Global $HWNDCHILD, $Child_W = 600, $Child_H = 400
Global $activePackage = 0, $activeChildren[1] = [0], $activeCell = 0

$HWNDMAIN = GUICreate("Main", $GUI_W, $GUI_H, Default, Default)
GUISetOnEvent($GUI_EVENT_CLOSE,"_Exit")
GUISetState()

$HWNDCHILD = GUICreate("",$Child_W,$Child_H,100, 100, BitOR($WS_POPUP,$WS_BORDER),$WS_EX_MDICHILD,$HWNDMAIN)
GUISetBkColor(0xFFFFBB)
GUISetState()
$activePackage = $HWNDCHILD ;Simulates something from full script
GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")

_CreateCell($HWNDCHILD, 136, 142 )
_CreateCell($HWNDCHILD, 136, 142 )



While 1
    Sleep(250)
WEnd


Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)

    ConsoleWrite("WM_WINDOWPOSCHANGING" & @CRLF)
        Local $i
        For $i = 1 to $activeChildren[0]
            If $hWnd = $activeChildren[$i] then
                $activeCell = $HWND
                ConsoleWrite($activeCell & @CRLF)
                ExitLoop
            EndIf
        Next


    If $hWnd <> $activeCell then Return
    If $activePackage = 0 then Return

    Local $aMain_Pos = WinGetPos($activePackage) ;Get the position of the ParentCell
    If NOT IsArray($aMain_Pos) then Return

            ;Get the position of the window which is currently dragging and specify the drag limits
            Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam)
            Local $iLeft = DllStructGetData($stWinPos, 3)
            Local $iTop = DllStructGetData($stWinPos, 4)
            Local $iWidth = DllStructGetData($stWinPos, 5)
            Local $iHeight = DllStructGetData($stWinPos, 6)
            Local $iX_Min = $aMain_Pos[0]
            Local $iY_Min = $aMain_Pos[1]
            Local $iX_Max = $aMain_Pos[0] + $aMain_Pos[2] - $iWidth
            Local $iY_Max = $aMain_Pos[1] + $aMain_Pos[3] - $iHeight


            ConsoleWrite("X = " & $iLeft & @CRLF & _
                        "Y = " & $iTop & @CRLF & _
                        "W = " & $iWidth & @CRLF & _
                        "H = " & $iHeight & @crlf)

            If $iLeft < $iX_Min Then DllStructSetData($stWinPos, 3, $iX_Min)

            If $iLeft > $iX_Max Then DllStructSetData($stWinPos, 3, $iX_Max)

            If $iTop < $iY_Min Then DllStructSetData($stWinPos, 4, $iY_Min) ;<<<<<<<<<<<<< This one doesn't obey properly and if the mouse continues to drag up the window will be resized after mouse is released

            If $iTop > $iY_Max Then DllStructSetData($stWinPos, 4, $iY_Max)

    Return $GUI_RUNDEFMSG

EndFunc


Func _CreateCell($vHWND, $w,$h )


    Local $HWNDCHILD = GUICreate("",$w, $h, 1, 1, BitOR($WS_POPUP,$WS_BORDER),$WS_EX_MDICHILD,$vHWND)
    GUICtrlCreatePic(@ProgramFilesDir & "\AutoIt3\Examples\GUI\Merlin.gif",0,0,$w,$h,Default,$GUI_WS_EX_PARENTDRAG)
    GUISetState()
    ReDim $activeChildren[$activeChildren[0] +2]
    $activeChildren[$activeChildren[0] +1] = $HWNDCHILD
    $activeChildren[0] +=1

    Return $HWNDCHILD

EndFunc


Func _Exit()
    Exit
EndFunc

This is the problem I'm seeing

Posted Image

Edited by ChrisL

Share this post


Link to post
Share on other sites



I'm on XpSp3 and there is no bug.


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

It doesn't work on Windows 7 x64 until I use #AutoIt3Wrapper_UseX64=N As to what caused this is something I can't answer right now :unsure:


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Here is how I got round it if anyone is interested, although I'm not sure why I needed to get round it!

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <misc.au3>

Opt("GuiOnEventMode",1)
Opt("MustDeclareVars",1)

Global $HWNDMAIN, $GUI_W = 800, $GUI_H = 600
Global $HWNDCHILD, $Child_W = 600, $Child_H = 400
Global $activePackage = 0, $activeChildren[1] = [0], $GUI_CTRLID = 0

$HWNDMAIN = GUICreate("Main", $GUI_W, $GUI_H, Default, Default)
GUISetOnEvent($GUI_EVENT_CLOSE,"_Exit")
GUISetState()

$HWNDCHILD = GUICreate("",$Child_W,$Child_H,100, 100, BitOR($WS_POPUP,$WS_BORDER),$WS_EX_MDICHILD,$HWNDMAIN)
GUISetBkColor(0xFFFFBB)
GUISetState()
$activePackage = $HWNDCHILD ;Simulates something from full script
GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")

_CreateCell($HWNDCHILD, 136, 142 )
_CreateCell($HWNDCHILD, 136, 142 )



While 1
    Sleep(250)
WEnd


Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)

    ConsoleWrite("WM_WINDOWPOSCHANGING" & @CRLF)

        Local $i, $activeCell = 0
        For $i = 1 to $activeChildren[0]
            If $hWnd = $activeChildren[$i] then
                $activeCell = $HWND
                ConsoleWrite($activeCell & @CRLF)
                ExitLoop
            EndIf
        Next

    If WinActive($HWNDMAIN) then Return
    If $hWnd <> $activeCell then Return
    If $activePackage = 0 then Return

    Local $aMain_Pos = WinGetPos($activePackage) ;Get the position of the ParentCell
    If NOT IsArray($aMain_Pos) then Return

    Local $aCell_Pos = WinGetPos($HWND) ;<< patch
    If NOT IsArray($aCell_Pos) then Return


            ;Get the position of the window which is currently dragging and specify the drag limits
            Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam)
            Local $iLeft = DllStructGetData($stWinPos, 3)
            Local $iTop = DllStructGetData($stWinPos, 4)
            Local $iWidth = $aCell_Pos[2] ;<< patch DllStructGetData($stWinPos, 5)
            Local $iHeight = $aCell_Pos[3] ;<< patch DllStructGetData($stWinPos, 6)

            If DllStructGetData($stWinPos, 5) <> $iWidth then DllStructSetData($stWinPos, 5, $iWidth)
            If DllStructGetData($stWinPos, 6) <> $iHeight then DllStructSetData($stWinPos, 6, $iHeight)

            Local $iX_Min = $aMain_Pos[0]
            Local $iY_Min = $aMain_Pos[1]
            Local $iX_Max = ($aMain_Pos[0] + $aMain_Pos[2]) - $iWidth
            Local $iY_Max = ($aMain_Pos[1] + $aMain_Pos[3]) - $iHeight


            ConsoleWrite("X = " & $iLeft & @CRLF & _
                        "Y = " & $iTop & @CRLF & _
                        "W = " & $iWidth & @CRLF & _
                        "H = " & $iHeight & @crlf)


            If $iLeft < $iX_Min Then DllStructSetData($stWinPos, 3, $iX_Min)

            If $iLeft > $iX_Max Then DllStructSetData($stWinPos, 3, $iX_Max)

            If $iTop < $iY_Min Then DllStructSetData($stWinPos, 4, $iY_Min)

            If $iTop > $iY_Max Then DllStructSetData($stWinPos, 4, $iY_Max)



    Return $GUI_RUNDEFMSG

EndFunc


Func _CreateCell($vHWND, $w,$h )


    Local $HWNDCHILD = GUICreate("",$w, $h, 1, 1, BitOR($WS_POPUP,$WS_BORDER),$WS_EX_MDICHILD,$vHWND)
    GUICtrlCreatePic(@ProgramFilesDir & "\AutoIt3\Examples\GUI\Merlin.gif",0,0,$w,$h, $WS_CLIPSIBLINGS ,$GUI_WS_EX_PARENTDRAG)
    GUICtrlCreateLabel("",0,0,$w,$h,Default,$GUI_WS_EX_PARENTDRAG)
    GUICtrlSetOnEvent(-1,"_MouseClick")
    GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT)
    GUISetState()
    ReDim $activeChildren[$activeChildren[0] +2]
    $activeChildren[$activeChildren[0] +1] = $HWNDCHILD
    $activeChildren[0] +=1

    Return $HWNDCHILD

EndFunc

Func _MouseClick()

    $GUI_CTRLID = @GUI_CtrlId

EndFunc


Func _Exit()
    Exit
EndFunc

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0