Jump to content

Pinning a Graphic to a slider thumb control


 Share

Recommended Posts

I have a slider control and a graphic that sits on top of the thumb control

But I'm not sure how I can click on the graphic and slide the graphic to get it to move the thumb control of the slider.

Any ideas?

Include <GDIPLUS.au3>
#include <GuiSlider.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$Parent = GuiCreate("Slider",500,400)
GuiSetState()


$Slider = GUICtrlCreateSlider(20,20,400,50, BitOr($TBS_AUTOTICKS, $TBS_FIXEDLENGTH, $TBS_TOOLTIPS), $WS_EX_LAYERED  )
$hSlider = GUICtrlGetHandle($Slider)
GUICtrlSetLimit($Slider, 200, 1)
_GUICtrlSlider_SetThumbLength($hSlider, 100)
_GUICtrlSlider_SetPageSize($hSlider, 12)
DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", $hSlider, "wstr", 0, "wstr", 0); allow it to be bigger by blocking XP+ theme

$aRect = _GUICtrlSlider_GetThumbRect($hSlider)
$Thumb_Slider =_GuiCtrlCreatePNG("ThumbSlide.png",20 + $aRect[0] -1,20 + $aRect[1], $parent)


Do
Until GuiGEtMsg() = -3




Func _GuiCtrlCreatePNG($sImage,$iPosX, $iPosY, $hMainGUI, $onmousedown = "", $onmouseup = "")

    _GDIPlus_Startup()
    $Ret = GUICreate("", 0,0, $iPosX, $iPosY,$WS_POPUP,BitOR($WS_EX_LAYERED,$WS_EX_MDICHILD),$hMainGUI)
    $hImage = _GDIPlus_ImageLoadFromFile($sImage)
    SetBitmap($Ret,$hImage,255)
    GUISetState(@SW_SHOW)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    If $onmousedown <> "" then GUISetOnEvent($GUI_EVENT_PRIMARYDOWN,$onmousedown)
    If $onmouseup <> "" then GUISetOnEvent($GUI_EVENT_PRIMARYUP,$onmouseup)
    Return $Ret

EndFunc

Func SetBitmap($hGUI, $hImage, $iOpacity)
    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, $hScrDC, 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-7154-12829018112426_thumb.png

Edited by ChrisL
Link to comment
Share on other sites

  • Moderators

ChrisL,

I would do it by creating a child GUI to hold the graphic and then limiting the movement of the GUI to match the slider - like this: ;)

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

Global Const $SC_DRAGMOVE = 0xF012

; Create main GUI
$hGUI = GUICreate("Test", 570, 500)

; Create Slider
$hSlider = GUICtrlCreateSlider(10, 25, 560, 20)
GUICtrlSetLimit(-1, 500)
GUICtrlSetData(-1, 250)

; Create labels to show GUI position and slider values
$hLabel_GUI = GUICtrlCreateLabel("250", 10, 100, 100, 30)
GUICtrlSetFont(-1, 24)
GUICtrlCreateLabel("Graphic", 110, 100, 200, 30)

$hLabel_Slider = GUICtrlCreateLabel("250", 10, 200, 100, 30)
GUICtrlSetFont(-1, 24)
GUICtrlCreateLabel("Slider", 110, 200, 200, 30)

GUISetState()

; Get system values for the GUI borders
Global $iBorder = _WinAPI_GetSystemMetrics(8) ; Border width
Global $iBar = _WinAPI_GetSystemMetrics(4) ; Title bar height
Global $aMain_Pos = WinGetPos($hGUI)

; Create the child GUI and move to correct place
$hGUI_Slider = GUICreate("", 50, 50, -1, -1, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)
GUISetBkColor(0xFF0000, $hGUI_Slider)
WinMove($hGUI_Slider, "", $aMain_Pos[0] + $iBorder + 285, $aMain_Pos[1] + $iBorder + $iBar + 10)
GUISetState(@SW_SHOW, $hGUI_Slider)

; Look for the child moving
GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")

