Sign in to follow this  
Followers 0
gcue

child GUI scrollbar breaks

25 posts in this topic

Hello All.

I am using Melba's example below to create a child gui within a parent gui - which works great! It adds a scrollbar to the child gui.

However, if script is running and I change the desktop background color in display properties, I can no longer scroll to the bottom of the child gui.

Melba's example is working example if any of you want to see what I'm talking about.

Thank you in advance =)

Share this post


Link to post
Share on other sites



any ideas? still cant figure this out

help is much appreciated.

Share this post


Link to post
Share on other sites

any ideas? still cant figure this out

help is much appreciated.

I haven't looked at the example or tried what you suggest. When you can't scroll to the bottom do you find that if you scroll to the top you go beyond the expected top position?


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

martin! =)

yes thats exactly what happens. you've come across this? if so, what did you do to fix it?

hope all is well!

Edited by gcue

Share this post


Link to post
Share on other sites

martin! =)

yes thats exactly what happens. you've come across this? if so, what did you do to fix it?

hope all is well!

It's a common problem with scrolling udf in AutoIt. The same thing happens if you have a gui with scrollbars and the gui can be resized. If you scroll down then resize the gui you get the same problem. In this case one way to fix it is to deal with $WM_ENTERSIZEMOVE and when the gui is to be resized set the scroll position to the top. For the program I was developing I couldn't get a satifactory solution using Melba's UDF although he sent me some attempts at a fix. I solved it using Kip's GUIScroll.au3 and even then (as far as I remember) I had to ignore his example use of WM_SIZE.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

You may be able to work around this problem by refreshing the child GUI. Actually it works perfectly well when you destroy and then recreate the child GUI (I just tested that). The complexity of recreating the GUI in the same state as it was before you destroyed it may make this solution less attractive than it at first might seem. It also depends on how you go about organizing the GUI creation code.

There may be other unwanted effects caused by the same or related issues, but I don't know that. The question is what triggers the problem and how to recognize it, so as to work around the issue. I somehow get the feeling that this bug is a Microsoft problem rather than it having anything to do with Melba's UDF.

Edited by czardas

Share this post


Link to post
Share on other sites

martin,

ill try to look into this more.

czardas,

the only problem is that i dont know when the user will be adjusting display properties.. so i wont know when to destroy/recreate the child gui.

thank you both for your responses =)

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Yeah, I'm also not sure what the best approach for recognizing changes would be. The resizing issue mentioned by Martin seems related. Perhaps there is a simple test that covers all scenarios.

My first thought was: there will probably be some examples of capturing the desktop background image, or colour, on this forum. That's what I would try. Then test to see if there have been any changes, perhaps using an Adlib function. Although it seems a lot of hassle for an issue like this, and there are likely to be simpler solutions; although I can't think of any. :mellow:

Edited by czardas

Share this post


Link to post
Share on other sites

thanks for trying. but yea this is a tough one.

Share this post


Link to post
Share on other sites
:mellow: If you come up with a solution post it, because I would also like to know. It's something to chew over for a while.

Share this post


Link to post
Share on other sites

definitely.

thanks again.

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

It might be an idea, to use AutoIt Window Info Tool to get information from Display Properties, if the user opens that window, and test for changes to the theme that way. I'm not sure if it will work on different versions of windows. I imagine that it should work. :mellow:

It will require some extra code, but the user isn't likely to change the desktop theme or colour so often, so the extra code to refresh the GUI will hardly ever be needed. It won't affect the programs normal performance (thinking out loud).

Edited by czardas

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

It might be an idea, to use AutoIt Window Info Tool to get information from Display Properties, if the user opens that window, and test for changes to the theme that way. I'm not sure if it will work on different versions of windows. I imagine that it should work. :mellow:

It will require some extra code, but the user isn't likely to change the desktop theme or colour so often, so the extra code to refresh the GUI will hardly ever be needed. It won't affect the programs normal performance (thinking out loud).

When the desktop is changed the gui is sent an NC_PAINT message so you can use that.

;create gui etc

 GUIRegisterMsg(0x85, "MY_PAINT"); $WM_NCPAINT = 0x0085 

