home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Advanced Visual Basic Techniques
(Publisher: John Wiley & Sons, Inc.)
Author(s): Rod Stephens
ISBN: 0471188816
Publication Date: 06/01/97

Search this book:
 
Previous Table of Contents Next


Once it has determined how large each row and column should be, ArrangeRowColControls moves the controls to their final locations.

Sub AlignRowsAndCols()

Dim the_controls As VBIDE.SelectedControlTemplates
Dim controls() As VBIDE.ControlTemplate
Dim tops() As Single
Dim lefts() As Single
Dim num_rows As Integer
Dim num_cols As Integer
Dim spacing As Single
Dim i As Integer

    On Error GoTo AlignError
    
    Set the_controls = VBInstance.ActiveProject _
        .ActiveForm.SelectedControlTemplates
    
    ‘ Get user input values.
    num_rows = CInt(AlignerDialog.NumRowsText.Text)
    num_cols = CInt(AlignerDialog.NumColsText.Text)
    spacing = CSng(AlignerDialog.SpaceText.Text)
    If num_rows * num_cols <> the_controls.Count Then
        Beep
        MsgBox "(# Rows) * (# Cols) does not equal the number of controls you selected.", _
            vbOKOnly + vbInformation, _
            "Error Aligning Controls"
        Exit Sub
    End If
    
    ‘ Allocate room for the control tamplates.
    ReDim controls(0 To the_controls.Count - 1)
    ReDim tops(0 To the_controls.Count - 1)
    ReDim lefts(0 To the_controls.Count - 1)
        
    ‘ Copy the selected controls’ templates.
    For i = 0 To the_controls.Count - 1
        Set controls(i) = the_controls(i)
        tops(i) = controls(i).Properties.Item("Top")
        lefts(i) = controls(i).Properties.Item("Left")
    Next i
            
    ‘ Sort the controls by rows and columns.
    SortControls num_rows, num_cols, controls, tops, lefts
    
    ‘ Arrange them.
    ArrangeRowColControls num_rows, num_cols, spacing, controls, tops, lefts
    Exit Sub

AlignError:
    Beep
    MsgBox "Error aligning controls." & vbCrLf & _
        Err.Description, _
        vbOKOnly + vbInformation, _
        "Error Aligning Controls"
    Exit Sub
End Sub

Sub SortControls(num_rows As Integer, num_cols As Integer, controls() As VBIDE.ControlTemplate,
tops() As Single, lefts() As Single)
Dim tmp_ctl As VBIDE.ControlTemplate
Dim max_ctl As Integer
Dim i As Integer
Dim j As Integer
Dim r As Integer
Dim min_i As Integer
Dim max_i As Integer
Dim best_value As Single
Dim best_j As Single

    ‘ Sort by Top value.
    max_ctl = num_rows * num_cols - 1
    For i = 0 To max_ctl - 1
        best_value = tops(i)
        best_j = i
        For j = i + 1 To max_ctl
            If best_value > tops(j) Then
                best_value = tops(j)
                best_j = j
            End If
        Next j
        If best_j <> i Then
            Set tmp_ctl = controls(i)
            Set controls(i) = controls(best_j)
            Set controls(best_j) = tmp_ctl
            tops(best_j) = tops(i)
            tops(i) = best_value
            best_value = lefts(best_j)
            lefts(best_j) = lefts(i)
            lefts(i) = best_value
        End If
    Next i
    
    ‘ Sort the controls in each row by Left.
    For r = 1 To num_rows
        min_i = (r - 1) * num_cols
        max_i = min_i + num_cols - 2
        For i = min_i To max_i
            best_value = lefts(i)
            best_j = i
            For j = i + 1 To max_i + 1
                If best_value > lefts(j) Then
                    best_value = lefts(j)
                    best_j = j
                End If
            Next j
            If best_j <> i Then
                Set tmp_ctl = controls(i)
                Set controls(i) = controls(best_j)
                Set controls(best_j) = tmp_ctl
                lefts(best_j) = lefts(i)
                lefts(i) = best_value
                best_value = tops(best_j)
                tops(best_j) = tops(i)
                tops(i) = best_value
            End If
        Next i
    Next r
End Sub

