mpower

Restrict drag of window to vertical axis only

5 posts in this topic

#1 ·  Posted (edited)

Hi guys,

I'd like to create a drag-out panel that can only be dragged vertically. The idea is that only the lower bit of the panel will be visible at the top of the screen but can be grabbed to drag gui down until the gui is fully visible. 

I attached some screenshots to illustrate what i'm after.

Basically, I'm trying to create an apple ios style drag-out panel (e.g. command centre on iPhone/iPad)

Any help would be super appreciated!

post-75824-0-63012400-1426051204_thumb.j

post-75824-0-44631500-1426051210_thumb.j

post-75824-0-49808100-1426051216_thumb.j

Edited by mpower

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Sorted it myself :D, but please feel free to suggest other ways!

Note I've made it so that after 3 seconds if inactivity the GUI hides itself and doesn't show again until mouse is moved to the top of the screen.

 

Posted it in Examples forum because I reckon it's pretty kewl (if I say so myself hahaha). '?do=embed' frameborder='0' data-embedContent>>

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <SendMessage.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#include <WinAPISys.au3>

Global $moved, $hidden = True

$hGUI = GUICreate("", 793, 717, -1, 0, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_NOACTIVATE + $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
$hGUI_child = GUICreate("", 790, 710, 0,  0, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_MDICHILD + $WS_EX_NOACTIVATE, $hGUI)
GUISetBkColor(0xFFFFFF, $hGUI_child)
_WinAPI_SetLayeredWindowAttributes($hGUI_child, 0xFFFFFF, 0xffffff)
$hIcon = _WinAPI_GetClassLongEx($hGUI, $GCL_HICON)
_WinAPI_DestroyIcon($hIcon)
_WinAPI_SetClassLongEx($hGUI, $GCL_HICON, 0)
_WinAPI_SetClassLongEx($hGUI, $GCL_HICONSM, 0)
_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\panel.png')
SetBitmap($hGUI, $hImage, 0xFF)
_GDIPlus_Shutdown()
WinMove($hGUI, "", Default, -663)
GUISetState(@SW_SHOWNOACTIVATE, $hGUI_child)
GUISetState(@SW_SHOWNOACTIVATE, $hGUI)
AdlibRegister("HiddenTimeout", 3000)

While 1
    $msg = GUIGetMsg(1)
    $cPos = MouseGetPos()
    If $cPos[1] = 0 And $hidden Then
        AdlibUnRegister("HiddenTimeout")
        $hidden = False
        For $i = 695 to 663 Step - 1
            WinMove($hGUI, "", Default, -$i)
            Sleep(10)
        Next
        AdlibRegister("HiddenTimeout", 3000)
    EndIf
    $cgPos = GUIGetCursorInfo($hGUI)
    If $cgPos[1] >= 633 And $cgPos[1] <= 679 And $cgPos[0] >= 350 And $cgPos[0] <= 450 Then
        GUISetCursor(0, 1, $hGUI)
    Else
        GUISetCursor(2, 1, $hGUI)
    EndIf
    Switch $msg[1]
        Case $hGUI
            Switch $msg[0]
                Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYDOWN ;exit on right click
                    Exit
                Case $GUI_EVENT_PRIMARYDOWN
                    AdlibUnRegister("HiddenTimeout")
                    $hidden = False
                    If BitAND($cgPos[1] >= 633, $cgPos[1] <= 679, $cgPos[0] >= 350, $cgPos[0] <= 450) Then
                        If $moved = True Then
                            WinMove($hGUI, "", Default, -663)
                            $moved = False
                            AdlibRegister("HiddenTimeout", 3000)
                        Else
                            $mPos = MouseGetPos()
                            $wPos2 = WinGetPos($hGUI)
                            While _IsPressed(1)
                                $mPos2 = MouseGetPos()
                                $wPos3 = WinGetPos($hGUI)
                                If $wPos3[1] >= -663 And $wPos2[1] + $mPos2[1] - $mPos[1] >= $wPos3[1] Then
                                    If $wPos2[1] + $mPos2[1] - $mPos[1] <= -3 And $wPos2[1] + $mPos2[1] - $mPos[1] >= -661 Then
                                        WinMove($hGUI, "", Default, $wPos2[1] + $mPos2[1] - $mPos[1])
                                        $moved = True
                                    EndIf
                                EndIf
                            WEnd
                        EndIf
                    Else
                        If BitOR(BitAND($cgPos[1] >= 633, $cgPos[1] <= 679), BitAND($cgPos[0] <= 350, $cgPos[0] >= 450)) Then
                            _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_TRANSPARENT))
                            MouseClick('left', Default, Default, 2)
                            _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitAND(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), BitNOT($WS_EX_TRANSPARENT)))
                        EndIF
                    EndIf
            EndSwitch
        Case $hGUI_child
            Switch $msg[0]
                Case $GUI_EVENT_CLOSE
                    Exit
            EndSwitch
    EndSwitch