while GUIGetMsg() <> -3
WEnd



Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
 ;set the Vscroll to top, Hscroll to left
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_PAINT

EDIT:

I should say "maybe you can try that" rather than "you can use that" because I don't know if it will help.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Thanks Martin. :mellow:

I'll try to figure something out later. Unfortunately, I'm too tired right now, but hopefully I'll find the time to look at it soon. No guarantees because I've a pretty busy schedule ATM.

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Here's my attempt to resolve this issue, but I'm not entirely satisfied (it needs further consideration). Recreating the embedded child GUI every time $WM_NCPAINT is called seems overkill. However I imagine the method should also resolve the window resizing problems. I'm pretty sure the code can can be refined. There may be bugs that I'm not aware of - besides I still don't fully understand this.

The solution is not universal, but it seems to be working with the example given by Melba. I wish I had more time to spend on this. Perhaps someone else can scrutinize the code, and hopefully it will provide you with some ideas.

CODE REMOVED => See Post 17

Good luck!

Edited by czardas

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

the only problem is that i dont know when the user will be adjusting display properties.

I have solved this. Read the values from the registry to see if anything changed.

$wallpaper = RegRead("HKEY_CURRENT_USER\Control Panel\Desktop", "Wallpaper")
MsgBox(4096, "Desktop Wallpaper", $wallpaper)

$background = RegRead("HKEY_CURRENT_USER\Control Panel\Colors", "Background")
MsgBox(4096, "Desktop Color", $background)

I have tried to find a solution for the scroll bar problem which doesn't require destroying the child GUI. I had some success repainting the scroll bars, but there were still some display issues and errors in my code. I am not familiar enough with using scroll bars and will have to study this a while. Somehow I managed to crash my system while working on this. :mellow:

Edited by czardas

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

I have found a workable solution for this at last. The problem I found with using the NC_PAINT message was that it didn't work when the GUI was minimized. The following solution seems to be working okay as far as I have tested it.

#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <GUIScrollBars.au3>
#include <ScrollBarConstants.au3>

Opt("MustDeclareVars", 1)

Func _GetBackground(ByRef $wallpaper, ByRef $background)
    Local $desktopWall = RegRead("HKEY_CURRENT_USER\Control Panel\Desktop", "Wallpaper"), _
    $desktopColor = RegRead("HKEY_CURRENT_USER\Control Panel\Colors", "Background")
    If $wallpaper <> $desktopWall Or $background <> $desktopColor Then
        $wallpaper = $desktopWall
        $background = $desktopColor
        Return 1
    EndIf
    Return 0
EndFunc

Func _Refresh($hWnd)
    Local $nPos = _GUIScrollBars_GetScrollPos($hWnd, $SB_VERT) ; Get current position
    _GUIScrollBars_SetScrollInfoPos($hWnd, $SB_VERT, 0) ; Set the scroll to zero

    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    _GUIScrollBars_ShowScrollBar($hWnd,  $SB_HORZ, False)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_SetScrollInfoPos($hWnd, $SB_VERT, $nPos)
EndFunc

_Main()

Func _Main()
    Local $nFileMenu, $nExititem, $GUIMsg, $button, $h_cGUI, $hGUI, $wallpaper, $background, $ret

    $wallpaper = RegRead("HKEY_CURRENT_USER\Control Panel\Desktop", "Wallpaper")
    $background = RegRead("HKEY_CURRENT_USER\Control Panel\Colors", "Background")

    $hGUI = GUICreate("ScrollBar Example", 400, 400, -1, -1)

    $nFileMenu = GUICtrlCreateMenu("File")
    $nExititem = GUICtrlCreateMenuItem("Exit", $nFileMenu)
    $button = GUICtrlCreateButton("Test", 300, 10, 80, 30)

    $h_cGUI = GUICreate("Child GUI", 200, 260, 10, 10, $WS_CHILD, Default, $hGUI)
    For $i = 0 to 39 Step 2
        GUICtrlCreateCheckbox("Check " & $i + 1,  10, 10 + 20 * $i/2, 90, 20)
        GUICtrlCreateCheckbox("Check " & $i + 2, 110, 10 + 20 * $i/2, 90, 20)
    Next
    GUISetState(@SW_SHOW)
    GUICtrlSetResizing($h_cGUI, $GUI_DOCKALL)

    GUISwitch($hGUI)

    GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")

    _GUIScrollBars_Init($h_cGUI)
    _GUIScrollBars_ShowScrollBar($h_cGUI,  $SB_HORZ, False)
    _GUIScrollBars_SetScrollInfoMax($h_cGUI, $SB_VERT, 25)

    GUISetState()

    While 1
        $GUIMsg = GUIGetMsg()

        Switch $GUIMsg
            Case $GUI_EVENT_CLOSE, $nExititem
                ExitLoop
            Case $button
                MsgBox(0, "Test", "")
        EndSwitch

        $ret = _GetBackground($wallpaper, $background)
        If $ret = 1 Then _Refresh($h_cGUI)
    WEnd

    Exit
