Sign in to follow this  
Followers 0
andygo

[SOLVED] Slide Button

13 posts in this topic

#1 ·  Posted (edited)

hello, i try to create a slide-button (on/off) like on iphone:

#include <GUIConstantsEx.au3>
$main = GUICreate("islider", 403, 54)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
GUISetBkColor(0xffffff, $main)
$s1 = GUICtrlCreatePic("slid.bmp", 0, 0, 296, 54)
GUICtrlSetOnEvent($s1, "_sl")
$a = GUICtrlCreateLabel("", 0, 0, 108, 54)
GUICtrlCreateLabel("", 108, 0, 2, 2)
GUICtrlCreateLabel("", 110, 0, 1, 1)
GUICtrlCreateLabel("", 108, 2, 1, 1)
GUICtrlCreateLabel("", 108, 52, 2, 2)
GUICtrlCreateLabel("", 108, 51, 1, 1)
GUICtrlCreateLabel("", 110, 53, 1, 1)
$b = GUICtrlCreateLabel("", 296, 0, 107, 54)
GUISetState(@SW_SHOW)
Opt("GuiOnEventMode", 1)

func _sl()
$i = 0
Do
    ControlMove ("islider", "", $s1, $i, 0)
    GUICtrlSetState($s1, @SW_DISABLE)
    GUICtrlDelete($b)
    $b = GUICtrlCreateLabel("", 296, 0, 107, 54)
    sleep(1)
    $i += 7
Until $i >= 109
GUICtrlDelete($s1)
$s1 = GUICtrlCreatePic("slid.bmp", 107, 0, 296, 54)
GUICtrlSetOnEvent($s1, "_sl2")
GUICtrlDelete($b)
$b = GUICtrlCreateLabel("", 296, 0, 107, 54)
endfunc
func _sl2()
$i = 107
Do
    ControlMove ("islider", "", $s1, $i, 0)
    GUICtrlSetState($s1, @SW_DISABLE)
    GUICtrlDelete($a)
    $a = GUICtrlCreateLabel("", 0, 0, 108, 54)
    sleep(1)
    $i -= 7
Until $i <= 0
GUICtrlDelete($s1)
$s1 = GUICtrlCreatePic("slid.bmp", 0, 0, 296, 54)
GUICtrlSetOnEvent($s1, "_sl")
GUICtrlDelete($a)
$a = GUICtrlCreateLabel("", 0, 0, 108, 54)
endfunc

func _quit()
    Exit
EndFunc

While 1
    sleep(20)
WEnd

but there is some flickering during slide. is it possible to get rid of it?

script is very alpha and not as professional as it could be...

slid.bmp

Edited by andygo

Share this post


Link to post
Share on other sites



hello,

ok i played also a bit with the values, and found another flicker-free way:

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
$hGUI = GUICreate("GDI+", 200, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
GUISetbkColor(0xe0e0e0)
GUISetState()
Opt("GuiOnEventMode", 1)
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromFile ( "slid2.bmp")
$hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36, 0, 63, 18)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 );possible to make this area clickable???
$s1 = GUICtrlCreateButton("test", 50, 25, 60, 18)
GUICtrlSetOnEvent($s1, "_sl")
$state = 0

func _sl()
    $i = 0
    Do
        _GDIPlus_ImageDispose ($hClone)
        if $state = 0 then
            $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36-$i, 0, 63, 18)
        Else
            $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, $i, 0, 63, 18)
        endif
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 )
        sleep(1)
        $i += 2
    Until $i >= 37
    if $state = 0 then
        $state = 1
    Else
        $state = 0
    endif
endfunc

func _quit()
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose ($hClone)
    _WinAPI_DeleteObject ($hBitmap)
    _GDIPlus_Shutdown ()
    Exit
EndFunc

While 1
    sleep(20)
WEnd

but there's a litte "problem": the _GDIPlus_GraphicsDrawImageRect itself should be clickable. is this possible?

slid2.bmp

Share this post


Link to post
Share on other sites

Haven't had much chance to script in autoit3 lately so am feeling a bit rusty. Make sure I disposed of all objects etc.

