mpower

Slide-out top of screen panel GUI. Hides itself after timeout and peeks-out when mouse is moved to top of screen.

14 posts in this topic

#1 ·  Posted (edited)

Hi everyone, I've created a GUI that hides at the top of the screen, peeks out when mouse is held at top of screen for over ~1 second and can be clicked to slide down to display the GUI contents. Then it can be clicked again to slide away and hide after a timeout (~2.5 seconds).

UPDATE 14/03/2015Script has been completely overhauled and updated. Hope to get some feedback and perhaps improvements.

Now also works in both Aero and non-Aero environments.

Please make sure you download the two attached PNG files (NOT THEIR THUMBNAILS) to experience the GUI in whole glory (if you have Aero enabled).

Feedback appreciated :). Please do excuse me if something is not scripted in the best way possible, I am learning new things ever day and improving my autoit skills continuously.

#include-once
#NoTrayIcon
#AutoIt3Wrapper_Outfile=Example.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_UseX64=n
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <WinAPIEx.au3>

Global $bAero, $hidden = False, $tuck = False, $tucked = False, $untucked = False, $tucking = False, $untucking = False, $timer = 0, $tdiff = 0, _
$LAYERED_GUI = $WS_EX_LAYERED, $hGUI_child, $hGUI_height = 683
Global Const $hDwmApiDll = DllOpen("dwmapi.dll"), $sChkAero = DllStructCreate("int;")
DllCall($hDwmApiDll, "int", "DwmIsCompositionEnabled", "ptr", DllStructGetPtr($sChkAero))
$bAero = DllStructGetData($sChkAero, 1)
If Not $bAero Then
    $LAYERED_GUI = 0
    $hGUI_height = $hGUI_height - 20
EndIf

$hGUI = GUICreate("", 715, $hGUI_height, -1, 0, $WS_POPUP, $LAYERED_GUI + $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
$hIcon = _WinAPI_GetClassLongEx($hGUI, $GCL_HICON)
_WinAPI_DestroyIcon($hIcon)
_WinAPI_SetClassLongEx($hGUI, $GCL_HICON, 0)
_WinAPI_SetClassLongEx($hGUI, $GCL_HICONSM, 0)

If $bAero Then
    $hGUI_child = GUICreate("", 715-39, 683 - 26, 22,  3, $WS_POPUP, $WS_EX_MDICHILD + $WS_EX_TOPMOST, $hGUI)
    $hGUI_Font = $hGUI_child
Else
    $hGUI_Font = $hGUI
    $hGUI_child = $hGUI
EndIf
GUISetBkColor(0xFFFFFF)
GUISetFont(18, 100, Default, 'Segoe UI', $hGUI_Font, 5)
GUICtrlCreateLabel('Example lbl:', 10, 25)
GUICtrlCreateInput('input', 150, 20, 100, 35)
$testbutton = GUICtrlCreateButton('Example button', 100, 250)
GUISetFont(12, 100, Default, 'Segoe UI', $hGUI_Font, 5)
GUICtrlCreateLabel('Right click on GUI to exit', 100, 500)

$hGUI_child2 = GUICreate("", 112, 50, 299, 645, $WS_POPUP, $LAYERED_GUI + $WS_EX_MDICHILD + $WS_EX_TOPMOST, $hGUI_child)
If Not $bAero Then
    GUISetBkColor(0xE0F2F7)
    $hGUI_Font = $hGUI_child2
    GUISetFont(33, 100, Default, 'Segoe UI', $hGUI_Font, 5)
    GUICtrlCreateLabel(" = ", 0, 0, 112, 50, $SS_CENTER + $SS_CENTERIMAGE)
EndIf
GUISetCursor(0, 1, $hGUI_child2)

If $bAero Then
    _GDIPlus_Startup()
    $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\panel.png')
    SetBitmap($hGUI, $hImage)
    $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\roundbn.png')
    SetBitmap($hGUI_child2, $hImage)
    _GDIPlus_Shutdown()
EndIf

GUISetState(@SW_SHOW, $hGUI)
If $bAero Then GUISetState(@SW_SHOW, $hGUI_child)
GUISetState(@SW_SHOW, $hGUI_child2)

While 1
    $mPos = MouseGetPos()
    If BitAnd($hidden, $mPos[1] = 0, $timer = 0) Then
        $timer = TimerInit()
        Sleep(10)
    ElseIf $mPos[1] <> 0 Then
        $timer = 0
        $tdiff = 0
    EndIf
    If $timer <> 0 Then $tdiff = TimerDiff($timer)
    If BitAND($hidden, Not $tucked, $mPos[1] <> 0, Not $tucking) Then
        $tuck = True
        $untucking = False
        $tucking = True
        AdlibRegister("TuckAway", 2500)
    ElseIf BitAND($hidden, $tucked, $mPos[1] = 0, Not $untucking, $tdiff > 450) Then
        $tuck = False
        $tucking = False
        $untucking = True
        AdlibRegister("TuckAway")
    ElseIf BitAND($hidden, Not $tucked, $mPos[1] = 0, $tucking) Then
        AdlibUnRegister("TuckAway")
        $tuck = False
        $tucking = False
    EndIf
    $msg = GUIGetMsg(1)
    Switch $msg[1]
        Case $hGUI
            Switch $msg[0]
                Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYUP
                    Exit
                Case $testbutton
                    MsgBox(0,'Button','You clicked a button!', 0, $hGUI)
            EndSwitch
        Case $hGUI_child
            Switch $msg[0]
                Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYUP
                    Exit
                Case $testbutton
                    MsgBox(0,'Button','You clicked a button!', 0, $hGUI_child)
            EndSwitch
        Case $hGUI_child2
            Switch $msg[0]
                Case $GUI_EVENT_PRIMARYDOWN
                    If Not $hidden Then
                        HidePanel()
                    Else
                        HidePanel(False)
                    EndIf
            EndSwitch
    EndSwitch
WEnd

Func HidePanel($hide = True)
    AdlibUnRegister("TuckAway")
    If $hide Then
        $tucked = False
        $untucked = True
        $hidden = True
        For $i = -1 to -663 Step - 1
            WinMove($hGUI, "", Default, $i)
        Next
    Else
        $tucked = False
        $untucked = False
        $hidden = False
        For $i = -664 to -4 Step 1
            WinMove($hGUI, "", Default, $i)
        Next
    EndIf
EndFunc

Func TuckAway()
    If $tuck Then
        $tucking = False
        $untucked = False
        $tucked = True
        For $i = 663 to 695 Step 1
            WinMove($hGUI, "", Default, -$i)
            Sleep(10)
        Next
    Else
        $untucking = False
        $tucked = False
        For $i = 695 to 663 Step - 1
            WinMove($hGUI, "", Default, -$i)
            Sleep(10)
        Next
    EndIf
    AdlibUnRegister("TuckAway")
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

post-75824-0-96433600-1426251001_thumb.p

post-75824-0-02363500-1426251003.png

Edited by mpower
3 people like this

Share this post


Link to post
Share on other sites



I need to comment ;~ WinMove($hGUI, "", Default, -663) for see the gui

and i can't drag it... :huh2:


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

Odd, works here on different machines... all running win7 64bit and Autoit 3.3.12.0

I need to comment ;~ WinMove($hGUI, "", Default, -663) for see the gui

and i can't drag it... :huh2:

Share this post


Link to post
Share on other sites

all running win7 64bit and Autoit 3.3.12.0

 

Same for me.


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

So you can see the panel but can't drag it?

UPDATE: I've updated the script in OP. Now you need to hold mouse on top of screen for at least 1 second for get the gui to peek out for dragging. As before it will hide after 3 seconds of inactivity

Share this post


Link to post
Share on other sites

Ok i have found why.

I have dragged your png on my desktop but it give me the thumbnail 320x290, instead of the full image 793x717

So now it works. -_-


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

#7 ·  Posted (edited)

Ah ! That makes sense ;). Glad it works! Feedback?

