Jump to content

Recommended Posts

Hi guys, I have a GUI which requires scrolling, however resizing is a bit of a problem because any time you scroll down/up and then resize, the controls move down/up and blank space is created within the scrollable area. 

Any help with maintaining scrollable area size to be fixed would be great.

Here is a reproducer:

To achieve the undesirable effect I described, simply run the script, scroll down and then resize window. You will notice that new blank space is created either on top or on bottom of the window depending on scrolling/resizing direction. Easiest way to see how bad it is, is to scroll down the page about half-way and then maximise the window. You will notice now a whole bunch of blank space is added to the top of the window and scrolling up simply shows nothing, scrolling down shows controls but they are cut off because of the blank space created on top of the page.

This is all happening within the yellow bg  child gui. I need to make it so that even if the GUI is resized the contents of the yellow bg child gui do not move and the scrollable area within the child gui remains the same.

#NoTrayIcon
#include-once
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIScroll.au3>
#include <SendMessage.au3>
Opt("GUIResizeMode", 802)

Global $parentgui_w = 880, $parentgui_h = 810, $childgui_w = $parentgui_w - 2, $childgui_h = $parentgui_h - 292

$parentgui = GUICreate("Scrollbar resize problem", $parentgui_w, $parentgui_h, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
GUISetBkColor(0xFFFFFF, $parentgui)

$childgui = GUICreate("", $childgui_w, $childgui_h, -5, 263, $WS_POPUP, $WS_EX_MDICHILD, $parentgui)
GUISetBkColor(0xFFF123, $childgui)
Dim $buttons[25]

For $i = 0 to 24
    If $i > 0 Then
        $cPos = ControlGetPos($childgui, "", $buttons[$i - 1])
        $buttons[$i] = GUICtrlCreateButton("Button " & $i + 1, ($childgui_w - 200) / 2, $cPos[1] + $cPos[3] + 50, 200, 80)
    Else
        $buttons[$i] = GUICtrlCreateButton("Button " & $i + 1, ($childgui_w - 200) / 2, 20, 200, 80)
    EndIf
Next

Scrollbar_Create($childgui, $SB_VERT, 130 * 25)
Scrollbar_Step(15, $childgui, $SB_VERT)

GUIRegisterMsg($WM_SIZE, "WM_SIZE")
GUIRegisterMsg($WM_NCACTIVATE, "WM_NCACTIVATE")
GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL")

GUISetState(@SW_SHOW, $parentgui)
GUISetState(@SW_SHOWNOACTIVATE, $childgui)

While 1
    $msg = GUIGetMsg(1)
    Switch $msg[1]
        Case $parentgui
            Switch $msg[0]
                Case $GUI_EVENT_CLOSE
                    Exit
                Case $GUI_EVENT_RESTORE
                    $pPos = WinGetPos($parentgui)
                    WinMove($parentgui, "", Default, Default, $pPos[2]+1, $pPos[3]+1)
                    WinMove($parentgui, "", Default, Default, $pPos[2]-1, $pPos[3]-1)
            EndSwitch
    EndSwitch
WEnd

Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)
    Local $iMw = BitShift($wParam, 16)
    $scroll_lines = 5

    If $iMw > 0 Then
        For $i = 0 to $scroll_lines
            _SendMessage($childgui, $WM_VSCROLL, $SB_LINEUP)
        Next
    Else
        For $i = 0 to $scroll_lines
            _SendMessage($childgui, $WM_VSCROLL, $SB_LINEDOWN)
        Next
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_SIZE($hwnd, $uMsg, $wParam, $lParam)
    If $hwnd = $parentgui Then
        $wPos = WinGetPos($parentgui)
        $pgui_wdiff = ($wPos[2] - $parentgui_w) / 2
        $pgui_hdiff = ($wPos[3] - $parentgui_h) / 2
        If $pgui_wdiff > 7 Then
            If $pgui_hdiff <> 0 Then
                If $wPos[2] > $parentgui_w Then
                    WinMove($childgui, "", $wPos[0] + 2 + $pgui_wdiff, Default, $parentgui_w - 2, $wPos[3] - 306)
                Else
                    WinMove($childgui, "", $wPos[0] + 2 + $pgui_wdiff, Default, $wPos[2] - 16, $wPos[3] - 306)
                EndIf
            Else
                WinMove($childgui, "", $wPos[0] + 2 + $pgui_wdiff, Default)
            EndIf
        ElseIf $pgui_wdiff < 7 Then
            If $wPos[0] <> -32000 Then
                WinMove($childgui, "", $wPos[0] + 8, Default, $wPos[2] - 16, $wPos[3] - 306)
            EndIf
        ElseIf $pgui_hdiff > 42 Then
            WinMove($childgui, "", Default, Default, Default, $wPos[3] - 306)
        EndIf
    EndIf
    Return 0