WEnd

Func HiddenTimeout()
    For $i = 663 to 695 Step 1
        WinMove($hGUI, "", Default, -$i)
        Sleep(10)
    Next
    AdlibUnRegister("HiddenTimeout")
    $hidden = True
EndFunc

Func SetBitmap($hGUI, $hImage, $iOpacity = 255)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, $hGUI, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc   ;==>SetBitmap

post-75824-0-41092500-1426066031_thumb.p

Edited by mpower

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Hmm, so on my latest code (below), I can't seen to be able to click into the Input and enter data. Any solution?

Also I did away with the dragging as it was unnecessary, now the panel fully slides in and out on click.

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <SendMessage.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#include <WinAPISys.au3>
#include <ButtonConstants.au3>

Global $moved, $hidden = True, $showtimer, $showtimerd

$hGUI = GUICreate("", 793, 717, -1, 0, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_NOACTIVATE + $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
$hGUI_child = GUICreate("", 790, 710, 0,  0, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_MDICHILD + $WS_EX_NOACTIVATE, $hGUI)
GUISetBkColor(0xFFFFFF, $hGUI_child)
_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\panel.png')
SetBitmap($hGUI, $hImage, 0xFFFFFF)
_GDIPlus_Shutdown()
_WinAPI_SetLayeredWindowAttributes($hGUI_child, 0xFFFFFF, 0xFFFFFF)
GUISetFont(18, Default, Default, 'Segoe UI', $hGUI_child, 5)
GUICtrlCreateLabel('Filter:', 80, 25)
$testinput = GUICtrlCreateInput('', 150, 20, 100, 35)
$hIcon = _WinAPI_GetClassLongEx($hGUI, $GCL_HICON)
_WinAPI_DestroyIcon($hIcon)
_WinAPI_SetClassLongEx($hGUI, $GCL_HICON, 0)
_WinAPI_SetClassLongEx($hGUI, $GCL_HICONSM, 0)
WinMove($hGUI, "", Default, -663)
GUISetState(@SW_SHOWNOACTIVATE, $hGUI)
GUISetState(@SW_SHOWNOACTIVATE, $hGUI_child)
AdlibRegister("HiddenTimeout", 3000)

While 1
    $msg = GUIGetMsg(1)
    $cPos = MouseGetPos()
    If $showtimer <> '' Then $showtimerd = TimerDiff($showtimer)
    If $cPos[1] = 0 And $hidden And $showtimerd > 1000 Then
        $showtimer = ''
        $showtimerd = ''
        AdlibUnRegister("HiddenTimeout")
        $hidden = False
        For $i = 695 to 663 Step - 1
            WinMove($hGUI, "", Default, -$i)
            Sleep(10)
        Next
        AdlibRegister("HiddenTimeout", 3000)
    Else
        If $cPos[1] = 0 And $hidden And $showtimer = '' Then
            $showtimer = TimerInit()
        ElseIf $cPos[1] <> 0 Then
            $showtimer = ''
        EndIf
    EndIf
    $cgPos = GUIGetCursorInfo($hGUI)
    If $cgPos[1] >= 633 And $cgPos[1] <= 679 And $cgPos[0] >= 350 And $cgPos[0] <= 450 Then
        GUISetCursor(0, 1, $hGUI)
    Else
        GUISetCursor(2, 1, $hGUI)
    EndIf
    Switch $msg[1]
        Case $hGUI
            Switch $msg[0]
                Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYDOWN ;exit on right click
                    Exit
                Case $GUI_EVENT_PRIMARYDOWN
                    AdlibUnRegister("HiddenTimeout")
                    $hidden = False
                    If BitAND($cgPos[1] >= 633, $cgPos[1] <= 679, $cgPos[0] >= 350, $cgPos[0] <= 450) Then
                        If $moved = True Then
                            For $i = -4 to -663 Step - 1
                                WinMove($hGUI, "", Default, $i)
                            Next
                            $moved = False
                            AdlibRegister("HiddenTimeout", 3000)
                        Else
                            For $i = -664 to -4 Step 1
                                WinMove($hGUI, "", Default, $i)
                            Next
                            $moved = True
                        EndIf
                    Else
                        If BitOR(BitAND($cgPos[1] >= 633, $cgPos[1] <= 679), BitAND($cgPos[0] <= 350, $cgPos[0] >= 450)) Then
                            _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_TRANSPARENT))
                            MouseClick('left', Default, Default, 2)
                            _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitAND(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), BitNOT($WS_EX_TRANSPARENT)))
                        EndIF
                    EndIf
            EndSwitch
    EndSwitch
WEnd