EndFunc   ;==>_Main

Func WM_VSCROLL($hWnd, $Msg, $wParam, $lParam)
    #forceref $Msg, $wParam, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $index = -1, $yChar, $yPos
    Local $Min, $Max, $Page, $Pos, $TrackPos

    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $index = $x
            $yChar = $aSB_WindowInfo[$index][3]
            ExitLoop
        EndIf
    Next
    If $index = -1 Then Return 0


    ; Get all the vertial scroll bar information
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")
    $Max = DllStructGetData($tSCROLLINFO, "nMax")
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    ; Save the position for comparison later on
    $yPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $yPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

    Switch $nScrollCode
        Case $SB_TOP ; user clicked the HOME keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $Min)

        Case $SB_BOTTOM ; user clicked the END keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $Max)

        Case $SB_LINEUP ; user clicked the top arrow
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)

        Case $SB_LINEDOWN ; user clicked the bottom arrow
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)

        Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)

        Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch

;~    // Set the position and then retrieve it.  Due to adjustments
;~    //   by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    ;// If the position has changed, scroll the window and update it
    $Pos = DllStructGetData($tSCROLLINFO, "nPos")

    If ($Pos <> $yPos) Then
        _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
        $yPos = $Pos
    EndIf

    Return $GUI_RUNDEFMSG

EndFunc   ;==>WM_VSCROLL

The only thing that I need to figure out now is how to get the current Windows theme and account for changes that the user might make, because the same issue occurs. Hopefully it will be easy to read from the Registry.

Edited by czardas

Share this post


Link to post
Share on other sites

I have found a workable solution for this at last. The problem I found with using the NC_PAINT message was that it didn't work when the GUI was minimized. The following solution seems to be working okay as far as I have tested it.

The only thing that I need to figure out now is how to get the current Windows theme and account for changes that the user might make, because the same issue occurs. Hopefully it will be easy to read from the Registry.

You can do this without polling.

Three system messages are broadcast when display properties are changed.

WM_THEMECHANGED

WM_SYSCOLORCHANGE

WM_WININICHANGE

The refresh code is ineffective if run directly from the themechanged handler when a blocking function has paused the script,

so the usual global flag or dummy control is needed to run refresh after the blocking function returns.

#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <GUIScrollBars.au3>
#include <ScrollBarConstants.au3>

Opt("MustDeclareVars", 1)

Global Const $WM_THEMECHANGED = 0x031A
Global $cRefresh

_Main()

Func _Main()
    Local $nFileMenu, $nExititem, $GUIMsg, $button, $hGUI, $h_cGUI

    $hGUI = GUICreate("ScrollBar Example", 400, 400, -1, -1)

    $cRefresh = GUICtrlCreateDummy() ;for on-event and message loop modes

    $nFileMenu = GUICtrlCreateMenu("File")
    $nExititem = GUICtrlCreateMenuItem("Exit", $nFileMenu)
    $button = GUICtrlCreateButton("Test", 300, 10, 80, 30)

    $h_cGUI = GUICreate("Child GUI", 200, 260, 10, 10, $WS_CHILD, Default, $hGUI)
    For $i = 0 to 39 Step 2
        GUICtrlCreateCheckbox("Check " & $i + 1,  10, 10 + 20 * $i/2, 90, 20)
        GUICtrlCreateCheckbox("Check " & $i + 2, 110, 10 + 20 * $i/2, 90, 20)
    Next
    GUISetState(@SW_SHOW)
    GUICtrlSetResizing($h_cGUI, $GUI_DOCKALL)

    GUISwitch($hGUI)

    GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")
    GUIRegisterMsg($WM_THEMECHANGED, "WM_THEMECHANGED")

    _GUIScrollBars_Init($h_cGUI)
    _GUIScrollBars_ShowScrollBar($h_cGUI,  $SB_HORZ, False)
    _GUIScrollBars_SetScrollInfoMax($h_cGUI, $SB_VERT, 25)

    GUISetState()

    While 1
        $GUIMsg = GUIGetMsg()

        Switch $GUIMsg
            Case $cRefresh
                _Refresh($h_cGUI)
            Case $GUI_EVENT_CLOSE, $nExititem
                ExitLoop
            Case $button
                MsgBox(0, "Test", "")
        EndSwitch

    WEnd

    Exit