I would draw the slider into a guictrlpic and then capture the clicks on the guictrl.

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
$hGUI = GUICreate("GDI+", 200, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
GUISetbkColor(0xe0e0e0)
GUISetState()
Opt("GuiOnEventMode", 1)



global $pic = GUICtrlCreatePic("", 50,50,100, 18)
    background(-1,36)
GUICtrlSetOnEvent($pic, "_sl")
$state = 0

func _sl()
     if $state = 0 then
        $i = 36
        Do
           background($pic,$i)
           sleep(1)
           $i -= 2
       Until $i <= 0
       $state = 1
   else
            $i = 0
        Do
           background($pic,$i)
           sleep(1)
           $i += 2
       Until $i >= 36
       $state = 0
    EndIf

    
endfunc

func _quit()
    Exit
EndFunc

While 1
    sleep(20)
WEnd

func background($control,$x)
    _GDIPlus_Startup ()
    $hwd=GUICtrlGetHandle($control)
    ;$guiname=_WinAPI_GetParent($hwd)
    $width=_WinAPI_GetClientWidth($hwd)
    $height=_WinAPI_GetClientHeight($hwd)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hwd)
    $hBitmap1 = _GDIPlus_BitmapCreateFromGraphics($width,$height, $hGraphic)

    $hGraphic2 = _GDIPlus_ImageGetGraphicsContext($hBitmap1) 

$iconname=@ScriptDir & "\slid2.bmp"
$icon = _GDIPlus_ImageLoadFromFile($iconname)
$hClone = _GDIPlus_BitmapCloneArea ($icon, $x, 0, 63, 18)
    _GDIPlus_GraphicsDrawImageRect($hGraphic2, $hClone, 0, 0, 63, $height)

    $hImage1 = _GDIPlus_ImageGetGraphicsContext($hBitmap1)
    _GDIPlus_GraphicsSetSmoothingMode($hImage1, 2)
    $hBMP1 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap1)
     _WinAPI_DeleteObject(GUICtrlSendMsg($control, 0x0172, 0, $hBMP1))
    _GDIPlus_ImageDispose ($hImage1)
    _GDIPlus_ImageDispose ($hClone)
    _WinAPI_DeleteObject($hBMP1)
    _WinAPI_DeleteObject($hBitmap1)
    _GDIPlus_GraphicsDispose ($hGraphic)
        _GDIPlus_GraphicsDispose ($hGraphic2)
        _GDIPlus_ImageDispose($icon)
    _GDIPlus_Shutdown ()
EndFunc

Share this post


Link to post
Share on other sites

hello, during my jogging i had another idea, works almost like picea892's one:

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
$hGUI = GUICreate("GDI+", 200, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
GUISetbkColor(0xe0e0e0)
GUISetState()
Opt("GuiOnEventMode", 1)
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromFile ( "slid2.bmp")
$hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36, 0, 63, 18)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 )
$s1 = GUICtrlCreatePic("sb.bmp", 50, 50, 27, 18)
GUICtrlSetOnEvent($s1, "_sl")
$state = 0

func _sl()
    GUICtrlDelete($s1)
    $i = 0
    Do
        _GDIPlus_ImageDispose ($hClone)
        if $state = 0 then
            $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36-$i, 0, 63, 18)
        Else
            $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, $i, 0, 63, 18)
        endif
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 )
        sleep(1)
        $i += 2
    Until $i >= 37
    if $state = 0 then
        $state = 1
        $s1 = GUICtrlCreatePic("sb.bmp", 86, 50, 27, 18)
GUICtrlSetOnEvent($s1, "_sl")
    Else
        $state = 0
        $s1 = GUICtrlCreatePic("sb.bmp", 50, 50, 27, 18)
GUICtrlSetOnEvent($s1, "_sl")
    endif
endfunc

func _quit()
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose ($hClone)
    _WinAPI_DeleteObject ($hBitmap)
    _GDIPlus_Shutdown ()
    Exit
EndFunc

While 1
    sleep(20)
WEnd

i seperate the buttongraphic between 0 and 1 and place it as a ctrlpic. works fine

Share this post


Link to post
Share on other sites