EDIT: I've updated the Script in OP (removed the draggable aspect of the gui as it was unnecessary and replaced with a slide-out/slid-in on click style instead)

Edited by mpower

Share this post


Link to post
Share on other sites

I've updated the Script in OP (removed the draggable aspect of the gui as it was unnecessary and replaced with a slide-out/slid-in on click style instead)

Can you elaborate on how it's now supposed to work?

On Win 7 Pro (without Aero) the script runs (doesn't abort), but it doesn't respond to any mouse actions at the edge of the screen.

How should I be triggering it?

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Can you elaborate on how it's now supposed to work?

On Win 7 Pro (without Aero) the script runs (doesn't abort), but it doesn't respond to any mouse actions at the edge of the screen.

How should I be triggering it?

 

Thanks qwert, I've looked into it and it seems that Aero is necessary for this to work. So I've added an Aero check at the start of the application.

Script has been updated in OP.

Edited by mpower

Share this post


Link to post
Share on other sites

Thanks for the clarification.

Is there any chance your original method worked without Aero?

I ask because I have a good application in mind for this, but I can't require users to enable Aero ... especially since I don't run it myself.

Share this post


Link to post
Share on other sites

Script has been completely overhauled and updated. Hope to get some feedback and perhaps improvements.

qwert, you'll be happy to know that I've made this compatible with non-Aero windows environments :)

Share this post


Link to post
Share on other sites

I've made this compatible with non-Aero windows environments

Thanks for that.

It looks good on a quick first pass.  I'll be able to take a closer look next week.

Share this post


Link to post
Share on other sites

Just a couple of quick comments, as I haven't had time to test very much:

First, I found that changing the trigger for right-click close from $GUI_EVENT_SECONDARYDOWN to $GUI_EVENT_SECONDARYUP avoids having the click pass through to the underlying window, whatever that window might be.

Second, I'm curious why in non-Aero mode, there's a need to avoid using the PNGs ... as in:

    $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & 'panel.png')
    SetBitmap($hGUI, $hImage)
 

I use PNGs all the time in non-Aero GUIs, primarily as backgrounds.  Can you clarify what's missing in the non-Aero environment that your method needs?

Share this post


Link to post
Share on other sites

Thanks qwert, using $GUI_EVENT_SECONDARYUP is definitely better :) I've updated this in the script in OP.

I'm not sure why my script doesn't work in non-Aero with PNG to be honest, if you could suggest a workaround that would be really awesome, I've tried multiple things and just can't seem to get it to work so I've done away with it for the time being (until a solution is found).

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