While 1
    ; Use the advanced parameter to distinguish between GUIs
    $aMsg = GUIGetMsg(1)
    Switch $aMsg[1]
        Case $hGUI
            Switch $aMsg[0]
                Case $GUI_EVENT_CLOSE
                    Exit
            EndSwitch
        Case $hGUI_Slider
            Switch $aMsg[0]
                ; If the mouse is down on the child
                Case $GUI_EVENT_PRIMARYDOWN
                    ; Tell the GUI to drag
                    _SendMessage($hGUI_Slider, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
            EndSwitch
    EndSwitch

WEnd

; Handler for the child moving
Func WM_WINDOWPOSCHANGING($hWnd, $Msg, $wParam, $lParam)

    ; If it the child sending the message
    If $hWnd = $hGUI_Slider Then

        ; Get main GUI position and calculate current min and max positions for child
        $aMain_Pos = WinGetPos($hGUI)
        Local $iY = $aMain_Pos[1] + $iBorder + $iBar + 10 ; Only one value needed as we do not want any vertical movement
        Local $iX_Min = $aMain_Pos[0] + $iBorder + 10
        Local $iX_Max = $aMain_Pos[0] + $iBorder + 510

        ; Get current child position
        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)

        ; Adjust as necessary to remain within the limits we set
        If $iLeft < $iX_Min Then DllStructSetData($stWinPos, 3, $iX_Min)
        If $iLeft > $iX_Max Then DllStructSetData($stWinPos, 3, $iX_Max)
        If $iTop <> $iY Then DllStructSetData($stWinPos, 4, $iY)

        ; Calculate child position within main GUI and display results
        Local $iValue = $iLeft - 10 - $aMain_Pos[0]
        If $iValue > -1 And $iValue < 501 Then
            GUICtrlSetData($hLabel_GUI, $iValue)
            GUICtrlSetData($hSlider, $iValue)
            GUICtrlSetData($hLabel_Slider, GUICtrlRead($hSlider))
        EndIf

    EndIf

EndFunc

You can see that the GUI position and the slider give the same value - you might want to do without the slider and just use the GUI! ;)

All clear? :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Link to comment
Share on other sites

Link to comment
Share on other sites

  • Moderators

ChrisL,

Easy! ;)

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

Global Const $SC_DRAGMOVE = 0xF012

$hGUI = GUICreate("Test", 570, 500)

$hSlider = GUICtrlCreateSlider(10, 25, 560, 20)
GUICtrlSetLimit(-1, 1200)
GUICtrlSetData(-1, 600)

$hLabel_GUI = GUICtrlCreateLabel("250", 10, 100, 100, 30)
GUICtrlSetFont(-1, 24)
GUICtrlCreateLabel("Graphic", 110, 100, 200, 30)

$hLabel_Slider = GUICtrlCreateLabel("600", 10, 200, 100, 30)
GUICtrlSetFont(-1, 24)
GUICtrlCreateLabel("Slider", 110, 200, 200, 30)

GUISetState()

Global $iBorder = _WinAPI_GetSystemMetrics(8) ; Border width
Global $iBar = _WinAPI_GetSystemMetrics(4) ; Title bar height
Global $aMain_Pos = WinGetPos($hGUI)

$hGUI_Slider = GUICreate("", 50, 50, -1, -1, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)
GUISetBkColor(0xFF0000, $hGUI_Slider)
WinMove($hGUI_Slider, "", $aMain_Pos[0] + $iBorder + 285, $aMain_Pos[1] + $iBorder + $iBar + 10)
GUISetState(@SW_SHOW, $hGUI_Slider)

GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")

While 1

    $aMsg = GUIGetMsg(1)
    Switch $aMsg[1]
        Case $hGUI
            Switch $aMsg[0]
                Case $GUI_EVENT_CLOSE
                    Exit
            EndSwitch
        Case $hGUI_Slider
            Switch $aMsg[0]
                Case $GUI_EVENT_PRIMARYDOWN
                _SendMessage($hGUI_Slider, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
            EndSwitch
    EndSwitch

WEnd

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

    If $hWnd = $hGUI_Slider Then

        $aMain_Pos = WinGetPos($hGUI)
        Local $iY = $aMain_Pos[1] + $iBorder + $iBar + 10
        Local $iX_Min = $aMain_Pos[0] + $iBorder + 10
        Local $iX_Max = $aMain_Pos[0] + $iBorder + 510

        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)

        If $iLeft < $iX_Min Then DllStructSetData($stWinPos, 3, $iX_Min)
        If $iLeft > $iX_Max Then DllStructSetData($stWinPos, 3, $iX_Max)
        If $iTop <> $iY Then DllStructSetData($stWinPos, 4, $iY)

        Local $iValue = $iLeft - 10 - $aMain_Pos[0]
        If $iValue > -1 And $iValue < 501 Then
            GUICtrlSetData($hLabel_GUI, $iValue)
            GUICtrlSetData($hSlider, $iValue * 1200 / 500) : <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            GUICtrlSetData($hLabel_Slider, GUICtrlRead($hSlider))
        EndIf

    EndIf

EndFunc

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...