EndFunc   ;==>_Main


Func WM_THEMECHANGED($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg, $wParam, $lParam
    GUICtrlSendToDummy($cRefresh)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_THEMECHANGED


Func _Refresh($hWnd)
    Local $nPos = _GUIScrollBars_GetScrollPos($hWnd, $SB_VERT) ; Get current position
    _GUIScrollBars_SetScrollInfoPos($hWnd, $SB_VERT, 0) ; Set the scroll to zero

    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    _GUIScrollBars_ShowScrollBar($hWnd,  $SB_HORZ, False)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_SetScrollInfoPos($hWnd, $SB_VERT, $nPos)
EndFunc


Func WM_VSCROLL($hWnd, $Msg, $wParam, $lParam)
    #forceref $Msg, $wParam, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $index = -1, $yChar, $yPos
    Local $Min, $Max, $Page, $Pos, $TrackPos

    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $index = $x
            $yChar = $aSB_WindowInfo[$index][3]
            ExitLoop
        EndIf
    Next
    If $index = -1 Then Return 0


    ; Get all the vertial scroll bar information
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")
    $Max = DllStructGetData($tSCROLLINFO, "nMax")
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    ; Save the position for comparison later on
    $yPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $yPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

    Switch $nScrollCode
        Case $SB_TOP ; user clicked the HOME keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $Min)

        Case $SB_BOTTOM ; user clicked the END keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $Max)

        Case $SB_LINEUP ; user clicked the top arrow
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)

        Case $SB_LINEDOWN ; user clicked the bottom arrow
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)

        Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)

        Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch

;~    // Set the position and then retrieve it.  Due to adjustments
;~    //   by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    ;// If the position has changed, scroll the window and update it
    $Pos = DllStructGetData($tSCROLLINFO, "nPos")

    If ($Pos <> $yPos) Then
        _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
        $yPos = $Pos
    EndIf

    Return $GUI_RUNDEFMSG

EndFunc   ;==>WM_VSCROLL

I see fascists...

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

You can do this without polling.

Three system messages are broadcast when display properties are changed.

WM_THEMECHANGED

WM_SYSCOLORCHANGE

WM_WININICHANGE

The refresh code is ineffective if run directly from the themechanged handler when a blocking function has paused the script,

so the usual global flag or dummy control is needed to run refresh after the blocking function returns.

That's very helpful, thanks. However the problem still seems to occur when switching from Windows XP theme to Windows Classic theme. I have been trying to figure it out, but it's strange because it appears to work when switching back to the Windows XP theme.

I can just imagine a user discovering this bug by accident and not being able to reproduce the circumstances that caused it. :mellow:

Edited by czardas

Share this post


Link to post
Share on other sites

I've modified a little rover's code and tested on windows XP (VM) and windows 7, both 32 bits (changing themes and backgrounds) and seems ok now:

#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <GUIScrollBars.au3>
#include <ScrollBarConstants.au3>

Opt("MustDeclareVars", 1)

Global Const $WM_THEMECHANGED = 0x031A
Global $cRefresh, $nPos

_Main()