EndFunc

Func WM_NCACTIVATE($hwnd, $imsg, $wparam)
    If $hwnd = $parentgui Then
        If NOT $wparam Then Return 1
    EndIf
    Return $gui_rundefmsg
EndFunc

 

Edited by mpower
Link to post
Share on other sites

I'd recommend getting the dialog metrics for the system so you can make your child fit a little better.

Func GetDialogMetrics()
    Local $tStruct = DllStructCreate("struct;long caption;long xBorder;long yBorder;long xDlgFrame;long yDlgFrame;endstruct")
    For $iSysMetric = $SM_CYCAPTION To $SM_CYDLGFRAME
        DllStructSetData($tStruct, $iSysMetric - $SM_CYCAPTION + 1, _WinAPI_GetSystemMetrics($iSysMetric))
    Next
    Return $tStruct
EndFunc   ;==>GetDialogMetrics

As for the sizing, you can get the new width and height of the main gui using the lParam from the WM_SIZE function

Func WM_SIZE($hwnd, $uMsg, $wParam, $lParam)
    Local $iWidth = _WinAPI_LoWord($lParam)
    Local $iHeight = _WinAPI_HiWord($lParam)

    If $hwnd = $parentgui Then
        WinMove($childgui, "", x, y, $iWidth - 2, $iHeight - 292)
    EndIf
    Return 0
EndFunc

Also, if you use _WinApi_SetParent you can make your child GUI a real mdi child gui, so it's drawn inside the parent. It will get rid of that nasty effect where the child and parent minimize separately.

Link to post
Share on other sites
49 minutes ago, InunoTaishou said:

I'd recommend getting the dialog metrics for the system so you can make your child fit a little better.

Func GetDialogMetrics()
    Local $tStruct = DllStructCreate("struct;long caption;long xBorder;long yBorder;long xDlgFrame;long yDlgFrame;endstruct")
    For $iSysMetric = $SM_CYCAPTION To $SM_CYDLGFRAME
        DllStructSetData($tStruct, $iSysMetric - $SM_CYCAPTION + 1, _WinAPI_GetSystemMetrics($iSysMetric))
    Next
    Return $tStruct
EndFunc   ;==>GetDialogMetrics

As for the sizing, you can get the new width and height of the main gui using the lParam from the WM_SIZE function

Func WM_SIZE($hwnd, $uMsg, $wParam, $lParam)
    Local $iWidth = _WinAPI_LoWord($lParam)
    Local $iHeight = _WinAPI_HiWord($lParam)

    If $hwnd = $parentgui Then
        WinMove($childgui, "", x, y, $iWidth - 2, $iHeight - 292)
    EndIf
    Return 0
EndFunc

Also, if you use _WinApi_SetParent you can make your child GUI a real mdi child gui, so it's drawn inside the parent. It will get rid of that nasty effect where the child and parent minimize separately.

Thanks for these! I will take this into account, especially _WinApi_SetParent. 

