Results 1 to 28 of 28

Thread: [RESOLVED] Problem with dynamic resising on controls on a form.

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Resolved [RESOLVED] Problem with dynamic resising on controls on a form.

    I have been working on this resizing UC now for some time and it starts to shape up. One of the problems I still have to solve is with proportional resizing, the control can optionally resize controls either anchored or proportionally. I'm first describing the problem in 2 images, so it's clearer what I am talking about.

    Name:  before_resize.jpg
Views: 1015
Size:  2.5 KBName:  after_resize.jpg
Views: 988
Size:  2.7 KB

    So, what happens exactly is that, starting from the form's original size, as the form resizes there is a gap growing below the bottom of the lowest placed controls and the statusbar/bottom-border of the form. Above all controls resize perfectly fine in relation to each other. Also note that there is almost no gap growing on the right width side. Very little compared to the hight. The anchored resize doesn't show this gap.

    Now to so come. I could possibly attach the full UC project but first of all I use UniSuitePro controls and the project also uses vbRichclient5 so my plan is instead that once I am satisfied and sure it all works, I will make a copy of the project and change the UniSuitePro control references to the original VB6 ones. It will continue to depend on vbRichclient5 though, but that's why I don't want to attach the full project now.

    The resize control keeps a reference to the parent form, so the resizing takes place in the forms resize event but in the resize control. I don't put here the declarations private to the control as there are too many, but they start with a m in the name, except for API declarations. It should be understandable anyhow or ask.

    EDIT: Decided to add the code initializing the UC as it may be of help understanding.
    Code:
    Private Sub UserControl_Initialize()
    Dim uRect As RECT
    
    mTwPerPxHeight = Screen.TwipsPerPixelY
    mTwPerPxWidth = Screen.TwipsPerPixelX
    Call SystemParametersInfo(SPI_GETWORKAREA, 0, uRect, 0)
    
    With uRect
       mMaxFormHeightPix = .Bottom - .Top
       mMaxFormWidthPix = .Right - .Left
    End With
    End Sub
    
    Private Sub UserControl_InitProperties()
    
    On Error Resume Next
    
    mSaveParentSizePos = True
    mFontResize = True
    mResizeType = rtProportional
    Call InitControls
    End Sub
    
    Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    Dim sJson As String
    
    On Error Resume Next
    
    With PropBag
       sJson = CStr(.ReadProperty("Anchors", "{}"))
       Set mAnchors = New_c.JSONDecodeToCollection(sJson)
       mSaveParentSizePos = .ReadProperty("SaveParentSizePos", True)
       mFontResize = .ReadProperty("FontResize", True)
       mResizeType = .ReadProperty("ResizeType", 0)
    End With
    
    If Ambient.UserMode Then 'If we're not in design mode
       'Get a reference of parent form
       Set mFrm = Parent
    
       'Subclass the parent form
       With mFrm
                sc_Subclass .hwnd
                sc_AddMsg .hwnd, WM_GETMINMAXINFO
       End With
    
    End If
    
    End Sub
    Code:
    Private Sub mFrm_Resize()
    '****************************************************************
    '* Reference to the parent form and its event.
    '* The first resize is when the form is created and its proper
    '* dimensions as in design is established at run time. Here we first
    '* grab and save these values for later use, to have a solid baseline
    '* to resize from. So we will always resize in relation to this baseline.
    '*
    '* The very first control resize takes place in the form load event, to
    '* properly deal with the situation when the program starts up Maximized.
    '* The following resizing of controls, in response to user resize of form,
    '* is initiated here by calling the ResizeControls function.
    '*****************************************************************
    
    If Not mParrentHasResized Then
       'The very first resize as the form is created.
       'Get original (development) form dimension
       GetWindowRect mFrm.hwnd, mFrmRect
    
       With mFrmRect
          mInitialHeight = .Bottom - .Top
          mInitialWidth = .Right - .Left
       End With
    
       mMinFormHeightPix = mInitialHeight
       mMinFormWidthPix = mInitialWidth
    
       If mMinFormHeightPix > mMaxFormHeightPix Then
          mMinFormHeightPix = mMaxFormHeightPix
       End If
    
       If mMinFormWidthPix > mMaxFormWidthPix Then
          mMinFormWidthPix = mMaxFormWidthPix
       End If
    
       mParrentHasResized = True
    Else
    
       If mParrentHasLoaded Then
          'Don't respond to and resize controls until form fully loaded
          Call ResizeControls
       End If
    End If
    
    End Sub
    Code:
    Private Sub ResizeControls()
    '***********************************************************************
    '* Initiates the resize by setting up basic values used for
    '* both anchored and proportional resize. To avoid flickering,
    '* freezes the window before deciding what type of resize to do
    '* and then call its function accordingly.
    '*
    '* Then unfreez and redraws the window to display the resize that have happened.
    '************************************************************************
    
    With mFrm
    
       ' Don't bother if we are minimized.
       If .WindowState <> vbMinimized Then
          If Not mCtlSizes Is Nothing Then
             If mCtlSizes.Count > 0 Then
                GetWindowRect .hwnd, mFrmRect
    
                With mFrmRect
                   mHeightChangeFactor = (.Bottom - .Top) / mInitialHeight
                   mWidthChangeFactor = (.Right - .Left) / mInitialWidth
                End With
    
                mFontSizeChangeFactor = (mHeightChangeFactor + mWidthChangeFactor) / 2
    
                If mFontSizeChangeFactor > mHeightChangeFactor Then
                   mFontSizeChangeFactor = mHeightChangeFactor
                End If
    
               'Mainly to allow specific fontsize handling in PictureBox
               RaiseEvent BeforeResize(mFontSizeChangeFactor)
                'Freeze the Application
                'Freezing the Control Redraws makes the application faster in resizing controls.
                SendMessage .hwnd, WM_SETREDRAW, 0&, 0
    
                If mResizeType = rtProportional Then
                   Call ResizeProportionally
                Else
                   Call ResizeByAnchor
                End If
    
                'Unfreeze the application and redraw the window after the resize
                SendMessage .hwnd, WM_SETREDRAW, 1&, 0
                RedrawWindow .hwnd, ByVal 0&, ByVal 0&, RDW_INVALIDATE Or RDW_UPDATENOW Or RDW_ALLCHILDREN
             End If
          End If
       End If
    
    End With
    
    End Sub
    Code:
    Private Sub ResizeProportionally()
    '***********************************************************************
    '* Resizes controls proportionally according to the factor for widths
    '* and heights as calculated in ResizeControls function.
    '*
    '* mCtlSizes is a vbRichclient5 collection in JSON mode that store all
    '* controls original position values.
    '***************************************************************************
    
    Dim ctrl As Control
    Dim sKey As String
    
    If Not mCtlSizes Is Nothing Then
    
       For Each ctrl In mFrm.Controls
    
          If IsSupportedControl(ctrl) Then
             sKey = GetCtrlNameWithIndex(ctrl)
    
             With ctrl
    
                If Not TypeOf ctrl Is Line Then
                   .Left = (mCtlSizes(sKey)("Left") * mWidthChangeFactor) * mTwPerPxWidth
                   .Top = (mCtlSizes(sKey)("Top") * mHeightChangeFactor) * mTwPerPxHeight
                   .Width = (mCtlSizes(sKey)("Width") * mWidthChangeFactor) * mTwPerPxWidth
    
                   If Not TypeOf ctrl Is UniCombo Then
                      ' Cannot change height of ComboBoxes.
                      .Height = (mCtlSizes(sKey)("Height") * mHeightChangeFactor) * mTwPerPxHeight
                   End If
    
                   On Error Resume Next
    
                   If mFontResize Then
                      
                      If Not (TypeOf ctrl Is UniCheck Or TypeOf ctrl Is UniOption Or TypeOf ctrl Is UniFrame) Then
                         If Not TypeOf ctrl Is PictureBox Then
                         .Font.Size = mCtlSizes(sKey)("FontSize") * mFontSizeChangeFactor
                         End If
                      Else
                         'reduce font size increase for these controls
                         .Font.Size = mCtlSizes(sKey)("FontSize") * (mFontSizeChangeFactor - ((mFontSizeChangeFactor - 1) / 2))
                      End If
                   End If
    
                   On Error GoTo 0
    
                Else
                   .X1 = (mCtlSizes(sKey)("Left") * mTwPerPxWidth) * mWidthChangeFactor
                   .Y1 = (mCtlSizes(sKey)("Top") * mTwPerPxHeight) * mHeightChangeFactor
                   .X2 = .X1 + (mCtlSizes(sKey)("Width") * mTwPerPxWidth) * mWidthChangeFactor
                   .Y2 = .Y1 + (mCtlSizes(sKey)("Height") * mTwPerPxHeight) * mHeightChangeFactor
                End If
    
             End With
    
          End If
    
       Next
    
    End If
    
    End Sub
    For reference and completeness, here is also the anchored resize, which works ok.
    Code:
    Private Sub ResizeByAnchor()
    '********************************************************
    '* Resizing only of anchored controls.
    '*******************************************************
    On Error Resume Next
    
    Dim nHeightChange As Long, nWidthChange As Long
    Dim sKey As String
    Dim cAnchor As vbRichClient5.cCollection
    Dim ctrl As Control
    
    'Calculate the change in pixels
    With mFrmRect
       nHeightChange = (.Bottom - .Top) - mInitialHeight
       nWidthChange = (.Right - .Left) - mInitialWidth
    End With
    
    If nHeightChange <> 0 Or nWidthChange <> 0 Then
    
       For Each ctrl In mFrm.Controls
    
          If IsSupportedControl(ctrl) Then
             sKey = GetCtrlNameWithIndex(ctrl)
    
             If mAnchors.Exists(sKey) Then
                Set cAnchor = mAnchors(sKey)
             Else
                Set cAnchor = New_c.JSONDecodeToCollection(JSON_DEF_ANCHOR)
             End If
    
             With ctrl
    
                If nWidthChange Then
                   If cAnchor("Left") And cAnchor("Right") Then
                      If Not TypeOf ctrl Is Line Then
                         .Width = (mCtlSizes(sKey)("Width") + nWidthChange) * mTwPerPxWidth
                      Else
                         .X2 = (mCtlSizes(sKey)("Width") + nWidthChange) * mTwPerPxWidth
                      End If
    
                   ElseIf cAnchor("Right") Then
    
                      If Not TypeOf ctrl Is Line Then
                         .Left = (mCtlSizes(sKey)("Left") + nWidthChange) * mTwPerPxWidth
                      Else
                         .X1 = (mCtlSizes(sKey)("Left") + nWidthChange) * mTwPerPxWidth
                         .X2 = (mCtlSizes(sKey)("Width") + nWidthChange) * mTwPerPxWidth
                      End If
                   End If
                End If
    
                If nHeightChange Then
                   If cAnchor("Top") And cAnchor("Bottom") Then
                      If Not TypeOf ctrl Is Line Then
                         .Height = (mCtlSizes(sKey)("Height") + nHeightChange) * mTwPerPxHeight
    
                         If mFontResize Then
                            If Not (TypeOf ctrl Is UniCheck Or TypeOf ctrl Is UniOption) Then
                               .Font.Size = mCtlSizes(sKey)("FontSize") * mFontSizeChangeFactor
                            Else
                               .Font.Size = mCtlSizes(sKey)("FontSize") * (mFontSizeChangeFactor - ((mFontSizeChangeFactor - 1) / 2))
                            End If
                         End If
    
                      Else
                         .Y2 = (mCtlSizes(sKey)("Height") + nHeightChange) * mTwPerPxHeight
                      End If
    
                   ElseIf cAnchor("Bottom") Then
    
                      If Not TypeOf ctrl Is Line Then
                         .Top = (mCtlSizes(sKey)("Top") + nHeightChange) * mTwPerPxHeight
    
                         If mFontResize Then
                            If Not (TypeOf ctrl Is UniCheck Or TypeOf ctrl Is UniOption) Then
                               .Font.Size = mCtlSizes(sKey)("FontSize") * mFontSizeChangeFactor
                            Else
                               .Font.Size = mCtlSizes(sKey)("FontSize") * (mFontSizeChangeFactor - ((mFontSizeChangeFactor - 1) / 2))
                            End If
                         End If
    
                      Else
                         .Y1 = (mCtlSizes(sKey)("Top") + nHeightChange) * mTwPerPxHeight
                         .Y2 = (mCtlSizes(sKey)("Height") + nHeightChange) * mTwPerPxHeight
                      End If
                   End If
                End If
    
             End With
    
          End If
    
       Next
    
    End If
    
    End Sub
    Last edited by 7edm; Aug 8th, 2015 at 05:10 AM. Reason: added some more code
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Problem with dynamic resising on controls on a form.

    You don't mention how you are calculating your change factor variables. And proportional scaling may not be completely described by you. Proportional to what? The form's original size, the control's original size? In either case, a 'gap' would be expected if the form is not resized proportionally.

    Edited: I see the answers to my question above. You are not proportionally scaling anything in my opinion. Let's assume the form was 500x500 square at startup and user dragged the height another 500 pixels. Ok, your control would scale twice as tall now because mHeightChangeFactor = 2 & mWidthChangeFactor = 1, correct? That is not proportional scaling IMO. It is the same as stretching

    When scaling proportionally, you will scale the height & width by the same factor...

    Let's say you have a square control, i.e., a picturebox at 200x200 pixels. Ok, now someone drags just the bottom edge of the form 500 pixels so it is 500 pixels taller but the same width. If you were scaling the control proportionally on either the original dimensions of the form or the control, then the control wouldn't resize in that case, it would still remain 200x200 if the control is to remain completely visible on the form, even though the form is now 500 pixels taller. Proportional scaling is based on either the change of height or change of width, not both. Usually you'd choose the lower change value/ratio.

    Edited Again. The gap issue can be described with this scenario:
    1. Form: 500x500: Control 100x100
    2. Form resizes height only by 500 pixels
    3. Anchored method: control resizes to 100x600 (500 pixel change)
    4. Proportional method: control resizes to 100x200 (2x height change). Gap is significant
    Last edited by LaVolpe; Aug 8th, 2015 at 08:48 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: Problem with dynamic resising on controls on a form.

    Quote Originally Posted by LaVolpe View Post
    You don't mention how you are calculating your change factor variables. And proportional scaling may not be completely described by you. Proportional to what? The form's original size, the control's original size? In either case, a 'gap' would be expected if the form is not resized proportionally.

    Let's say you have a square control, i.e., a picturebox at 200x200 pixels. Ok, now someone drags just the bottom edge of the form 500 pixels so it is 500 pixels taller but the same width. If you were scaling the control proportionally on either the original dimensions of the form or the control, then the control wouldn't resize in that case, it would still remain 200x200 even though the form is now 500 pixels taller.
    Ok I thought it was clear from the code I posted, that it is relative to the original form size. On load the original width and height in pixels of the form is assigned to vars, together with twipsperpixels values etc. On resize both new width and height (of the form window) are read into a RECT structure and the new width value is divided by the original, to get a scaling factor, same with hight. then each controls original Left and Width values are multiplied with this the width fact and then multiplied with the twips per pixelX value, and same for Top and Hight with the hight factor and twips per pixelY value. But maybe it's easier if I simply paste in all the UC code then it should all be readable. I may have to split it in 2 posts.

    The code should work out of the box for proportional, while anchor needs the Property page to be set up but wont paste that.
    Code:
    Option Explicit
    ''*****************************************
    ''* Perfomance timer functions from the t2win library
    ''**************************************************
    'Private Declare Function cTimerOpen Lib "t2win-32.dll" () As Integer
    'Private Declare Function cTimerStart Lib "t2win-32.dll" (ByVal TimerHandle As Long) As Integer
    'Private Declare Function cTimerRead Lib "t2win-32.dll" (ByVal TimerHandle As Long) As Long
    'Private Declare Function cTimerReset Lib "t2win-32.dll" (ByVal TimerHandle As Long) As Integer
    'Private Declare Function cTimerClose Lib "t2win-32.dll" (ByVal TimerHandle As Long) As Integer
    'Private hTimer1 As Integer, hTimer2 As Integer, mStartOk As Boolean, mCloseOk As Boolean
    
    '************************************************
    '* Originally inspired by Advanced Anchor Control by Developers : Hamed Oveisi & Patrick de Groot *
    '* http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=53861&lngWId=1
    '* http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=75387&lngWId=1
    '* and FlexUI Resizer by Alaeddin Hallak
    '* http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=56199&lngWId=1
    '************************************************
    '
    Enum eResizeType
       rtProportional
       rtAnchor
    End Enum
    Private mHeightChangeFactor As Single
    Private mWidthChangeFactor As Single
    Private mFontSizeChangeFactor As Single
    
    Private mFontResize As Boolean
    Private mTwPerPxHeight As Long
    Private mTwPerPxWidth As Long
    Private mAppName As String
    Private mFrmName As String
    Private mParrentHasResized As Boolean
    Private mParrentHasLoaded As Boolean
    
    'Subclassing code by Paul_Caton@hotmail.com ----------------------------------------------------------------------------
    Private Enum eMsgWhen                                                       'When to callback
    
       MSG_BEFORE = 1                                                            'Callback before the original WndProc
       MSG_AFTER = 2                                                             'Callback after the original WndProc
       MSG_BEFORE_AFTER = MSG_BEFORE Or MSG_AFTER                                'Callback before and after the original WndProc
    
    End Enum
    
    Private Const ALL_MESSAGES  As Long = -1                                    'All messages callback
    Private Const MSG_ENTRIES   As Long = 32                                    'Number of msg table entries
    Private Const WNDPROC_OFF   As Long = &H38                                  'Thunk offset to the WndProc execution address
    Private Const GWL_WNDPROC   As Long = -4                                    'SetWindowsLong WndProc index
    Private Const IDX_SHUTDOWN  As Long = 1                                     'Thunk data index of the shutdown flag
    Private Const IDX_HWND      As Long = 2                                     'Thunk data index of the subclassed hWnd
    Private Const IDX_WNDPROC   As Long = 9                                     'Thunk data index of the original WndProc
    Private Const IDX_BTABLE    As Long = 11                                    'Thunk data index of the Before table
    Private Const IDX_ATABLE    As Long = 12                                    'Thunk data index of the After table
    Private Const IDX_PARM_USER As Long = 13                                    'Thunk data index of the User-defined callback parameter data index
    
    Private z_ScMem             As Long                                         'Thunk base address
    Private z_Sc(66)            As Long                                         'Thunk machine-code initialised here
    Private z_Funk              As Collection                                   'hWnd/thunk-address collection
    Private Declare Function CallWindowProcA Lib "user32" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function IsBadCodePtr Lib "kernel32" (ByVal lpfn As Long) As Long
    Private Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function SetWindowLongA Lib "user32" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function VirtualAlloc Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
    Private Declare Function VirtualFree Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
    Private Declare Sub RtlMoveMemory Lib "kernel32" (ByVal Destination As Long, ByVal Source As Long, ByVal Length As Long)
    
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Private Declare Sub CopyMemoryToMinMaxInfo Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As MINMAXINFO, ByVal hpvSource As Long, ByVal cbCopy As Long)
    Private Declare Sub CopyMemoryFromMinMaxInfo Lib "kernel32" Alias "RtlMoveMemory" (ByVal hpvDest As Long, hpvSource As MINMAXINFO, ByVal cbCopy As Long)
    Private Declare Sub CopyMemoryToSizingInfo Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As RECT, ByVal hpvSource As Long, ByVal cbCopy As Long)
    Private Declare Sub CopyMemoryFromSizingInfo Lib "kernel32" Alias "RtlMoveMemory" (ByVal hpvDest As Long, hpvSource As RECT, ByVal cbCopy As Long)
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    Private Declare Function RedrawWindow Lib "user32" (ByVal hwnd As Long, lprcUpdate As Any, ByVal hrgnUpdate As Long, ByVal fuRedraw As Long) As Long
    Private Declare Function SystemParametersInfo& Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long)
    Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Private Declare Function GetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
    Private Declare Function SetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
    Private Declare Function SetWindowPos Lib "user32.dll" (ByVal hwnd As _
    Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As _
    Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
    
    'WindowsPlacement
    Private Const SW_MINIMIZE As Long = 6
    Private Const SW_RESTORE As Long = 9
    Private Const SW_SHOWMINIMIZED As Long = 2
    Private Const SW_SHOWNORMAL As Long = 1
    Private Const SW_SHOWMAXIMIZED As Long = 3
    
    Private Type POINTAPI
       x As Long
       y As Long
    End Type
    
    Private Type MINMAXINFO
       ptReserved As POINTAPI
       ptMaxSize As POINTAPI
       ptMaxPosition As POINTAPI
       ptMinTrackSize As POINTAPI
       ptMaxTrackSize As POINTAPI
    End Type
    
    Private Type RECT
       Left As Long
       Top As Long
       Right As Long
       Bottom As Long
    End Type
    
    Private Type WINDOWPLACEMENT
       Length As Long
       flags As Long
       showCmd As Long
       ptMinPosition As POINTAPI
       ptMaxPosition As POINTAPI
       rcNormalPosition As RECT
    End Type
    
    Private mFrmRect As RECT
    
    Private Const WM_SIZE As Long = &H5
    Private Const WM_SIZING As Long = &H214
    Private Const WM_ENTERSIZEMOVE As Long = &H231&
    Private Const WM_EXITSIZEMOVE As Long = &H232&
    Private Const WM_GETMINMAXINFO As Long = &H24
    Private Const WM_SETREDRAW As Long = &HB
    Private Const RDW_INVALIDATE As Long = &H1
    Private Const RDW_INTERNALPAINT As Long = &H2
    Private Const RDW_ALLCHILDREN As Long = &H80
    Private Const RDW_UPDATENOW As Long = &H100
    Private Const WM_PAINT As Long = &HF
    Private Const SPI_GETWORKAREA As Long = &H30
    Private Const SIZE_MINIMIZED As Long = 1
    'Do not move the window.
    Private Const SWP_NOSIZE As Long = &H1
    Private Const SWP_DRAWFRAME = &H20
    
    
    
    Private mInitialHeight As Long, mInitialWidth As Long    'Initial (design) Height and Width values for the parent form
    Private WithEvents mFrm As Form
    
    'Private mInitWidth As Long, mInitHeight As Long     'The initial form size at design time (usefull for MDI child forms)
    Private mMinFormWidthPix As Long
    Private mMinFormHeightPix As Long
    Private mMaxFormWidthPix As Long
    Private mMaxFormHeightPix As Long
    
    'Public UseWinHook As Boolean    'Use winproc hooking to optimize min/max size handling (not using it causes flickering when limiting size)
    Public Event AfterResize(ByVal HeightChanged As Long, ByVal WidthChanged As Long)
    Public Event BeforeResize(FontSizeChangeFactor As Single)
    Private mAnchors As vbRichClient5.cCollection
    Private mCtlSizes As vbRichClient5.cCollection
    Private mSaveParentSizePos As Boolean
    Private mSaveFormSizePos As Boolean
    ' Variable to hold 'ResizeType' property value
    Private mResizeType As eResizeType
    
    Public Property Get FontResize() As Boolean
       FontResize = mFontResize
    End Property
    
    Public Property Let FontResize(ByVal Value As Boolean)
       mFontResize = Value
    End Property
    
    Public Property Get Anchors() As vbRichClient5.cCollection
    Set Anchors = mAnchors
    End Property
    
    Public Property Set Anchors(ByVal Value As vbRichClient5.cCollection)
    
    If Value.IsJSONObject Then
       Set mAnchors = Value
       PropertyChanged "Anchors"
    End If
    
    End Property
    
    Public Property Get ResizeType() As eResizeType
    ResizeType = mResizeType
    End Property
    
    Public Property Let ResizeType(ByVal Value As eResizeType)
    mResizeType = Value
    PropertyChanged "ResizeType"
    
    If Ambient.UserMode Then                                                              'If we're not in design mode
       SaveSetting mAppName, mFrmName, "ResizeType", mResizeType
       ResizeControls
    End If
    
    End Property
    
    Public Property Get SaveParentSizePos() As Boolean
    SaveParentSizePos = mSaveParentSizePos
    End Property
    
    Public Property Let SaveParentSizePos(ByVal Value As Boolean)
    mSaveParentSizePos = Value
    PropertyChanged "SaveParentSizePos"
    
    If Ambient.UserMode Then                                                               'If we're not in design mode
       SaveSetting mAppName, mFrmName, "SaveParentSizePos", mSaveParentSizePos
    End If
    
    End Property
    
    Friend Function FormControls() As Object
    'Used in propertypage
    'Returns the collection of controls on the parent form.
    Set FormControls = Parent.Controls
    End Function
    
    Friend Function GetAnchorsCollection() As vbRichClient5.cCollection
    Dim sJson As String
    'Used in propertypage
    'Get the anchor collection without a reference
    'Basically a clone, to make it possible to Cancel the page properly.
    sJson = mAnchors.SerializeToJSONString
    Set GetAnchorsCollection = New_c.JSONDecodeToCollection(sJson)
    End Function
    
    Friend Function NameOfForm() As String
    'Used in propertypage
    NameOfForm = Parent.Name
    End Function
    
    Private Sub InitControls()
    'On Error Resume Next
    Dim sKey As String
    Dim ctrl As Control
    Dim cAnchor As vbRichClient5.cCollection
    Dim cRefCtrls As vbRichClient5.cCollection
    Dim I As Long, T As Long, tStart As Long, tClose As Long, tMS As Long, N As Long
    Dim bChanged As Boolean
    
    'Dim sJSON As String
    'Dim aProp As PropertyBag
    If Not mAnchors Is Nothing Then
       Set cRefCtrls = New_c.Collection(False)
    
       'Build a reference collection
       For Each ctrl In Parent.Controls
    
          If IsSupportedControl(ctrl) Then
             sKey = GetCtrlNameWithIndex(ctrl)
             cRefCtrls.Add "1", sKey
          End If
    
       Next
    
       'Clean out stale items of removed controls
       For I = mAnchors.Count - 1 To 0 Step -1
          sKey = mAnchors.KeyByIndex(I)
    
          If Not cRefCtrls.Exists(sKey) Then
             mAnchors.Remove sKey
             bChanged = True
          End If
    
       Next
    
       'Check if all controls exists in collection
       For I = 0 To cRefCtrls.Count - 1
          sKey = cRefCtrls.KeyByIndex(I)
    
          If Not mAnchors.Exists(sKey) Then
             'add it with default anchor values
             mAnchors.Prop(sKey) = New_c.JSONDecodeToCollection(JSON_DEF_ANCHOR)
             bChanged = True
          End If
    
       Next
    
    Else
       Set mAnchors = New_c.JSONObject
    
       '   T = cTimerOpen
       '   tStart = cTimerStart(T)
       '
       '   For I = 1 To 5432100
       '      N = I * 2
       '   Next
       For Each ctrl In Parent.Controls
    
          If IsSupportedControl(ctrl) Then
             sKey = GetCtrlNameWithIndex(ctrl)
             'sJSON = "{""Left"":1,""Top"":1,""Right"":0,""Bottom"":0}"
             mAnchors.Prop(sKey) = New_c.JSONDecodeToCollection(JSON_DEF_ANCHOR)
          End If
    
       Next
    
       '   tMS = cTimerRead(T)
       '   tClose = cTimerClose(T)
       '   Debug.Print "Timer is " & CStr(tMS) & " ms"
       '   sJSON = mAnchors.SerializeToJSONString
       '   Set aProp = New PropertyBag
       '   aProp.WriteProperty "Anchors", sJSON, ""
       bChanged = True
    End If
    
    If bChanged Then
       PropertyChanged "Anchors"
    End If
    
    End Sub
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Problem with dynamic resising on controls on a form.

    You got to my post before I edited it. Please read my edited comments on my previous reply. Though we may not agree to the definition of proportional scaling, the gap issue I believe is hghlighted for you. I concede that you are attempting to scale the controls proportional to the change of the form, but not proportionally relative to the original shape of the form.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: Problem with dynamic resising on controls on a form.

    Second part, probably of 4
    Code:
    Private Sub InitCtrlSizes()
    Dim sJson As String
    Dim ctrl As Control
    Dim sKey As String
    
    Set mCtlSizes = New_c.JSONObject
    
    For Each ctrl In mFrm.Controls
    
       If IsSupportedControl(ctrl) Then
          sKey = GetCtrlNameWithIndex(ctrl)
    
          With ctrl
    
             If Not TypeOf ctrl Is Line Then
                sJson = "{""Left"":" & CStr(.Left \ mTwPerPxWidth) & ",""Top"":" & CStr(.Top \ mTwPerPxHeight) & ",""Width"":" & CStr(.Width \ mTwPerPxWidth) & ",""Height"":" & CStr(.Height \ mTwPerPxHeight)
    
                On Error Resume Next
    
                Err.Clear
                sJson = sJson & ",""FontSize"":" & CStr(.Font.Size) & "}"
    
                If Err.Number = 438 Then
                   sJson = sJson & "}"
                End If
    
                On Error GoTo 0
    
             Else
                sJson = "{""Left"":" & CStr(.X1 \ mTwPerPxWidth) & ",""Top"":" & CStr(.Y1 \ mTwPerPxHeight) & ",""Width"":" & CStr((.X2 - .X1) \ mTwPerPxWidth) & ",""Height"":" & CStr((.Y2 - .Y1) \ mTwPerPxHeight) & "}"
             End If
    
          End With
    
          mCtlSizes.Prop(sKey) = New_c.JSONDecodeToCollection(sJson)
       End If
    
    Next
    
    End Sub
    
    Private Sub ResizeByAnchor()
    '********************************************************
    '* Resizing only of anchored controls.
    '*******************************************************
    On Error Resume Next
    
    Dim nHeightChange As Long, nWidthChange As Long
    Dim sKey As String
    Dim cAnchor As vbRichClient5.cCollection
    Dim ctrl As Control
    
    'Calculate the change in pixels
    With mFrmRect
       nHeightChange = (.Bottom - .Top) - mInitialHeight
       nWidthChange = (.Right - .Left) - mInitialWidth
    End With
    
    If nHeightChange <> 0 Or nWidthChange <> 0 Then
    
       For Each ctrl In mFrm.Controls
    
          If IsSupportedControl(ctrl) Then
             sKey = GetCtrlNameWithIndex(ctrl)
    
             If mAnchors.Exists(sKey) Then
                Set cAnchor = mAnchors(sKey)
             Else
                Set cAnchor = New_c.JSONDecodeToCollection(JSON_DEF_ANCHOR)
             End If
    
             With ctrl
    
                If nWidthChange Then
                   If cAnchor("Left") And cAnchor("Right") Then
                      If Not TypeOf ctrl Is Line Then
                         .Width = (mCtlSizes(sKey)("Width") + nWidthChange) * mTwPerPxWidth
                      Else
                         .X2 = (mCtlSizes(sKey)("Width") + nWidthChange) * mTwPerPxWidth
                      End If
    
                   ElseIf cAnchor("Right") Then
    
                      If Not TypeOf ctrl Is Line Then
                         .Left = (mCtlSizes(sKey)("Left") + nWidthChange) * mTwPerPxWidth
                      Else
                         .X1 = (mCtlSizes(sKey)("Left") + nWidthChange) * mTwPerPxWidth
                         .X2 = (mCtlSizes(sKey)("Width") + nWidthChange) * mTwPerPxWidth
                      End If
                   End If
                End If
    
                If nHeightChange Then
                   If cAnchor("Top") And cAnchor("Bottom") Then
                      If Not TypeOf ctrl Is Line Then
                         .Height = (mCtlSizes(sKey)("Height") + nHeightChange) * mTwPerPxHeight
    
                         If mFontResize Then
                            If Not (TypeOf ctrl Is UniCheck Or TypeOf ctrl Is UniOption) Then
                               .Font.Size = mCtlSizes(sKey)("FontSize") * mFontSizeChangeFactor
                            Else
                               .Font.Size = mCtlSizes(sKey)("FontSize") * (mFontSizeChangeFactor - ((mFontSizeChangeFactor - 1) / 2))
                            End If
                         End If
    
                      Else
                         .Y2 = (mCtlSizes(sKey)("Height") + nHeightChange) * mTwPerPxHeight
                      End If
    
                   ElseIf cAnchor("Bottom") Then
    
                      If Not TypeOf ctrl Is Line Then
                         .Top = (mCtlSizes(sKey)("Top") + nHeightChange) * mTwPerPxHeight
    
                         If mFontResize Then
                            If Not (TypeOf ctrl Is UniCheck Or TypeOf ctrl Is UniOption) Then
                               .Font.Size = mCtlSizes(sKey)("FontSize") * mFontSizeChangeFactor
                            Else
                               .Font.Size = mCtlSizes(sKey)("FontSize") * (mFontSizeChangeFactor - ((mFontSizeChangeFactor - 1) / 2))
                            End If
                         End If
    
                      Else
                         .Y1 = (mCtlSizes(sKey)("Top") + nHeightChange) * mTwPerPxHeight
                         .Y2 = (mCtlSizes(sKey)("Height") + nHeightChange) * mTwPerPxHeight
                      End If
                   End If
                End If
    
             End With
    
          End If
    
       Next
    
       'RaiseEvent AfterResize(nHeightChange, nWidthChange)
    End If
    
    End Sub
    
    Private Sub ResizeControls()
    '***********************************************************************
    '* Initiates the resize by setting up basic values used for
    '* both anchored and proportional resize. To avoid flickering,
    '* freezes the window before deciding what type of resize to do
    '* and then call its function accordingly.
    '*
    '* Then unfreez and redraws the window to display the resize that have happened.
    '************************************************************************
    With mFrm
    
       ' Don't bother if we are minimized.
       If .WindowState <> vbMinimized Then
          If Not mCtlSizes Is Nothing Then
             If mCtlSizes.Count > 0 Then
                GetWindowRect .hwnd, mFrmRect
    
                With mFrmRect
                   mHeightChangeFactor = (.Bottom - .Top) / mInitialHeight
                   mWidthChangeFactor = (.Right - .Left) / mInitialWidth
                End With
    
                mFontSizeChangeFactor = (mHeightChangeFactor + mWidthChangeFactor) / 2
    
                If mFontSizeChangeFactor > mHeightChangeFactor Then
                   mFontSizeChangeFactor = mHeightChangeFactor
                End If
    
                'Debug.Print "WindowRect"
                'Debug.Print "mHeightChangeFactor" & mHeightChangeFactor
                'Debug.Print "mWidthChangeFactor" & mWidthChangeFactor
                'Debug.Print "mFontSizeChangeFactor" & mFontSizeChangeFactor
                'Mainly to allow specific fontsize handling in PictureBox
                RaiseEvent BeforeResize(mFontSizeChangeFactor)
                'Freeze the Application
                'Freezing the Control Redraws makes the application faster in resizing controls.
                SendMessage .hwnd, WM_SETREDRAW, 0&, 0
    
                If mResizeType = rtProportional Then
                   Call ResizeProportionally
                Else
                   Call ResizeByAnchor
                End If
    
                'Unfreeze the application and redraw the window after the resize
                SendMessage .hwnd, WM_SETREDRAW, 1&, 0
                RedrawWindow .hwnd, ByVal 0&, ByVal 0&, RDW_INVALIDATE Or RDW_UPDATENOW Or RDW_ALLCHILDREN
             End If
          End If
       End If
    
    End With
    
    End Sub
    
    Private Sub ResizeProportionally()
    '***********************************************************************
    '* Resizes controls proportionally according to the factor for widths
    '* and heights as calculated in ResizeControls function.
    '*
    '* mCtlSizes is a vbRichclient5 collection in JSON mode that store all
    '* controls original position values.
    '***************************************************************************
    
    Dim ctrl As Control
    Dim sKey As String
    
    If Not mCtlSizes Is Nothing Then
    
       For Each ctrl In mFrm.Controls
    
          If IsSupportedControl(ctrl) Then
             sKey = GetCtrlNameWithIndex(ctrl)
    
             With ctrl
    
                If Not TypeOf ctrl Is Line Then
                   .Left = (mCtlSizes(sKey)("Left") * mWidthChangeFactor) * mTwPerPxWidth
                   .Top = (mCtlSizes(sKey)("Top") * mHeightChangeFactor) * mTwPerPxHeight
                   .Width = (mCtlSizes(sKey)("Width") * mWidthChangeFactor) * mTwPerPxWidth
    
                   If Not TypeOf ctrl Is UniCombo Then
                      ' Cannot change height of ComboBoxes.
                      .Height = (mCtlSizes(sKey)("Height") * mHeightChangeFactor) * mTwPerPxHeight
                   End If
    
                   On Error Resume Next
    
                   If mFontResize Then
                      
                      If Not (TypeOf ctrl Is UniCheck Or TypeOf ctrl Is UniOption Or TypeOf ctrl Is UniFrame) Then
                         If Not TypeOf ctrl Is PictureBox Then
                         .Font.Size = mCtlSizes(sKey)("FontSize") * mFontSizeChangeFactor
                         End If
                      Else
                         'reduce font size increase for these controls
                         .Font.Size = mCtlSizes(sKey)("FontSize") * (mFontSizeChangeFactor - ((mFontSizeChangeFactor - 1) / 2))
                      End If
                   End If
    
                   On Error GoTo 0
    
                Else
                   .X1 = (mCtlSizes(sKey)("Left") * mTwPerPxWidth) * mWidthChangeFactor
                   .Y1 = (mCtlSizes(sKey)("Top") * mTwPerPxHeight) * mHeightChangeFactor
                   .X2 = .X1 + (mCtlSizes(sKey)("Width") * mTwPerPxWidth) * mWidthChangeFactor
                   .Y2 = .Y1 + (mCtlSizes(sKey)("Height") * mTwPerPxHeight) * mHeightChangeFactor
                End If
    
             End With
    
          End If
    
       Next
    
    End If
    
    End Sub
    
    Private Sub mFrm_Load()
    Dim nLeft As Long, nTop As Long, nWidth As Long, nHeight As Long
    Dim rtn As Long
    Dim uRect As RECT
    Dim wp As WINDOWPLACEMENT
    Dim I As Long
    Dim sKey As String
    
    mAppName = App.EXEName
    mFrmName = mFrm.Name
    mSaveFormSizePos = False 'CBool(GetSetting(mAppName, mFrmName, "SaveFormSizePos", mSaveParentSizePos))
    Call InitCtrlSizes
    
    If mAnchors.Count > mCtlSizes.Count Then
    
       For I = 0 To mAnchors.Count - 1
          sKey = mAnchors.KeyByIndex(I)
          Debug.Assert mCtlSizes.Exists(sKey)
          'If Not mCtlSizes.Exists(sKey) Then
          '   Debug.Print "Missing: " & sKey
          'End If
       Next
    
    End If
    
    If Not mSaveFormSizePos Then
    
       With uRect
          .Left = (mMaxFormWidthPix - mMinFormWidthPix) \ 2
          .Top = (mMaxFormHeightPix - mMinFormHeightPix) \ 2
          .Right = .Left + mMinFormWidthPix
          .Bottom = .Top + mMinFormHeightPix '+ (300 / mTwPerPxHeight)
       End With
    
       'SetWindowPos mFrm.hwnd, 0&, (mMaxFormWidthPix - mMinFormWidthPix) \ 2, (mMaxFormHeightPix - mMinFormHeightPix) \ 2, 0, 0, SWP_NOSIZE Or SWP_DRAWFRAME
    Else
    
       'Restore last form position and size
       ' Initialize wp from the registry.
       With uRect
          .Left = GetSetting(mAppName, mFrmName, "Left", (mMaxFormWidthPix - mMinFormWidthPix) \ 2)
          .Top = GetSetting(mAppName, mFrmName, "Top", (mMaxFormHeightPix - mMinFormHeightPix) \ 2)
          .Right = GetSetting(mAppName, mFrmName, "Right", .Left + mMinFormWidthPix)
          .Bottom = GetSetting(mAppName, mFrmName, "Bottom", .Top + mMinFormHeightPix)
       End With
    
    End If
    
    With wp
       .Length = Len(wp)
       .flags = GetSetting(mAppName, mFrmName, "flags", 0)
       .showCmd = GetSetting(mAppName, mFrmName, "showCmd", SW_RESTORE)
       .ptMinPosition.x = GetSetting(mAppName, mFrmName, "MinX", 100)
       .ptMinPosition.y = GetSetting(mAppName, mFrmName, "MinY", 100)
       .rcNormalPosition = uRect
    End With
    
    SetWindowPlacement mFrm.hwnd, wp
    ResizeControls
    mParrentHasLoaded = True
    End Sub
    
    Private Sub mFrm_Resize()
    '****************************************************************
    '* Reference to the parent form and its event.
    '* The first resize is when the form is created and its proper
    '* dimensions as in design is established at run time. Here we first
    '* grab and save these values for later use, to have a solid baseline
    '* to resize from. So we will always resize in relation to this baseline.
    '*
    '* The very first control resize takes place in the form load event, to
    '* properly deal with the situation when the program starts up Maximized.
    '* The following resizing of controls, in response to user resize of form,
    '* is initiated here by calling the ResizeControls function.
    '*****************************************************************
    If Not mParrentHasResized Then
       'The very first resize as the form is created.
       'Get original (development) form dimension
       GetWindowRect mFrm.hwnd, mFrmRect
    
       With mFrmRect
          mInitialHeight = .Bottom - .Top
          mInitialWidth = .Right - .Left
       End With
    
       mMinFormHeightPix = mInitialHeight
       mMinFormWidthPix = mInitialWidth
    
       If mMinFormHeightPix > mMaxFormHeightPix Then
          mMinFormHeightPix = mMaxFormHeightPix
       End If
    
       If mMinFormWidthPix > mMaxFormWidthPix Then
          mMinFormWidthPix = mMaxFormWidthPix
       End If
    
       mParrentHasResized = True
    Else
    
       If mParrentHasLoaded Then
          'Don't respond to and resize controls until form fully loaded
          Call ResizeControls
       End If
    End If
    
    End Sub
    
    Private Sub mFrm_Unload(Cancel As Integer)
    Dim disallow_minimized As Boolean
    Dim wp As WINDOWPLACEMENT
    Dim tRect As RECT
    Dim rtn As Long
    Dim sName As String
    
    ' Do nothing if the form is not visible.
    If Not mFrm.Visible Or mFrm.WindowState = vbMinimized Then Exit Sub
    ' Get the window's normalized placement.
    wp.Length = Len(wp)
    GetWindowPlacement mFrm.hwnd, wp
    
    With wp
    
       If ((.showCmd = SW_MINIMIZE) Or (.showCmd = SW_SHOWMINIMIZED)) Then
          SaveSetting mAppName, mFrmName, "showCmd", SW_SHOWNORMAL
       Else
          SaveSetting mAppName, mFrmName, "showCmd", .showCmd
       End If
    
       SaveSetting mAppName, mFrmName, "flags", .flags
       SaveSetting mAppName, mFrmName, "MinX", .ptMinPosition.x
       SaveSetting mAppName, mFrmName, "MinY", .ptMinPosition.y
    
       With .rcNormalPosition
          SaveSetting mAppName, mFrmName, "Left", .Left
          SaveSetting mAppName, mFrmName, "Top", .Top
          SaveSetting mAppName, mFrmName, "Right", .Right
          SaveSetting mAppName, mFrmName, "Bottom", .Bottom
       End With
    End With
    
    End Sub
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: Problem with dynamic resising on controls on a form.

    Quote Originally Posted by LaVolpe View Post
    You don't mention how you are calculating your change factor variables. And proportional scaling may not be completely described by you. Proportional to what? The form's original size, the control's original size? In either case, a 'gap' would be expected if the form is not resized proportionally.

    Edited: I see the answers to my question above. You are not proportionally scaling anything in my opinion. Let's assume the form was 500x500 square at startup and user dragged the height another 500 pixels. Ok, your control would scale twice as tall now because mHeightChangeFactor = 2 & mWidthChangeFactor = 1, correct? That is not proportional scaling IMO. It is the same as stretching

    When scaling proportionally, you will scale the height & width by the same factor...

    Let's say you have a square control, i.e., a picturebox at 200x200 pixels. Ok, now someone drags just the bottom edge of the form 500 pixels so it is 500 pixels taller but the same width. If you were scaling the control proportionally on either the original dimensions of the form or the control, then the control wouldn't resize in that case, it would still remain 200x200 if the control is to remain completely visible on the form, even though the form is now 500 pixels taller. Proportional scaling is based on either the change of height or change of width, not both. Usually you'd choose the lower change value/ratio.

    Edited Again. The gap issue can be described with this scenario:
    1. Form: 500x500: Control 100x100
    2. Form resizes height only by 500 pixels
    3. Anchored method: control resizes to 100x600 (500 pixel change)
    4. Proportional method: control resizes to 100x200 (2x height change). Gap is significant
    Ok I will halt pasting of code for now, in case it may not be needed... Well, proportional or stretching and it might be as you say. What I mean by proportional is in relation to original, width or hight independently. So yes, if the user just increases the hight the resize will only be on the hight, that's how I want it to be. So what you say is that this is unavoidable when resizing controls based on a factor from how much the form has resized?

    It's not a big issue, everything resizes fine, with loads of controls on the form. Internally they resize without overlapping, or gapping, it's just this gap that increases at the forms bottom end. Anyway, I cannot see any other way to do this "proportional" (or stretching) way all controls are to be resized, unless the anchored model is chosen, can you?

    I just thought I had it before without a gap and then I suddenly saw it after some changes, but maybe it was there all the time and I was just focused on other things.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  7. #7
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Problem with dynamic resising on controls on a form.

    So what you say is that this is unavoidable when resizing controls based on a factor from how much the form has resized?
    Yes.

    A couple minor notes:

    1. You are individually adjusting the left,top,width,height members of the control. A .Move method would be more pleasing to the user. Let's say a textbox with wrapping is has its width set, then its height set. If the control redraws between those property changes, the text format will be change visibly as each are set. Similar issue with say a Image control with Stretch property set to true. Not only that, setting each of those individually could result in 4 separate re-draw events vs. just 1 for a single .Move command. Though those visible issues are attempted to be handled with a SetRedraw API call, overall efficiency can be increased using .Move

    2. You have several lines of code like m[xxx]ChangeFactor * mTwPerPx[xxx]. A bit more efficient if they were multiplied once, assuming it doesn't break some code elsewhere in other functions/methods
    Code:
                With mFrmRect
                   mHeightChangeFactor = (.Bottom - .Top) / mInitialHeight * mTwPerPxHeight
                   mWidthChangeFactor = (.Right - .Left) / mInitialWidth * mTwPerPxWdith
                End With
    3. Wouldn't recommend resizing based on original size of form. Form can change ScaleHeight when menu items exist and form is scaled smaller. The menus can wrap to another line and the client height is resized. Less real estate for the controls. I think a more appropriate base-factor would be the client rectangle, not overall rectangle of the form..

    Anyway, I cannot see any other way to do this "proportional" (or stretching) way all controls are to be resized, unless the anchored model is chosen, can you?
    It's up to the user. However, many design their forms to look the way they want them to look. I personally wouldn't want a vast majority of my projects to have control's stretched to some shape not proportional to the shape I designed them in. In other words, if I used a resizer control, one of the options it must provide is proportional resizing based on the original shape of the form/controls.
    Last edited by LaVolpe; Aug 8th, 2015 at 09:54 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  8. #8

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: Problem with dynamic resising on controls on a form.

    Quote Originally Posted by LaVolpe View Post
    So what you say is that this is unavoidable when resizing controls based on a factor from how much the form has resized?
    Yes.
    Guess I'll have to live with that then.

    Quote Originally Posted by LaVolpe View Post
    A couple minor notes:

    1. You are individually adjusting the left,top,width,height members of the control. A .Move method would be more pleasing to the user. Let's say a textbox with wrapping is has its width set, then its height set. If the control redraws between those property changes, the text format will be change visibly as each are set. Similar issue with say a Image control with Stretch property set to true. Not only that, setting each of those individually could result in 4 separate re-draw events vs. just 1 for a single .Move command. Though those visible issues are attempted to be handled with a SetRedraw API call, overall efficiency can be increased using .Move
    Yes there are room for improvements, I know. I just wanted to get it overall working first of all. I haven't had time to investigate this yet, but one can rely on that each and every control that has .Left, .Top, .Width and .Hight properties also have a .Move method?

    Quote Originally Posted by LaVolpe View Post
    2. You have several lines of code like m[xxx]ChangeFactor * mTwPerPx[xxx]. A bit more efficient if they were multiplied once, assuming it doesn't break some code elsewhere in other functions/methods
    Code:
                With mFrmRect
                   mHeightChangeFactor = (.Bottom - .Top) / mInitialHeight * mTwPerPxHeight
                   mWidthChangeFactor = (.Right - .Left) / mInitialWidth * mTwPerPxWdith
                End With
    I don't think that will work actually, you have probably mixed up the 2 different calculations used for anchored and stretched resize. But I will investigate.

    Quote Originally Posted by LaVolpe View Post
    3. Wouldn't recommend resizing based on original size of form. Form can change height when menu items exist and form is scaled smaller. The menus can wrap to another line and the height is resized. I think a more appropriate base-factor would be the client rectangle, not overall rectangle of the form..


    It's up to the user. However, many design their forms to look the way they want them to look. I personally wouldn't want a vast majority of my projects to have control's stretched to some shape not proportional to the shape I designed them in. In other words, if I used a resizer control, one of the options it must provide is proportional resizing based on the original shape of the form/controls.
    While 3. is true, in this version of the control I have set the original dimension as a minimal size, unless it's run on a device with lower resolution that I base my forms max design size on, 1024x768px so it should be a non-event in this case. I'm developing this control for my own needs and will then add it to the code bank and anyone can modify according to their needs.

    As for the (non)proportional resizing, it's basically to satisfy user requests. I am replacing old resizing code of this sort based on resolutions and when I did so I though "hey why resize this form, it looks good and there is no need..." I though, and made a test with some users and it turned out that some just want to have the form full screen no matter what so ever. So I am creating something that reminds of the old behaviour for these users, as I am dead bent to remove that old resize code that originally is from a time when 1024x768 was "big". Anyway, I think this is solved. Thanks for your help.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    You resolved this and the following comment is just for thoughts:

    If you were to use the client rectangle vs the overall form rectangle, these advantages do present themselves:

    1. The controls are always sized when the client area is resized, i.e., ScaleWidth and/or ScaleHeight changes value. In the scenario I gave with menu items wrapping/unwrapping, the physical size of the form does NOT change, but the client area does change. When menus wrap, this will have the effect of any 'bottom-aligned' controls being clipped by the bottom of the form. You can see this with the VB IDE.
    - size the IDE so it is as tall as your screen
    - within the client area, open a form, class, whatever. Then drag it's bottom edge to the bottom edge of the visible client area
    - now drag the right edge of the IDE window until the IDE menus wrap to another line
    - you will see that the bottom edge of whatever you had open in the client area is now clipped

    2. You would no longer need to call GetWindowRect nor perform calculations like .Right-Left, etc. The form's ScaleWidth & ScaleHeight properties can be used instead. The API version of those would be GetClientRect.

    Afterthoughts:

    1. Regarding what I'd personally expect from proportional resizing, just to make myself clear. Let's say I have a control that had equal width & height. Regardless of how the form were sized, the control would always remain a square shape.

    2. Don't know the reasons for using that richclient DLL/OCX. If it just for subclassing, about a dozen or so lines of VB6 code can be used instead of attaching another dependency to your project.

    3. Improvements to consider:
    - Allow option for control to be sized vertically, horizontally or both. Example. Maybe we don't want line controls be thicker
    - Definitely add option for proportional scaling based on original control size. IMO, few would truly use it otherwise
    - Consider cases where the control has the VB Align property set, i.e., pictureboxes

    I'm sure that if you pursue this project and later post additional questions or request feedback, many would offer other suggestions. Have fun & have a good weekend
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Quote Originally Posted by LaVolpe View Post
    You resolved this and the following comment is just for thoughts:


    2. You would no longer need to call GetWindowRect nor perform calculations like .Right-Left, etc. The form's ScaleWidth & ScaleHeight properties can be used instead. The API version of those would be GetClientRect.
    Thanks for all your points and I will examine them one by one, but to start with I was thinking of using the client rectangle, but how do I detect that it resizes? As you pointed out yourself, it can change size without the form necessarily resizes so how to detect it? Do have to use subclassing?

    I have some subclass code in place, which I don't fully understand but I decided for it bc it doesn't need a bas module but can be self contained in the control.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  11. #11
    New Member
    Join Date
    Aug 2015
    Posts
    4

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    i need u help for timeGetTime, QueryPerformanceCounter, GetTickCount api hooking

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Quote Originally Posted by exe676 View Post
    i need u help for timeGetTime, QueryPerformanceCounter, GetTickCount api hooking
    Please start your own topic, no one will answer you here. What you just did is called to hijack a topic and is not considered nice. No appols needed, just start a new topic.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  13. #13
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    7edm... Client size changes when form size changes whether or not menus exist, whether or not they wrap. So, you would simply compare the cached client rect with the new client rect when your form resizes.

    Note you'll also get a resize event/message in this unique scenario:
    1. Form has menu and sized just barely wide enough that the menu wrapped
    2. Code inside form is activated that hides one of the menu items which unwraps the menu and form client area resizes as expected
    3. Even though the form itself did not resize, its width/height remained the same, the resize event/message still triggers
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  14. #14

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    So this also cover the situation you described above, the client rectangle changes without the actual form size changes, but form resize event fires?
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  15. #15

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Experiencing something really strange here, not exactly relation to this resize issue but regarding the sequencial order of firing form events. On my start up form, where I have tested the control so far, the resize event fires before the load event. However, I now tested the control on another form and got them firing in the oposite order, so load fired first and then resize - which seems logical to me - so is this just by random and how can I then with certainty read the forms original size?

    This is of importance not only for the resizing but the control also keep track of size and position of the window between runs.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  16. #16
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    I'd imagine the answer to the question for your purposes is: after the form has been made visible for the first time. That way, if there is any manual resizing code (internal to VB or user-code) within the form's Load or Resize event that gets executed before it is shown, the controls will be the desired size/position once it is shown. Maybe trap the WM_SHOWWINDOW message & cache your control sizes/positions at that point? Keep in mind that message can be sent more than once, i.e., Me.Visible = False: Me.Visible = True. So you may want to keep a value around that determines whether or not the controls were already processed once or test some existing value that would change once the controls have been processed

    So this also cover the situation you described above, the client rectangle changes without the actual form size changes, but form resize event fires?
    Yes
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  17. #17

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Ok thanks, guess it's back to the drawing table once again... but that's no problem as long as we are having fun!
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  18. #18

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Ok I will try to make use of trapping WM_SHOWWINDOW, but would like to ask you for some further assistance with the subclassing and possibly if you understand more about my subclass routine (by Paul Caton) than I do ;-) I do have some basic understanding of the subject, but this selfsub seem to work a bit differently than other code \i have studied, and probably by reason as it can all be contained inside the control.

    What I don't fully understand with this model is the part where you are supposed pass on a return value or not depending on if the message is handled or not. So here if I now read and act on the values the WM_SHOWWINDOW, do I need to do something more? As I see it I'm just a passive listener here and doesn't exactly act on the message itself or do I have it wrong there? For now I have just put debug.print calls there to study but will later, if successful, add some active code like probably get both window and client rectangle and maybe even position the window.

    Code:
    '-Subclass callback, usually ordinal #1, the last method in this source file----------------------
    Private Sub zWndProc1(ByVal bBefore As Boolean, ByRef bHandled As Boolean, ByRef lReturn As Long, ByVal lng_hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByRef lParamUser As Long)
    '*************************************************************************************************
    '* bBefore    - Indicates whether the callback is before or after the original WndProc. Usually
    '*              you will know unless the callback for the uMsg value is specified as
    '*              MSG_BEFORE_AFTER (both before and after the original WndProc).
    '* bHandled   - In a before original WndProc callback, setting bHandled to True will prevent the
    '*              message being passed to the original WndProc and (if set to do so) the after
    '*              original WndProc callback.
    '* lReturn    - WndProc return value. Set as per the MSDN documentation for the message value,
    '*              and/or, in an after the original WndProc callback, act on the return value as set
    '*              by the original WndProc.
    '* lng_hWnd   - Window handle.
    '* uMsg       - Message value.
    '* wParam     - Message related data.
    '* lParam     - Message related data.
    '* lParamUser - User-defined callback parameter
    '*************************************************************************************************
    Dim MinMax As MINMAXINFO
    
    Select Case uMsg
    Case WM_GETMINMAXINFO
       If mParrentHasLoaded Then
          'Retrieve default MinMax settings
          CopyMemoryToMinMaxInfo MinMax, lParam, Len(MinMax)
          'Specify new minimum size for window.
          MinMax.ptMinTrackSize.x = mMinFormWidthPix
          MinMax.ptMinTrackSize.y = mMinFormHeightPix
    
          'Specify new maximum size for window.
          If mMaxFormWidthPix >= mMinFormWidthPix Then
             MinMax.ptMaxTrackSize.x = mMaxFormWidthPix
          End If
    
          If mMaxFormHeightPix >= mMinFormHeightPix Then
             MinMax.ptMaxTrackSize.y = mMaxFormHeightPix
          End If
    
          'Copy local structure back.
          CopyMemoryFromMinMaxInfo lParam, MinMax, Len(MinMax)
       End If
    
       Case WM_SHOWWINDOW
    
           Debug.Print "wParam " & wParam
           Debug.Print "lParam " & lParam
       
    End Select
    
    End Sub
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  19. #19
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    If you are only listening, never set the bHandled to true. If you set bHandled to true, you must also pass the appropriate return value for that particular message. Each message should be reviewed on MSDN to see what return values are expected. If bHandled is set to true, then VB won't get the message. Even as a listener only, you can modify the message parameters (in many cases) so that VB gets a different value than what was originally sent. That is what is happening in the WM_GETMINMAXINFO portion of your posted code. Regarding the WM_SHOWWINDOW, that should be an 'after' message, not 'before', just in case additional stuff is being done before VB returns from that message. Also, be sure to check the parameter values; they indicate whether window is being shown or hidden.

    Tip: Don't know how mParrentHasLoaded is being set. But it is possible that WM_GETMINMAXINFO is the 1st message a window procedure receives, even before a WM_CREATE

    Edited: That TIP was just FYI. In your case, it isn't applicable. The usercontrol won't be created before its container is created. Since your subclassing occurs from your usercontrol, any WM_GETMINMAXINFO you trap will be well after the subclassed window has been created.
    Last edited by LaVolpe; Aug 8th, 2015 at 01:49 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  20. #20
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    FYI: The model of Caton's subclassing looks like this
    Code:
    message round trip
    [O/S] > [?] > subclasser > [?] > hWnd ----|
                                              |
    [O/S] < [?] < subclasser < [?] < [rtn val]|
    
    during sending phase, parameters can be changed
    during return phase, return value can be changed
    the [?] are other subclassers that may exist above & below yours
    The subclassing procedure looks like this
    Code:
    If [before] Then ' sending phase
        - modify parameters if wanted
        - track if needed
        - if needed, prevent forwarding down the chain by setting bHandled & return value
    Else [after] ' return phase
        - modify return value if needed (don't know if Caton's routines allow this option)
        - track if needed
    End If
    Edited: During the sending phase, any subclasser can short-circuit any subclassers below them by sending the message directly via the DefWindowProc API. If there is a need for this (not recommended), the message should be declared as handled to prevent it from continuing down the chain.
    Last edited by LaVolpe; Aug 8th, 2015 at 02:25 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  21. #21

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Ok several things to take in here... first, mParrentHasLoaded is set very last in the form_load event, used both here for WM_GETMINMAXINFO to strip out unnecessary processing, and in form resize event also to avoid unnecessary repeat of control resizing as these events/messages fires several times as things gets going. But maybe I have found a new approach now so I don't need that flag.

    As for WM_SHOWWINDOW, what would it mean to "handle" that message? Like if I made my SetWindowPlacement call there to size and place the form window when it loads, would that be to handle it? MSDN says "If an application processes this message, it should return zero." but what exactly does it mean to "process" it, changing any of lParam or wParam values or e.g. set size and pos with SetWindowPlacement?

    Thanks for the explaination of the subclassing code, understand it a bit better now but still much to learn.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  22. #22
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Handled as far as Paul Caton's subclassing: do not forward the message any further. It stops with your subclass procedure. The return value is set by you. If you are passing the message down the chain, you are not handling the message, just reviewing/modifying it.

    Processing as far as MSDN is concerned: Similar to Caton's handled. It doesn't mean that the hWnd had to do any action. It means that the procedure simply saw the message and made a decision to act or not act on it. Maybe a message is sent that isn't handled/processed by the hWnd. This could be for a couple reasons, i.e., the message doesn't apply therefore ignored internally. If it's not processed, then whatever sent the window the message may take action. Kinda like: if you don't do something with this, I might, otherwise I'll honor your actions. An unhandled message may trigger follow-up message traffic? It really depends on the sender which doesn't have to be the operating system. The return value is not always a true/false type of value and it depends on the specific message. Unhandled messages may be sent to the default window procedure for that window class.

    Edited: I've always considered messages that say zero should be the return value as an info-only message. Why? Well imagine a window procedure, a lot of Select Case statements for the various messages it handles. Well, if a message it doesn't handle, unaware of, is received, then it flows thru the procedure untouched. And the default return of many functions is simply zero.

    Examples of variety of return values: The WM_NCHITTEST message can return 1 of 26 different values. WM_GETICON returns an Icon handle
    Last edited by LaVolpe; Aug 8th, 2015 at 02:59 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  23. #23
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Hmmmm... Maybe WM_SHOWWINDOW isn't ideal. You may not get the message if the VB startup property is Maximized. Didn't realize that message may not be fired in that case, until I re-read the remarks for that specific message.

    Per this link, maybe WM_WINDOWPOSCHANGED is a better choice.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  24. #24

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Quote Originally Posted by LaVolpe View Post
    Hmmmm... Maybe WM_SHOWWINDOW isn't ideal. You may not get the message if the VB startup property is Maximized. Didn't realize that message may not be fired in that case, until I re-read the remarks for that specific message.

    Per this link, maybe WM_WINDOWPOSCHANGED is a better choice.
    Ok I will test for that and see if it applies for my intended uses. I mean, I am really just interested when the form is initially loaded and shown by user action and I think that always is as Normal. But thanks for pointing it out and I will check. A negative with WM_WINDOWPOSCHANGED is that it give no clue about if the form was launched or not. With WM_SHOWWINDOW I can check wParam which is True with the window is about to show and lParam which is set to 0 if it is due to a call to the ShowWindow function (or frm.Show in VB6).

    I will test and see what I come up with but I think I'm on more stable ground with it now, and thanks a lot for your help.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  25. #25
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Quote Originally Posted by 7edm View Post
    A negative with WM_WINDOWPOSCHANGED is that it give no clue about if the form was launched or not. With WM_SHOWWINDOW I can check wParam which is True with the window is about to show and lParam which is set to 0 if it is due to a call to the ShowWindow function (or frm.Show in VB6).
    Not so. The lParam of that message contains a 28 byte WINDOWPOS structure. The last member of that structure contains what you are looking for: If (.Flags And SWP_SHOWWINDOW) = SWP_SHOWWINDOW then the window is being shown. You retrieve that structure very similar to how you retrieve the MINMAXINFO structure in your posted sample code.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  26. #26

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Hmm. Using the SetWindowPlacement call together with WM_SHOWWINDOW doesn't seem to work well as the function triggers a new message on each call, creating a loop of loading the window... can get around by setting a loaded flag of course but feels a bit hackish.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  27. #27

    Thread Starter
    Addicted Member
    Join Date
    Jun 2010
    Posts
    182

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    Ok, after changing to use GetClientRect API for the control resizing I can report there is still a small gap at the bottom opening up BUT much less than before and as an end user you probably wont notice. It's just me looking at it focused on details. So my "fake proportional" resizing mode now seem to work perfectly. I will look at also implementing a true proportional mode. Let me just explain the need for this fake mode. It appears to me that some (of my programs) end users seem to be disturbed by the situation if the form cannot resize to fill the full screen display. It doesn't look "aesthetic" with part of the desktop "shining through" on the side(s). So, the user is always correct... but options are of course the best way to go.
    M$ vs. VB6 = The biggest betrayal and strategic mistake of the century!?

  28. #28
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [RESOLVED] Problem with dynamic resising on controls on a form.

    The slight clipping may be due to some rounding errors when calculating the control's scaled width/height and/or adjusting the top/left especially if they are offset by a previous controls top/left -- kinda snowball effect. But I'll leave that to you to troubleshoot if you are a perfectionist.

    Yep, depends on the customer. But if I were a customer, proportional scaling would be a primary concern for me. Again, if the form layout I designed was square (to make this somewhat easy to explain), I'd expect that when maximized on a non-square display (as all monitors seem to be), then the controls wouldn't fill out the maximized form -- perfectly reasonable. I can visualize what your customer is saying too and understand it is not the same requirement I'd demand as a customer. Though customers are always right, rarely do they all agree. However, knowing this and if I wanted to fill the form out more while maintaining proportional sizing, what to do?

    1. Live with it. Maybe scale positions relative to the center of the form. Sizes are proportional and centered vs anchored top/left.

    2. Use non-proportional scaling when compared to original control sizes, similar to what you have now.

    3. Filling the excess space by adjusting the top/left positions of the controls as they were proportionally scaled. This of course is probably far more complicated. The end result would be proportional scaling in respect to size, but more 'space' between controls to fill the entire form. And that is what I'd call a compromise between proportional & non-proportional scaling: proportional dimensions mixed with non-proportional positioning

    4. Set the MINMAXINFO so that the form can never be scaled beyond proportions. That way the controls would 'fill out' the form.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width