Func _Main()
    Local $nFileMenu, $nExititem, $GUIMsg, $button, $hGUI, $h_cGUI

    $hGUI = GUICreate("ScrollBar Example", 400, 400, -1, -1)

    $cRefresh = GUICtrlCreateDummy() ;for on-event and message loop modes

    $nFileMenu = GUICtrlCreateMenu("File")
    $nExititem = GUICtrlCreateMenuItem("Exit", $nFileMenu)
    $button = GUICtrlCreateButton("Test", 300, 10, 80, 30)

    $h_cGUI = GUICreate("Child GUI", 200, 260, 10, 10, $WS_CHILD, Default, $hGUI)
    For $i = 0 to 39 Step 2
        GUICtrlCreateCheckbox("Check " & $i + 1,  10, 10 + 20 * $i/2, 90, 20)
        GUICtrlCreateCheckbox("Check " & $i + 2, 110, 10 + 20 * $i/2, 90, 20)
    Next
    GUISetState(@SW_SHOW)
    GUICtrlSetResizing($h_cGUI, $GUI_DOCKALL)

    GUISwitch($hGUI)

    GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")
    GUIRegisterMsg($WM_THEMECHANGED, "WM_THEMECHANGED")

    _GUIScrollBars_Init($h_cGUI)
    _GUIScrollBars_ShowScrollBar($h_cGUI,  $SB_HORZ, False)
    _GUIScrollBars_SetScrollInfoMax($h_cGUI, $SB_VERT, 25)

    GUISetState()

    While 1
  Sleep(10)
  $nPos = _GUIScrollBars_GetScrollPos($hGUI, $SB_VERT) ; Get current position <<<<<<<<<<<<<<<<<<<<<<<<< to here
        $GUIMsg = GUIGetMsg()
        Switch $GUIMsg
            Case $cRefresh
                _Refresh($h_cGUI)
            Case $GUI_EVENT_CLOSE, $nExititem
                ExitLoop
            Case $button
                MsgBox(0, "Test", "")
        EndSwitch

    WEnd

    Exit
EndFunc   ;==>_Main


Func WM_THEMECHANGED($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg, $wParam, $lParam
    GUICtrlSendToDummy($cRefresh)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_THEMECHANGED


Func _Refresh($hWnd)
    ;Local $nPos = _GUIScrollBars_GetScrollPos($hWnd, $SB_VERT) ; Get current position <<<<<<<<<<<<<<<<<<<<<<<<<< moved from here
    _GUIScrollBars_SetScrollInfoPos($hWnd, $SB_VERT, 0) ; Set the scroll to zero

    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    _GUIScrollBars_ShowScrollBar($hWnd,  $SB_HORZ, False)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_SetScrollInfoPos($hWnd, $SB_VERT, $nPos)
EndFunc


Func WM_VSCROLL($hWnd, $Msg, $wParam, $lParam)
    #forceref $Msg, $wParam, $lParam
    Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $index = -1, $yChar, $yPos
    Local $Min, $Max, $Page, $Pos, $TrackPos

    For $x = 0 To UBound($aSB_WindowInfo) - 1
        If $aSB_WindowInfo[$x][0] = $hWnd Then
            $index = $x
            $yChar = $aSB_WindowInfo[$index][3]
            ExitLoop
        EndIf
    Next
    If $index = -1 Then Return 0


    ; Get all the vertial scroll bar information
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")
    $Max = DllStructGetData($tSCROLLINFO, "nMax")
    $Page = DllStructGetData($tSCROLLINFO, "nPage")
    ; Save the position for comparison later on
    $yPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $yPos
    $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

    Switch $nScrollCode
        Case $SB_TOP ; user clicked the HOME keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $Min)

        Case $SB_BOTTOM ; user clicked the END keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $Max)

        Case $SB_LINEUP ; user clicked the top arrow
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1)

        Case $SB_LINEDOWN ; user clicked the bottom arrow
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1)

        Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)

        Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $TrackPos)
    EndSwitch

;~    // Set the position and then retrieve it.  Due to adjustments
;~    //   by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    ;// If the position has changed, scroll the window and update it
    $Pos = DllStructGetData($tSCROLLINFO, "nPos")

    If ($Pos <> $yPos) Then
        _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos))
        $yPos = $Pos
    EndIf

    Return $GUI_RUNDEFMSG

EndFunc   ;==>WM_VSCROLL

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