OK
... although this may be totally against Windows design standards, applied judiciously
the effect may
address specific design requirements.
The
methodology here is simple. For each button in a control array the button's style bits
are changed via a call to SetWindowLong. The non-Windows constants I've defined
below represent the values required by SetWindowLong to cause the button
captions to become positioned at points other than centred. The call to
set a centred caption is also included, though since this is the button's
default position its inclusion below is more for completeness than for practicality. In
the demo I've exaggerated
the button's height to visually emphasize the offset created through changing these button
styles.
An
interesting routine in this method is the CreateControlGrid sub. This takes
parameters set through a UDT to create a X by Y layout, such as the 3x3 layout
shown above. By creating a single control array button (index 0) and setting the
UDT's totalRows and totalColumns members, CreateControlGrid loads and positions
the controls based on the parameters specified. And,
before I get a ton'o'emails, no, you can not use this method to cause a graphical-style command button to change
the alignment of the caption and image such that they appear side-by-side on the same
line. Attempting to apply the code below to a graphical-style button will remove
the picture. |
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
' applications, but you may not reproduce
' or publish this code on any web site,
' online service, or distribute as source
' on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Const GWL_STYLE As Long = (-16)
'these are not true Windows button styles
Private Const BS_ALIGN_CENTRELEFT As Long = &H100
Private Const BS_ALIGN_CENTRERIGHT As Long = &H200
Private Const BS_ALIGN_CENTRE As Long = &H300
Private Const BS_ALIGN_TOPMIDDLE As Long = &H400
Private Const BS_ALIGN_TOPLEFT As Long = &H500
Private Const BS_ALIGN_TOPRIGHT As Long = &H600
Private Const BS_ALIGN_BOTTOMMIDDLE As Long = &H800
Private Const BS_ALIGN_BOTTOMLEFT As Long = &H900
Private Const BS_ALIGN_BOTTOMRIGHT As Long = &HA00
Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Type ControlLayoutData
totalRows As Long
totalColumns As Long
rowPadding As Long
colPadding As Long
ctlHeight As Long
ctlWidth As Long
pgridTop As Long
pgridLeft As Long
End Type
Private Sub Form_Load()
Dim cnt As Long
Dim style As Long
Dim cld As ControlLayoutData
Dim a()
'temp array for button captions
a() = Array("not used", _
"Top Left", "Top Centre", "Top Right", _
"Centre Left", "Centre", "Centre Right", _
"Bottom Left", "Bottom Centre", "Bottom Right")
'the UDT containing control array
'layout data
With cld
.colPadding = 200
.ctlHeight = 600
.ctlWidth = 1575
.pgridLeft = 300
.pgridTop = 300
.totalColumns = 3
.totalRows = 3
End With
'since CreateControlGrid hides Command1(0),
'the button's style must be retrieved
'before it is hidden
style = GetWindowLong(Command1(0).hwnd, GWL_STYLE)
'create a grid of buttons as per
'the ControlLayoutData specs and
'assign the button captions from
'the array
CreateControlGrid cld, a()
'change the button style for each
'of the nine visible buttons
Call SetWindowLong(Command1(1).hwnd, GWL_STYLE, style Or BS_ALIGN_TOPLEFT)
Call SetWindowLong(Command1(2).hwnd, GWL_STYLE, style Or BS_ALIGN_TOPMIDDLE)
Call SetWindowLong(Command1(3).hwnd, GWL_STYLE, style Or BS_ALIGN_TOPRIGHT)
Call SetWindowLong(Command1(4).hwnd, GWL_STYLE, style Or BS_ALIGN_CENTRELEFT)
Call SetWindowLong(Command1(5).hwnd, GWL_STYLE, style Or BS_ALIGN_CENTRE)
Call SetWindowLong(Command1(6).hwnd, GWL_STYLE, style Or BS_ALIGN_CENTRERIGHT)
Call SetWindowLong(Command1(7).hwnd, GWL_STYLE, style Or BS_ALIGN_BOTTOMLEFT)
Call SetWindowLong(Command1(8).hwnd, GWL_STYLE, style Or BS_ALIGN_BOTTOMMIDDLE)
Call SetWindowLong(Command1(9).hwnd, GWL_STYLE, style Or BS_ALIGN_BOTTOMRIGHT)
End Sub
Private Sub CreateControlGrid(cld As ControlLayoutData, caps() As Variant)
Dim cnt As Long
Dim nCol As Long
Dim nRow As Long
Dim pixTop As Long
Dim pixLeft As Long
'Preload all the required controls.
'VB's default state for new controls
'is hidden. Set the initial contro's
'height and width, avoiding the need
'to set it in the loop below.
With Command1(0)
.Height = cld.ctlHeight
.Width = cld.ctlWidth
.Visible = False
End With
'load all controls
For cnt = 1 To (cld.totalRows * cld.totalColumns)
Load Command1(cnt)
Next
'position the controls to form
'a grid
cnt = 0
For nRow = 1 To cld.totalRows
For nCol = 1 To cld.totalColumns
cnt = cnt + 1
With Command1(cnt)
.Top = cld.pgridTop + ((cld.ctlHeight * nRow) - cld.ctlHeight) + _
(cld.rowPadding * (nRow - 1))
.Left = cld.pgridLeft + ((cld.ctlWidth * nCol) - cld.ctlWidth) + _
(cld.colPadding * (nCol - 1))
.Caption = caps(cnt)
.Visible = True
End With
Next nCol
Next
End Sub |