One more possibility for you using point in rect.

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
$hGUI = GUICreate("GDI+", 200, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
GUISetbkColor(0xe0e0e0)
GUISetState()
Opt("GuiOnEventMode", 1)
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromFile ( "slid2.bmp")
$hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36, 0, 63, 18)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 );possible to make this area clickable???
$s1 = GUICtrlCreateButton("test", 50, 25, 60, 18)
GUICtrlSetOnEvent($s1, "_sl")
$state = 0
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "InRect")

func _sl()
    $i = 0
    Do
        _GDIPlus_ImageDispose ($hClone)
        if $state = 0 then
            $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36-$i, 0, 63, 18)
        Else
            $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, $i, 0, 63, 18)
        endif
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 )
        sleep(1)
        $i += 2
    Until $i >= 37
    if $state = 0 then
        $state = 1
    Else
        $state = 0
    endif
endfunc

func _quit()
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose ($hClone)
    _WinAPI_DeleteObject ($hBitmap)
    _GDIPlus_Shutdown ()
    Exit
EndFunc

While 1
    sleep(20)
WEnd

Func InRect()
    ; Set client mouse coord option and save current setting
    $iOldOpt = Opt("MouseCoordMode", 2)
    ; Set up rectangle at button coords
    Local $tRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
    DllStructSetData($tRect, "Left", 50)
    DllStructSetData($tRect, "Top", 50)
    DllStructSetData($tRect, "Right", 113)
    DllStructSetData($tRect, "Bottom", 68)
    ; Get mouse position
    Local $aPos = MouseGetPos()
    ; See if mouse over rectangle
    Local $aResult = DllCall("User32.dll", "int", "PtInRect", "ptr", DllStructGetPtr($tRect), "int", $aPos[0], "int", $aPos[1])
    If @error Then Return
    ; Act if over button
    If $aResult[0] <> 0 Then _sl()
    ; Reset original mouse coord option
    Opt("MouseCoordMode", $iOldOpt)

EndFunc

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I think you have to use ControlMove() :)

For idea's how, just look at my PowerSlide2Unlock (link in sign)

Edited by AppTux

PowerSlide2UnlockiPhone look-a-like program you can use to lock your pc, you can't access your desktop again until the password is entered and the slider slided to the right. (really proud of it)-- After a time AutoIt and Windows, I switched to Mac. Don't expect me to answer anymore.

Share this post


Link to post
Share on other sites

I think you have to use ControlMove() :)

For idea's how, just look at my PowerSlide2Unlock (link in sign)

hello, i took a look on your UDF, on my 4-screen-system it only locks the main-screen (redcrossed)

Posted Image

and if i hit the windows-button on keyboard i have access to the windows-bar.

Share this post


Link to post
Share on other sites

One more possibility for you using point in rect.

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
$hGUI = GUICreate("GDI+", 200, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
GUISetbkColor(0xe0e0e0)
GUISetState()
Opt("GuiOnEventMode", 1)
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromFile ( "slid2.bmp")
$hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36, 0, 63, 18)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 );possible to make this area clickable???
$s1 = GUICtrlCreateButton("test", 50, 25, 60, 18)
GUICtrlSetOnEvent($s1, "_sl")
$state = 0
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "InRect")

func _sl()
    $i = 0
    Do
        _GDIPlus_ImageDispose ($hClone)
        if $state = 0 then
            $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36-$i, 0, 63, 18)
        Else
            $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, $i, 0, 63, 18)
        endif
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 )
        sleep(1)
        $i += 2
    Until $i >= 37
    if $state = 0 then
        $state = 1
    Else
        $state = 0
    endif
endfunc

func _quit()
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose ($hClone)
    _WinAPI_DeleteObject ($hBitmap)
    _GDIPlus_Shutdown ()
    Exit
EndFunc

While 1
    sleep(20)
WEnd