Func HiddenTimeout()
    For $i = 663 to 695 Step 1
        WinMove($hGUI, "", Default, -$i)
        Sleep(10)
    Next
    AdlibUnRegister("HiddenTimeout")
    $hidden = True
EndFunc

Func SetBitmap($hGUI, $hImage, $iOpacity = 255)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, $hGUI, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc   ;==>SetBitmap
Edited by mpower

Share this post


Link to post
Share on other sites

I've done away with WS_EX_NOACTIVATE for now as that's what was causing the issue of not being able to access controls.

Does anyone have any ideas on how to keep both the main gui and child gui Inactive (i.e. not focused) but still allow input to controls?

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <SendMessage.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
#include <WinAPISys.au3>
#include <ButtonConstants.au3>

Global $moved, $hidden = True, $showtimer, $showtimerd

$hGUI = GUICreate("", 793, 717, -1, 0, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
$hGUI_child = GUICreate("", 790, 650, 0,  0, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_MDICHILD, $hGUI)
GUISetBkColor(0xFFFF0C, $hGUI_child)
_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\panel.png')
SetBitmap($hGUI, $hImage, 0xFFFFFF)
_GDIPlus_Shutdown()
_WinAPI_SetLayeredWindowAttributes($hGUI_child, 0xFFFF0C, 255)
GUISetFont(18, Default, Default, 'Segoe UI', $hGUI_child, 5)
GUICtrlCreateLabel('Filter:', 80, 25)
$testinput = GUICtrlCreateInput('', 150, 20, 100, 35)
$hIcon = _WinAPI_GetClassLongEx($hGUI, $GCL_HICON)
_WinAPI_DestroyIcon($hIcon)
_WinAPI_SetClassLongEx($hGUI, $GCL_HICON, 0)
_WinAPI_SetClassLongEx($hGUI, $GCL_HICONSM, 0)
WinMove($hGUI, "", Default, -663)
GUISetState(@SW_SHOWNOACTIVATE, $hGUI)
GUISetState(@SW_SHOWNOACTIVATE, $hGUI_child)
AdlibRegister("HiddenTimeout", 3000)

While 1
    $msg = GUIGetMsg(1)
    $cPos = MouseGetPos()
    If $showtimer <> '' Then $showtimerd = TimerDiff($showtimer)
    If $cPos[1] = 0 And $hidden And $showtimerd > 1000 Then
        $showtimer = ''
        $showtimerd = ''
        AdlibUnRegister("HiddenTimeout")
        $hidden = False
        For $i = 695 to 663 Step - 1
            WinMove($hGUI, "", Default, -$i)
            Sleep(10)
        Next
        AdlibRegister("HiddenTimeout", 3000)
    Else
        If $cPos[1] = 0 And $hidden And $showtimer = '' Then
            $showtimer = TimerInit()
        ElseIf $cPos[1] <> 0 Then
            $showtimer = ''
        EndIf
    EndIf
    $cgPos = GUIGetCursorInfo($hGUI)
    If $cgPos[1] >= 633 And $cgPos[1] <= 679 And $cgPos[0] >= 350 And $cgPos[0] <= 450 Then
        GUISetCursor(0, 1, $hGUI)
    Else
        GUISetCursor(2, 1, $hGUI)
    EndIf
    Switch $msg[1]
        Case $hGUI
            Switch $msg[0]
                Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYDOWN ;exit on right click
                    Exit
                Case $GUI_EVENT_PRIMARYDOWN
                    AdlibUnRegister("HiddenTimeout")
                    $hidden = False
                    If BitAND($cgPos[1] >= 633, $cgPos[1] <= 679, $cgPos[0] >= 350, $cgPos[0] <= 450) Then
                        If $moved = True Then
                            For $i = -4 to -663 Step - 1
                                WinMove($hGUI, "", Default, $i)
                            Next
                            $moved = False
                            AdlibRegister("HiddenTimeout", 3000)
                        Else
                            For $i = -664 to -4 Step 1
                                WinMove($hGUI, "", Default, $i)
                            Next
                            $moved = True
                        EndIf
                    Else
                        If BitOR(BitAND($cgPos[1] >= 633, $cgPos[1] <= 679), BitAND($cgPos[0] <= 350, $cgPos[0] >= 450)) Then
                            _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_TRANSPARENT))
                            MouseClick('left', Default, Default, 2)
                            _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitAND(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), BitNOT($WS_EX_TRANSPARENT)))
                        EndIF
                    EndIf
            EndSwitch
    EndSwitch
WEnd

Func HiddenTimeout()
    For $i = 663 to 695 Step 1
        WinMove($hGUI, "", Default, -$i)
        Sleep(10)
    Next
    AdlibUnRegister("HiddenTimeout")
    $hidden = True
EndFunc

Func SetBitmap($hGUI, $hImage, $iOpacity = 255)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, $hGUI, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc   ;==>SetBitmap

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