Scrollbar issues still persists though :(

 

EDIT: Hmm I tried using _WinApi_SetParent($childgui, $parentgui) however its not working correctly :(

Edited by mpower
Link to post
Share on other sites
  • 2 weeks later...

Does anyone know of an effective way of dealing with the issue of scrollable area when resizing? Is there a way to perhaps retain the scroll position, resize the gui and adjust the scrollable area to fit the new window size?

Link to post
Share on other sites

So the only solution I've been able to come up with is to set the vertical scroll position to 0 when resizing. Whilst its not very good for user experience, it does negate the blank white space that would be padded to the top of the gui and end up cutting of controls further down below.

If anyone does come up with a better solution I'd be super keen to see it! :)

 

P.S. Here's the updated WM_SIZE function with the scroll to top line added:

Func WM_SIZE($hwnd, $uMsg, $wParam, $lParam)
    Local $iWidth = _WinAPI_LoWord($lParam)
    Local $iHeight = _WinAPI_HiWord($lParam)

    If $hwnd = $parentgui Then
        Scrollbar_Scroll($childgui, $SB_VERT, 0)
        WinMove($childgui, "", Default, Default, $iWidth - 2, $iHeight - 292)
    EndIf
    Return 0
EndFunc

 

Edited by mpower
Link to post
Share on other sites
  • Moderators

mpower,

Quote

the only solution I've been able to come up with is to set the vertical scroll position to 0 when resizing

That was my conclusion too - see GUIScrollBars_Ex_Example_5 in my Scrollbars UDF (the link is in my sig). The _Scrollbars_WM_ENTER/EXITSIZEMOVE functions in the main UDF do all the work.

M23

Edited by Melba23
Fixed formatting

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 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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By mike1950r
      Hi,
      I have a problem with the scrollbar in edit control.
      In my case I use richedit, but it appears also in the "normal" editcontrol.
      The problem ONLY appears, when working with my program (including editcontrol) and another program like notpad on the other screen.
      It appears when using the scrollbar of notepad, then my scroll bar and so on ... (vertical scrollbars only)
      and then suddenly the area behind my scrollbar gets highlighted (black) like selected, above and below,
      if i move the mouse to the left during pressing, the whole area behind the scrollbar gets highlighted in black.
      When my program is loaded alone the problem NEVER happens.
      I have made two screenshots, 1st one when the problem appears, and the second one showing when moving to the left.
      I really have no idea and there is nothing special in my editcontrol.
      I would be really thankful, if someone could help me further to get this issue solved.
      thanks in advance
      cheers mike


       
    • By vargheseg
      I have a web page which  has  somewhere from 90-100 records any time. So one has to scroll from from certain height to bottom using scroll bar on the right or using the down key. Is there any functionality to take a single screenshot and give .jpeg file.  Any previous links or direction will be very helpful for me
       
      George V
    • By nooneclose
      I need to dynamically resize my 2d array while looping. 
      I know this code:
      ReDim $rArray[UBound($rArray) + 1] works for the rows, however, I also need to increase the columns. How would i go about increasing both rows and columns while looping? 
    • By Bilgus
      This is an update or derivative work of Beege 's Scrolling Line Graph UDF
      https://www.autoitscript.com/forum/topic/109599-scrolling-line-graph-udf
       
      I noticed a few issues for my use case with the UDF one being that adding a sample required updating the waveform
      High CPU usage went hand in hand with that requirement
      Another issue was just how long updating took to complete
      I've hopefully rectified that with this version
       
      There are a few changes (only 1 line per graph for instance)
      The addition of a function AddSample (uses graphics paths to speed up drawing samples on update) Gridlines are only generated once A sample finished line can be added UpdateGraph allows you to compress the discarded portion of the graph (it looks kinda cool but uses more CPU) Lower Cpu usage Uses real Control Ids - it is a label control underneath so you get click events and can display text when control is disabled Example (Waveform.au3)
       
      Example 2 (peak.au3)
      UDF
      Updated:
      Previous Downloads [38 / 38/ 0]
      SSLG.au3 waveform.au3 Peak.au3
    • By TheAutomator
      Is there a (simple) way to make your script using a picture-control to resize the gui?
      This would be useful for a transparant pop-up window with a custom made theme using picture controls:
      $Form = GUICreate('', 301, 173, 5, 5, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUICtrlCreatePic(@scriptdir & "\resize_win.bmp", 0, 73, 20, 51) ; some api call or code telling the os to use this picture as a resize border GUICtrlSetResizing(-1, $GUI_DOCKLEFT+$GUI_DOCKTOP+$GUI_DOCKBOTTOM+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) GUISetState(@SW_SHOW) While True if GUIGetMsg() = $GUI_EVENT_CLOSE then Exit WEnd  
      EDIT: to make it more clear what i wanna do, if you go with the mouse arrow over the border of a re-sizable window the arrow changes to a "resize" arrow, you click and drag the border and then the window size adjusts to the mouse position until you release the mouse button.
      I want my picture control to be used the same way as the resize border to resize my window.
×
×
  • Create New...