Func InRect()
    ; Set client mouse coord option and save current setting
    $iOldOpt = Opt("MouseCoordMode", 2)
    ; Set up rectangle at button coords
    Local $tRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
    DllStructSetData($tRect, "Left", 50)
    DllStructSetData($tRect, "Top", 50)
    DllStructSetData($tRect, "Right", 113)
    DllStructSetData($tRect, "Bottom", 68)
    ; Get mouse position
    Local $aPos = MouseGetPos()
    ; See if mouse over rectangle
    Local $aResult = DllCall("User32.dll", "int", "PtInRect", "ptr", DllStructGetPtr($tRect), "int", $aPos[0], "int", $aPos[1])
    If @error Then Return
    ; Act if over button
    If $aResult[0] <> 0 Then _sl()
    ; Reset original mouse coord option
    Opt("MouseCoordMode", $iOldOpt)

EndFunc

this also works flicker-free, thanks. :)

Share this post


Link to post
Share on other sites

finally i cleaned up my code a bit and now using this version:

you only need the slid2.bmp.

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
$hGUI = GUICreate("GDI+", 200, 150)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")
GUISetbkColor(0xe0e0e0)
GUISetState()
Opt("GuiOnEventMode", 1)
local $s1, $state = 0, $slide0 = 1, $slide1 = 1
_slider(0, 0); first 0 means initiate the switch, second 0 means no sliding delay

func _slider($slide0 = 1, $slide1 = 1)
    if $slide0 = 1 or $slide0 = 2 then GUICtrlDelete($s1)
    _GDIPlus_Startup ()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hgui)
    $hBitmap = _GDIPlus_BitmapCreateFromFile ( @ScriptDir & "\slid2.bmp")
    if $state = 0 then
        $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36, 0, 63, 18)
    else
        $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 0, 0, 63, 18)
    endif
    $i = 0
    if $slide0 = 1 then
        Do
            _GDIPlus_ImageDispose ($hClone)
            if $state = 0 then
                $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, 36-$i, 0, 63, 18)
            Else
                $hClone = _GDIPlus_BitmapCloneArea ($hbitmap, $i, 0, 63, 18)
            endif
            _GDIPlus_GraphicsDrawImageRect($hGraphic, $hclone, 50, 50, 63, 18 )
            sleep($slide1)
            $i += 2
        Until $i >= 37
    endif
    _GDIPlus_ImageSaveToFile($hclone, @ScriptDir & "\sb.bmp")
    $s1 = GUICtrlCreatePic(@ScriptDir & "\sb.bmp", 50, 50, 63, 18 )
    GUICtrlSetOnEvent($s1, "_slider"); uses the local defined function-variables, similar to _slider(1, 1)
    if $slide0 = 1 and $state = 0 then
        $state = 1
    Elseif $slide0 = 1 and $state = 1 then
        $state = 0
    endif
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose ($hClone)
    _WinAPI_DeleteObject ($hBitmap)
    _GDIPlus_Shutdown ()
endfunc

func _quit()
    Exit
EndFunc

While 1
    sleep(20)
WEnd

it's compatible on both GuiOnEventMode's 0 and 1

thanks all for your ideas.

Share this post


Link to post
Share on other sites

hello, i took a look on your UDF, on my 4-screen-system it only locks the main-screen (redcrossed)

Posted Image

and if i hit the windows-button on keyboard i have access to the windows-bar.

Yes I know, I still have no multi-monitor support, and I don't have multiple monitors... :)

Well, I don't know why it's not working... You have copied the code in the topic??? Because if you use the code in the .zip, it won't work, because that's a old version :)


PowerSlide2UnlockiPhone look-a-like program you can use to lock your pc, you can't access your desktop again until the password is entered and the slider slided to the right. (really proud of it)-- After a time AutoIt and Windows, I switched to Mac. Don't expect me to answer anymore.

Share this post


Link to post
Share on other sites

@AppTux: topic-code now has a pwd-field, but it flickers very feqent so that its hard to type in something...

and again only the mainscreen is locked. another thing i would change is the width of the slider.

i have a 1920 resolution, slider is too long.

Share this post


Link to post
Share on other sites

Yes I also heard of the password field flicker, but if you have recommends, PLEASE post them to the topic, because now it's gonna go off-topic


PowerSlide2UnlockiPhone look-a-like program you can use to lock your pc, you can't access your desktop again until the password is entered and the slider slided to the right. (really proud of it)-- After a time AutoIt and Windows, I switched to Mac. Don't expect me to answer anymore.

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