![]() | |
|
|
|
To access the contents, click the chapter and section titles.
Advanced Visual Basic Techniques
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
SummaryAligner 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.
|
|
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.
|