Sub ArrangeRowColControls(num_rows As Integer, num_cols As Integer, spacing As Single, 
controls() As VBIDE.ControlTemplate, tops() As Single, lefts() As Single)
Dim max_row As Integer
Dim max_col As Integer
Dim max_ctl As Integer
Dim same_rows As Boolean
Dim same_cols As Boolean
Dim row_align As Integer
Dim col_align As Integer
Dim row_hgt() As Single
Dim col_wid() As Single
Dim i As Integer
Dim r As Integer
Dim c As Integer
Dim start_x As Single
Dim start_y As Single
Dim x As Single
Dim y As Single
Dim val As Single

    max_row = num_rows - 1
    max_col = num_cols - 1
    max_ctl = num_rows * num_cols - 1

    ReDim row_hgt(0 To max_row)
    ReDim col_wid(0 To max_col)

    ‘ Get the row and column alignment values.
    For i = 0 To 2
        If AlignerDialog.RCRowOption(i).value Then Exit For
    Next i
    row_align = i

    For i = 0 To 2
        If AlignerDialog.RCColOption(i).value Then Exit For
    Next i
    col_align = i

    ‘ Find the row and column sizes.
    same_rows = (AlignerDialog.SameRowCheck.value = vbChecked)
    If same_rows Then
        ‘ Make all rows the height of the
        ‘ tallest rectangle.
        y = controls(0).Properties.Item("Height")
        For i = 1 To max_ctl
            val = controls(i).Properties.Item("Height")
            If y < val Then y = val
        Next i
        For i = 0 To max_row
            row_hgt(i) = y
        Next i
    Else
        ‘ Find the height for each row.
        For r = 0 To max_row
            row_hgt(r) = controls(r * num_cols) _
                .Properties.Item("Height")
            For c = 1 To max_col
                val = controls(r * num_cols + c) _
                    .Properties.Item("Height")
                If row_hgt(r) < val Then _
                   row_hgt(r) = val
            Next c
        Next r
    End If
    
    same_cols = (AlignerDialog.SameColCheck.value = vbChecked)
    If same_cols Then
        ‘ Make all columns the width of the
        ‘ widest rectangle.
        x = controls(0).Properties.Item("Width")
        For i = 1 To max_ctl
            val = controls(i).Properties.Item("Width")
            If x < val Then x = val
        Next i
        For i = 0 To max_col
            col_wid(i) = x
        Next i
    Else
        ‘ Find the width for each column.
        For c = 0 To max_col
            col_wid(c) = controls(c).Properties.Item("Width")
            For r = 1 To max_row
                val = controls(c + num_cols * r) _
                    .Properties.Item("Width")
                If col_wid(c) < val Then _
                   col_wid(c) = val
            Next r
        Next c
    End If
    
    ‘ Find the upper left corner.
    start_x = lefts(0)
    start_y = tops(0)
    For i = 1 To max_ctl
        If start_x > lefts(i) Then start_x = lefts(i)
        If start_y > tops(i) Then start_y = tops(i)
    Next i
    
    ‘ Position the rectangles.
    y = start_y
    
    ‘ Lay out the rows.
    i = 0
    For r = 0 To max_row
        x = start_x
        For c = 0 To max_col
            Select Case col_align
                Case ALIGN_LEFT
                    controls(i).Properties.Item("Left") = _
                        x
                Case ALIGN_CENTER
                    controls(i).Properties.Item("Left") = _
                        x + (col_wid(c) - _
                        controls(i).Properties.Item("Width")) / 2
                Case ALIGN_RIGHT
                    controls(i).Properties.Item("Left") = _
                        x + col_wid(c) - _
                        controls(i).Properties.Item("Width")
            End Select
            Select Case row_align
                Case ALIGN_TOP
                    controls(i).Properties.Item("Top") = _
                        y
                Case ALIGN_MIDDLE
                    controls(i).Properties.Item("Top") = _
                        y + (row_hgt(r) - _
                        controls(i).Properties.Item("Height")) / 2
                Case ALIGN_BOTTOM
                    controls(i).Properties.Item("Top") = _
                        y + row_hgt(r) - _
                        controls(i).Properties.Item("Height")
            End Select
            
            x = x + col_wid(c) + spacing
            i = i + 1
        Next c
        y = y + row_hgt(r) + spacing
    Next r
End Sub

Summary

Aligner modifies the Left and Top properties of a group of selected controls to arrange them in rows and columns. Using similar techniques an add-in could arrange controls vertically, horizontally, in circles, tiled to fill the form without overlap, or in all sorts of other ways.

PropertySetter and Aligner modify the properties of controls created by the developer. Chapters 6 and 7 demonstrate more advanced add-in techniques to add completely new controls and new source code to a project.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.