Jump to content
Sign in to follow this  
qwert

How to force scrollable bitmap window back to top?

Recommended Posts

qwert

I have a scrollable child GUI that contains a large bitmap that sometimes needs to be loaded with a different bitmap. The _SetHImage works fine, except that if the original bitmap has been scrolled downward, the replacement bitmap displays in the same "already scrolled down" position.

What is the proper way to force a "Home" on the child window before I load the new bitmap? I've tried a GUIScrollBars_Scroll Window function but could not get any worthwhile result.

Thanks in advance for any assistance.

Share this post


Link to post
Share on other sites
martin

I have a scrollable child GUI that contains a large bitmap that sometimes needs to be loaded with a different bitmap. The _SetHImage works fine, except that if the original bitmap has been scrolled downward, the replacement bitmap displays in the same "already scrolled down" position.

What is the proper way to force a "Home" on the child window before I load the new bitmap? I've tried a GUIScrollBars_Scroll Window function but could not get any worthwhile result.

Thanks in advance for any assistance.

Are the scrollbars in the child gui created using GuiScrollBars.au3?


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
qwert

Are the scrollbars in the child gui created using GuiScrollBars.au3?

Yes, with a _GUIScrollBars_Init plus ...InfoMax, ...InfoPage, etc.

Share this post


Link to post
Share on other sites
martin

Yes, with a _GUIScrollBars_Init plus ...InfoMax, ...InfoPage, etc.

You could just use a sawn-off version of the WM_VSCROLL combined with WM_HSCROLL supplied in the help

like this

;To set to top and left of window call VHSCROLLToTopLeft($GuiID)


Func VSCROLLToTopLeft($hWnd)
    Local $index = -1, $xChar, $yChar, $xPos, $yPos
    Local $Min, $Pos
     Local $tSCROLLINFO

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


    ; Get all the vertial scroll bar information
    $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")

    ; Save the position for comparison later on
    $yPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $yPos

    DllStructSetData($tSCROLLINFO, "nPos", $Min)

;~    // Set the position and then retrieve it.  Due to adjustments
;~    //   by Windows it might 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))


    ;now the HSCROLL
    ; Get all the horizontal scroll bar information
    $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $Min = DllStructGetData($tSCROLLINFO, "nMin")

    ; Save the position for comparison later on
    $xPos = DllStructGetData($tSCROLLINFO, "nPos")
    $Pos = $xPos

    DllStructSetData($tSCROLLINFO, "nPos", $Min)

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

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    ;// If the position has changed, scroll the window and update it
    $Pos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($Pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $Pos), 0)


EndFunc   ;==>VSCROLLToTopLeft
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
qwert

You could just use a sawn-off version of the WM_VSCROLL ...

Martin, thanks.

I should be able to adapt that pretty easily, especially since I only have to work with vertical scrolling. I was hoping I had overlooked some "Home" function, but I suppose scrolling a bitmap comes with some necessary complexity.

Share this post


Link to post
Share on other sites
qwert

I should be able to adapt that pretty easily ...

Well ... almost. It introduced a different problem.

My Child GUI can bring up a different bitmap but it's visible only if the original bitmap is in the "home" position. If it's in the "scrolled down" state, the area goes blank -- even though the new bitmap is being loaded (I can tell it loaded by the change in the scroll box size).

Any ideas?

Share this post


Link to post
Share on other sites
qwert

the area goes blank ... Any ideas?

In investigating alternatives, I found that since WM_VSCROLL is handling the user's scroll bar actions, I can call it locally with a $SB_TOP flag and it "homes" the bitmap.

The only downside is that there's a flash/redisplay cycle on the original bitmap as it gets homed. Ideally, the second bitmap would just appear "homed", without any intermediate action.

I would still like to understand what causes VSCROLLToTopLeft to blank out the area. Maybe it will still turn out to be the best solution.

Thanks for your help so far.

UPDATE: I solved the flash problem by bracketing the bitmap home and change with a @SW_LOCK and @SW_UNLOCK. It works perfectly ... EXCEPT that afterwards the scroll box is still in the down postion. But it magically jumps to the top if I mouse anywhere over the scroll bar.

How can I cause a refresh of the scroll bar after the new bitmap is ready?

UPDATE TWO: I fashioned a workaround to refresh the scroll bar using a MouseGetPos + MouseMove + MouseMove(original position). I'm sure there's a better way, but this one does work.

Edited by qwert

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.