vbAccelerator - Contents of code file: vbalGrid.ctl
VERSION 5.00
Begin VB.UserControl vbalGrid
ClientHeight = 3600
ClientLeft = 0
ClientTop = 0
ClientWidth = 4800
ControlContainer= -1 'True
ScaleHeight = 3600
ScaleWidth = 4800
ToolboxBitmap = "vbalGrid.ctx":0000
Begin VB.PictureBox picImage
AutoRedraw = -1 'True
AutoSize = -1 'True
BorderStyle = 0 'None
Height = 1920
Left = 1980
ScaleHeight = 1920
ScaleWidth = 1920
TabIndex = 0
TabStop = 0 'False
Top = 900
Visible = 0 'False
Width = 1920
End
End
Attribute VB_Name = "vbalGrid"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Attribute VB_Description = "vbAccelerator Grid Control"
Option Explicit
'
===============================================================================
=======
' Name: vbAccelerator S-Grid Control
' Author: Steve McMahon (steve@vbaccelerator.com)
' Date: 22 December 1998
'
' Requires: SSUBTMR.DLL
' cScrollBars.cls
' cShellSort.cls
' mGDI.bas
' HeaderControl.ctl
'
' Copyright 1998-1999 Steve McMahon for vbAccelerator
'
-------------------------------------------------------------------------------
-------
' Visit vbAccelerator - advanced free source code for VB programmers
' http://vbaccelerator.com
'
-------------------------------------------------------------7-----------------
-------
'
' A serious VB grid control. Can be used to replace the ListView and
MSFlexGrid, and
' can emulate the Outlook message list view.
'
' Features:
'
' * Drag-drop columns
' * Visible or invisible columns
' * Row height can be set independently for each row
' * MS Common Controls or vbAccelerator ImageList support
' * Up to two icons per cell (e.g. a check box and a standard icon)
' * Indent text within any cell
' * Many cell text formatting options including multi-line text
' * Independently set BackColor,ForeColor and Font for each cell
' * Show/Hide rows to allow filtering options
' * Show/Hide columns
' * Scroll bars implemented using true API scroll bars, and support
flat/encarta style
' * Up to 2 billion rows and columns (although practically about 20,000 is the
limit)
' * Full row sorting by up to three columns at once, allows sorting by icon,
text,
' date/time or number.
' * Tile bitmaps into the grid's background
' * Autosize columns
'
' Updated 19/10/99
' * 1) Added hWnd() property (Igor Tur)
' * 2) Flat Headers (SPM)
' * 3) Header icons now works when no text set (Igor Tur)
' * 4) ClearSelection method
' * 5) EnsureVisible method
' * 6) Prevented scroll bar edges from being visible in a new grid (see
UserControl_Show)
' * 7) Clear RowTextColumn when columns are removed (Rhys Nicholls)
' * 8) HighlightForeColor and HighlightBackColor Properties (Michael
Karathanasis, Igor Tur)
' * 9) Make sure all header items are persisted (Ricardo Taborda dos Reis)
' * 10) Allow setting of HeaderHeight (Andreas Claesson)
' * 11) First column didn't resize correctly when dbl click header (Cuong
Nguyen)
' * 12) GPF when add column with rows present in grid (Marc Scherwinski)
' * 13) ColumnWidthChanged event (Brian Beatty)
' * 14) Ensure cells ungray themselves when enable is set back to true, don't
draw
' focus rect when disabled (Ricardo Taborda dos Reis)
' * 15)
'
'
' FREE SOURCE CODE - ENJOY!
'
===============================================================================
=======
Public Enum ECGScrollBarStyles
ecgSbrRegular = EFSStyleConstants.efsRegular
ecgSbrEncarta = EFSStyleConstants.efsEncarta
ecgSbrFlat = EFSStyleConstants.efsFlat
End Enum
Public Enum ECGHdrTextAlignFlags
ecgHdrTextALignLeft = EHdrTextAlign.HdrTextALignLeft
ecgHdrTextALignCentre = EHdrTextAlign.HdrTextALignCentre
ecgHdrTextALignRight = EHdrTextAlign.HdrTextALignRight
End Enum
Public Enum ECGTextAlignFlags
DT_TOP = &H0&
DT_LEFT = &H0&
DT_CENTER = &H1&
DT_RIGHT = &H2&
DT_VCENTER = &H4&
DT_BOTTOM = &H8&
DT_WORDBREAK = &H10&
DT_SINGLELINE = &H20&
DT_EXPANDTABS = &H40&
DT_TABSTOP = &H80&
DT_NOCLIP = &H100&
DT_EXTERNALLEADING = &H200&
DT_CALCRECT = &H400&
DT_NOPREFIX = &H800&
DT_INTERNAL = &H1000&
'#if(WINVER >= =&H0400)
DT_EDITCONTROL = &H2000&
DT_PATH_ELLIPSIS = &H4000&
DT_END_ELLIPSIS = &H8000&
DT_MODIFYSTRING = &H10000
DT_RTLREADING = &H20000
DT_WORD_ELLIPSIS = &H40000
End Enum
' The grid:
Private m_tCells() As tGridCell
Private m_tDefaultCell As tGridCell
' Row and columns and associated info:
Private m_iCols As Long
Private m_iRows As Long
Private m_tRows() As tRowPosition
Private Type tColPosition
lWidth As Long
lStartX As Long
lCellColIndex As Long
bVisible As Boolean
bFixed As Boolean
bRowTextCol As Long
sKey As String
sTag As String
bIncludeInSelect As Boolean
lHeadercolIndex As Long
sHeader As String
iIconIndex As Long
eTextAlign As ECGHdrTextAlignFlags
sFmtString As String
bImageOnRight As Boolean
eSortType As cShellSortTypeConstants
eSortOrder As cShellSortOrderCOnstants
End Type
Private m_tCols() As tColPosition
' Grouping of cells:
Private Type tGroupCells
iGroupNum As Long
iRow As Long
iCol As Long
End Type
Private m_tGroupCells() As tGroupCells
' Sorting:
Private m_cSort As New cShellSortTGridCells
' Selection optimisations for not multi-select:
Private m_iSelRow As Long
Private m_iSelCol As Long
Private m_iLastSelRow As Long
Private m_iLastSelCol As Long
' Defaults:
Private m_lDefaultRowHeight As Long
Private m_lDefaultColumnWidth As Long
' Display items:
Private m_Fnt() As StdFont
Private m_hFnt() As Long
Private m_iFontCount As Long
' Drawing area:
Private m_lAvailWidth As Long
Private m_lAvailheight As Long
Private m_lGridWidth As Long
Private m_lGridHeight As Long
Private m_lStartX As Long
Private m_lStartY As Long
' Memory DC for flicker-free (1 row only) - also implements clipping
Private m_hDC As Long
Private m_hBmp As Long
Private m_hBmpOld As Long
Private m_lHeight As Long
Private m_lMaxRowHeight As Long
Private m_hFntDC As Long
Private m_hFntOldDC As Long
' Background:
Private m_bBitmap As Boolean
Private m_hDCSrc As Long
Private m_lBitmapW As Long
Private m_lBitmapH As Long
' Icons:
Private m_hIml As Long
Private m_lIconSizeX As Long
Private m_lIconSizeY As Long
' Gridlines:
Private m_bGridLines As Boolean
Private m_oGridLineColor As OLE_COLOR
' Active Colour 19/10/1999 (8)
Private m_oHighlightForeColor As OLE_COLOR
Private m_oHighlightBackColor As OLE_COLOR
' Behaviour:
Private m_bMultiSelect As Boolean
Private m_bRowMode As Boolean
Private m_bInFocus As Boolean
Private m_hWnd As Long
Private m_bDirty As Boolean
Private m_bRedraw As Boolean
Private m_bUserMode As Boolean
Private m_bMouseDown As Boolean
Private m_bHeader As Boolean
Private m_bInEdit As Boolean
Private m_bEditable As Boolean
Private m_bEnabled As Boolean
Private m_bDisableIcons As Boolean
Private m_bHighlightSelectedIcons As Boolean
Private m_bDrawFocusRectangle As Boolean
Private m_bNoOptimiseScroll As Boolean
Private m_bTryToFitGroupRows As Boolean
' "Row Text" Column:
Private m_iRowTextCol As Long
Private m_lRowTextStartCol As Long
Private m_bHasRowText As Boolean
' Search Column:
Private m_iSearchCol As Long
Private m_sSearchString As String
' Scroll bars:
Private WithEvents m_cScroll As cScrollBars
Attribute m_cScroll.VB_VarHelpID = -1
Private m_eScrollStyle As EFSStyleConstants
Private m_bAllowVert As Boolean
Private m_bAllowHorz As Boolean
' Header:
Private WithEvents m_cHeader As cHeaderControl
Attribute m_cHeader.VB_VarHelpID = -1
Private m_cFlatHeader As cFlatHeader
Private m_bHeaderFlat As Boolean
' Virtual Grid:
Private m_bIsVirtual As Boolean
Private m_bInVirtualRequest As Boolean
Public Enum ECGBorderStyle
ecgBorderStyleNone = 0
ecgBorderStyle3d = 1
ecgBorderStyle3dThin = 2
End Enum
Private m_eBorderStyle As ECGBorderStyle
Public Enum ECGSerialiseTypes
ecgSerialiseSGRID = 0
ecgSerialiseSGRIDLayout = 1
ecgSerialiseTextTabNewLine = 2
ecgSerialiseCSV = 3
End Enum
Public Event ColumnClick(ByVal lCol As Long)
Attribute ColumnClick.VB_Description = "Raised when the user clicks a column."
Public Event ColumnWidthStartChange(ByVal lCol As Long, ByVal lWidth As Long,
ByRef bCancel As Boolean)
Attribute ColumnWidthStartChange.VB_Description = "Raised when the user is
about to start changing the width of a column."
Public Event ColumnWidthChanging(ByVal lCol As Long, ByVal lWidth As Long,
ByRef bCancel As Boolean)
Attribute ColumnWidthChanging.VB_Description = "Raised whilst a column's width
is being changed."
Public Event ColumnWidthChanged(ByVal lCol As Long, ByVal lWidth As Long, ByRef
bCancel As Boolean)
Public Event HeaderRightClick(ByVal x As Single, ByVal y As Single)
Attribute HeaderRightClick.VB_Description = "Raised when the user right clicks
on the grid's header."
Public Event SelectionChange(ByVal lRow As Long, ByVal lCol As Long)
Attribute SelectionChange.VB_Description = "Raised when the user changes the
selected cell."
Public Event RequestEdit(ByVal lRow As Long, ByVal lCol As Long, ByVal
iKeyAscii As Integer, ByRef bCancel As Boolean)
Attribute RequestEdit.VB_Description = "Raised when the grid has the Editable
property set to True and the user's actions request editing of the current
cell."
Public Event CancelEdit()
Public Event KeyDown(KeyCode As Integer, Shift As Integer, bDoDefault As
Boolean)
Attribute KeyDown.VB_Description = "Raised when a key is pressed in the
control."
Public Event KeyPress(KeyAscii As Integer)
Attribute KeyPress.VB_Description = "Raised after the KeyDown event when the
key press has been converted to an ASCII code."
Public Event KeyUp(KeyCode As Integer, Shift As Integer)
Attribute KeyUp.VB_Description = "Raised when a key is released on the grid."
Public Event MouseDown(Button As Integer, Shift As Integer, x As Single, y As
Single, bDoDefault As Boolean)
Attribute MouseDown.VB_Description = "Raised when the a mouse button is pressed
over the control."
Public Event MouseMove(Button As Integer, Shift As Integer, x As Single, y As
Single)
Attribute MouseMove.VB_Description = "Raised when the mouse moves over the
control, or when the mouse moves anywhere and a mouse button has been pressed
over the control."
Public Event MouseUp(Button As Integer, Shift As Integer, x As Single, y As
Single)
Attribute MouseUp.VB_Description = "Raised when a mouse button is released
after having been pressed over the control."
Public Event DblClick(ByVal lRow As Long, ByVal lCol As Long)
Attribute DblClick.VB_Description = "Raised when the user double clicks on the
grid."
Public Event RequestRow(ByVal lRow As Long, ByVal sKey As String, ByVal
bVisible As Boolean, ByVal lHeight As Long, ByVal bGroupRow As Boolean, ByRef
bNoMoreRows As Boolean)
Attribute RequestRow.VB_Description = "Raised when the grid is in Virtual mode
and the grid has been scrolled to expose a new row. Set bNoMoreRows to True
to indicate all rows have been added."
Public Event RequestRowData(ByVal lRow As Long)
Attribute RequestRowData.VB_Description = "Raised in virtual mode when a new
row has been added in response to RequestRow. Respond by filling in the cells
for that row."
Public Event ColumnOrderChanged()
Public Property Get HighlightSelectedIcons() As Boolean
Attribute HighlightSelectedIcons.VB_Description = "Gets/sets whether icons in
selected cells will be highlighted using the selection colour."
HighlightSelectedIcons = m_bHighlightSelectedIcons
End Property
Public Property Let HighlightSelectedIcons(ByVal bHighlight As Boolean)
m_bHighlightSelectedIcons = bHighlight
PropertyChanged "HighlightSelectedIcons"
End Property
Public Property Get DrawFocusRectangle() As Boolean
Attribute DrawFocusRectangle.VB_Description = "Gets/sets whether a focus
rectangle (dotted line around the selection) will be shown."
DrawFocusRectangle = m_bDrawFocusRectangle
End Property
Public Property Let DrawFocusRectangle(ByVal bDraw As Boolean)
m_bDrawFocusRectangle = bDraw
PropertyChanged "DrawFocusRectangle"
End Property
Public Property Get Enabled() As Boolean
Attribute Enabled.VB_Description = "Gets/sets whether the grid is enabled or
not. Note the grid can still be read when it is disabled, but cannot be
selected or edited."
Enabled = m_bEnabled
End Property
Public Property Let Enabled(ByVal bState As Boolean)
Dim iRow As Long, iCol As Long
m_bEnabled = bState
m_cHeader.Enabled = bState
If UserControl.Ambient.UserMode Then
m_bDirty = True
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = True
Next iCol
Next iRow
Draw
' 19/10/1999 (14):
UserControl_Paint
End If
PropertyChanged "Enabled"
End Property
Public Property Get DisableIcons() As Boolean
Attribute DisableIcons.VB_Description = "Gets/sets whether icons are drawn
disabled when the control is disabled."
DisableIcons = m_bDisableIcons
End Property
Public Property Let DisableIcons(ByVal bState As Boolean)
m_bDisableIcons = bState
If Not (m_bEnabled) Then
m_bDirty = True
Draw
End If
PropertyChanged "DisableIcons"
End Property
Public Property Get Editable() As Boolean
Attribute Editable.VB_Description = "Gets/sets whether the grid will be
editable (i.e. raise RequestEdit events)."
Editable = m_bEditable
End Property
Public Property Let Editable(ByVal bState As Boolean)
m_bEditable = bState
PropertyChanged "Editable"
End Property
Public Property Get SortObject() As cShellSortTGridCells
Attribute SortObject.VB_Description = "Returns a reference to the sort object
where grid sorting options can be specified."
Set SortObject = m_cSort
End Property
Public Sub Sort()
Attribute Sort.VB_Description = "Sorts the grid data according to the options
set up in the SortObject."
Dim sKey As String
Dim i As Long
Dim bS As Boolean
If m_iRows > 0 And m_iCols > 0 Then
If (m_iSelRow > 0) And (m_iSelRow <= m_iRows) Then
sKey = m_tRows(m_iSelRow).sKey
m_tRows(m_iSelRow).sKey = "!SELECTEDROW!"
End If
m_cSort.SortItems m_tCells(), m_tRows()
If (m_iSelRow > 0) Then
For i = 1 To m_iRows
If (m_tRows(i).sKey = "!SELECTEDROW!") Then
m_tRows(i).sKey = sKey
m_iSelRow = i
Exit For
End If
Next i
End If
m_tRows(1).lStartY = 0
RowVisible(1) = RowVisible(1)
bS = m_bNoOptimiseScroll
m_bNoOptimiseScroll = True
m_bDirty = True
If (m_iSelRow > 0) And (m_iSelCol > 0) And (m_iSelRow <= m_iRows) And
(m_iSelCol <= m_iCols) Then
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Else
m_iSelRow = 1: m_iSelCol = 1
Draw
End If
m_bNoOptimiseScroll = bS
Else
' That makes the sort somewhat quicker :)
End If
End Sub
Public Property Get EvaluateTextHeight( _
ByVal lRow As Long, _
ByVal lCol As Long _
) As Long
Attribute EvaluateTextHeight.VB_Description = "Determines the ideal height
required to display all the cell's text in a cell. This property is only of
any use if the Cell's CellTextAlign property allows multiple lines."
Dim hFntOld As Long
Dim tR As RECT
Dim sCopy As String
Dim iCol As Long, lCCol As Long
' Ensure correct font:
If (m_tCells(lCol, lRow).iFntIndex <> 0) Then
hFntOld = SelectObject(m_hDC, m_hFnt(m_tCells(lCol, lRow).iFntIndex))
End If
' Draw the text, calculating rect:
If Not IsMissing(m_tCells(lCol, lRow).sText) Then
sCopy = m_tCells(lCol, lRow).sText
For iCol = 1 To m_iCols
If (m_tCols(iCol).lCellColIndex = lCol) Then
lCCol = iCol
Exit For
End If
Next iCol
If (m_tCols(lCCol).sFmtString <> "") Then
sCopy = Format$(sCopy, m_tCols(lCCol).sFmtString)
End If
tR.Right = m_tCols(lCCol).lWidth - 4 - 2 * Abs(m_bGridLines)
tR.Right = tR.Right - m_tCells(lCol, lRow).lIndent
If (m_tCells(lCol, lRow).iIconIndex >= 0) Then
tR.Right = tR.Right - m_lIconSizeX - 2
End If
If (m_tCells(lCol, lRow).lExtraIconIndex >= 0) Then
tR.Right = tR.Right - m_lIconSizeX - 2
End If
DrawText m_hDC, sCopy & vbNullChar, -1, tR, m_tCells(lCol,
lRow).eTextFlags Or DT_CALCRECT
EvaluateTextHeight = tR.Bottom - tR.Top
Else
' don't need to do anything:
End If
If (hFntOld <> 0) Then
SelectObject m_hDC, hFntOld
hFntOld = 0
End If
End Property
Public Property Get EvaluateTextWidth( _
ByVal lRow As Long, _
ByVal lCol As Long, _
Optional ByVal bForceNoModify As Boolean = True _
) As Long
Attribute EvaluateTextWidth.VB_Description = "Determines the ideal width
required to fully display text in a cell."
EvaluateTextWidth = plEvaluateTextWidth(lRow, lCol, bForceNoModify, 0)
End Property
Private Property Get plEvaluateTextWidth( _
ByVal lRow As Long, _
ByVal lCol As Long, _
ByVal bForceNoModify As Boolean, _
ByVal lMaxWidth As Long _
) As Long
Dim hFntOld As Long
Dim tR As RECT
Dim sCopy As String
Dim sOrig As String
Dim iCol As Long
Dim lCCol As Long
Dim eFlags As ECGTextAlignFlags
Dim lLastRight As Long
' Ensure correct font:
If (m_tCells(lCol, lRow).iFntIndex <> 0) Then
hFntOld = SelectObject(m_hDC, m_hFnt(m_tCells(lCol, lRow).iFntIndex))
End If
' Find the index of lCol in the columns array:
For iCol = 1 To m_iCols
If (m_tCols(iCol).lCellColIndex = lCol) Then
lCCol = iCol
Exit For
End If
Next iCol
' Evaluate the text in the cell:
If Not (IsMissing(m_tCells(lCol, lRow).sText)) Then
sCopy = m_tCells(lCol, lRow).sText
End If
If (m_tCols(lCCol).sFmtString <> "") Then
sCopy = Format$(sCopy, m_tCols(lCCol).sFmtString)
End If
eFlags = m_tCells(lCol, lRow).eTextFlags Or DT_CALCRECT
' For multi line we specify the right so we get a height:
If (eFlags And DT_WORDBREAK) = DT_WORDBREAK Then
tR.Right = m_tCols(lCCol).lWidth
If (lMaxWidth > tR.Right) Then
tR.Right = lMaxWidth
End If
End If
If (bForceNoModify) Then
eFlags = eFlags And Not (DT_WORD_ELLIPSIS Or DT_PATH_ELLIPSIS Or
DT_MODIFYSTRING Or DT_END_ELLIPSIS)
End If
sOrig = sCopy
DrawText m_hDC, sCopy & vbNullChar, -1, tR, eFlags
If (eFlags And DT_WORDBREAK) = DT_WORDBREAK Then
Do While (tR.Bottom > m_tRows(lRow).lHeight)
sCopy = sOrig
' Extend in blocks of 16 until we fit...
tR.Right = tR.Right + 16
lLastRight = tR.Right
DrawText m_hDC, sCopy & vbNullChar, -1, tR, eFlags
tR.Right = lLastRight
Loop
End If
plEvaluateTextWidth = tR.Right - tR.Left
If (hFntOld <> 0) Then
SelectObject m_hDC, hFntOld
hFntOld = 0
End If
End Property
Public Property Get RowTextStartColumn() As Long
Attribute RowTextStartColumn.VB_Description = "Gets/sets the column that text
in the RowText column will start drawing at."
Attribute RowTextStartColumn.VB_MemberFlags = "400"
RowTextStartColumn = m_lRowTextStartCol
End Property
Public Property Let RowTextStartColumn(ByVal lColumn As Long)
m_lRowTextStartCol = lColumn
End Property
Public Property Let DefaultRowHeight(ByVal lHeight As Long)
Attribute DefaultRowHeight.VB_Description = "Gets/sets the height which will be
used as a default for rows in the grid."
m_lDefaultRowHeight = lHeight
PropertyChanged "DefaultRowHeight"
End Property
Public Property Get DefaultRowHeight() As Long
DefaultRowHeight = m_lDefaultRowHeight
End Property
Public Property Get Redraw() As Boolean
Attribute Redraw.VB_Description = "Gets/sets whether the grid is redrawn in
response to changes. Set to False whilst setting many properties to increase
speed. Setting to True after it has been False forces a re-draw of the
control."
Attribute Redraw.VB_ProcData.VB_Invoke_Property = ";Behavior"
Redraw = m_bRedraw
End Property
Public Property Let Redraw(ByVal bState As Boolean)
m_bRedraw = bState
If (UserControl.Ambient.UserMode) Then
m_bDirty = True
Draw
End If
PropertyChanged "Redraw"
End Property
Public Property Get SelectedRow() As Long
Attribute SelectedRow.VB_Description = "Gets the selected row. In multi-select
mode, this is the most recently selected row."
Attribute SelectedRow.VB_MemberFlags = "400"
SelectedRow = m_iSelRow
End Property
Public Property Let SelectedRow(ByVal lRow As Long)
Dim iCol As Long
Dim iRow As Long
If (m_iSelCol = 0) Then
'm_iSelCol = plGetFirstVisibleColumn()
End If
If (lRow > 0) And (lRow <= m_iRows) Then
m_iSelRow = lRow
If (m_bMultiSelect) Then
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (m_bRowMode) Then
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected <> (iRow = m_iSelRow))
m_tCells(iCol, iRow).bSelected = (iRow = m_iSelRow)
Else
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected) <> ((iCol = m_iSelCol) And (iRow =
m_iSelRow))
m_tCells(iCol, iRow).bSelected = ((iCol = m_iSelCol) And
(iRow = m_iSelRow))
End If
Next iCol
Next iRow
Else
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Else
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Property
Public Property Get SelectedCol() As Long
Attribute SelectedCol.VB_Description = "Gets the selected column. In
multi-select mode, this is the most recently selected column."
Attribute SelectedCol.VB_MemberFlags = "400"
SelectedCol = m_iSelCol
End Property
Public Property Let SelectedCol(ByVal lCol As Long)
If (lCol > 0) And (lCol <= m_iCols) Then
m_iSelCol = lCol
m_tCells(m_iSelCol, m_iSelRow).bSelected = True
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Else
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Property
Public Property Let ScrollBarStyle(ByVal eStyle As ECGScrollBarStyles)
Attribute ScrollBarStyle.VB_Description = "Gets/sets the style in which scroll
bars are drawn. Flat or Encarta style scroll bars are only supported in
systems with COMCTL32.DLL version 4.72 or higher."
m_eScrollStyle = eStyle
If Not (m_cScroll Is Nothing) Then
m_cScroll.Style = eStyle
End If
PropertyChanged "ScrollBarStyle"
End Property
Public Property Get ScrollBarStyle() As ECGScrollBarStyles
ScrollBarStyle = m_eScrollStyle
End Property
Public Property Get CellFormattedText(ByVal lRow As Long, ByVal lCol As Long)
As String
Attribute CellFormattedText.VB_Description = "Gets the text of a cell with any
formatting string applicable to the cell's column applied."
Dim iCCol As Long
Dim iCol As Long
For iCol = 1 To m_iCols
If (m_tCols(iCol).lCellColIndex = lCol) Then
iCCol = iCol
Exit For
End If
Next iCol
If (m_tCols(iCCol).sFmtString <> "") Then
CellFormattedText = Format$(m_tCells(lCol, lRow).sText,
m_tCols(iCCol).sFmtString)
Else
CellFormattedText = m_tCells(lCol, lRow).sText
End If
End Property
Public Property Get CellText(ByVal lRow As Long, ByVal lCol As Long) As Variant
Attribute CellText.VB_Description = "Gets/sets the text associated with a cell.
This property is a variant allowing you to store Numbers and Dates as well.
In columns which are not visible, it could also be used to store objects. "
If pbValid(lRow, lCol) Then
CellText = m_tCells(lCol, lRow).sText
End If
End Property
Public Property Let CellText(ByVal lRow As Long, ByVal lCol As Long, ByVal
sText As Variant)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).sText = sText
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Property
Public Property Get CellTextAlign(ByVal lRow As Long, ByVal lCol As Long) As
ECGTextAlignFlags
Attribute CellTextAlign.VB_Description = "Gets/sets the alignment and
formatting properties used to draw cell text."
If pbValid(lRow, lCol) Then
CellTextAlign = m_tCells(lCol, lRow).eTextFlags
End If
End Property
Public Property Let CellTextAlign(ByVal lRow As Long, ByVal lCol As Long, ByVal
eAlign As ECGTextAlignFlags)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).eTextFlags = eAlign Or DT_NOPREFIX And Not
DT_CALCRECT
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Property
Public Property Get CellIndent(ByVal lRow As Long, ByVal lCol As Long) As Long
Attribute CellIndent.VB_Description = "Gets/sets the horizontal indentation of
a cell from the cell's border."
If pbValid(lRow, lCol) Then
CellIndent = m_tCells(lCol, lRow).lIndent
End If
End Property
Public Property Let CellIndent(ByVal lRow As Long, ByVal lCol As Long, ByVal
lIndent As Long)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).lIndent = lIndent
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Property
Public Property Get CellExtraIcon(ByVal lRow As Long, ByVal lCol As Long) As
Long
Attribute CellExtraIcon.VB_Description = "Gets/sets the extra icon for a cell.
This icon will always appear in the leftmost position for the cell. Set
CellExtraIcon to -1 to remove an icon. CellExtraIcons represent ImageList
icon indexes and run from 0 to Count-1."
If pbValid(lRow, lCol) Then
CellExtraIcon = m_tCells(lCol, lRow).lExtraIconIndex
End If
End Property
Public Property Let CellExtraIcon(ByVal lRow As Long, ByVal lCol As Long, ByVal
lIconIndex As Long)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).lExtraIconIndex = lIconIndex
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Property
Public Property Get CellItemData(ByVal lRow As Long, ByVal lCol As Long) As Long
Attribute CellItemData.VB_Description = "Gets/sets a long value associated with
the cell."
If pbValid(lRow, lCol) Then
CellItemData = m_tCells(lCol, lRow).lItemData
End If
End Property
Public Property Let CellItemData(ByVal lRow As Long, ByVal lCol As Long, ByVal
lItemData As Long)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).lItemData = lItemData
End If
End Property
Public Property Get CellSelected(ByVal lRow As Long, ByVal lCol As Long) As
Boolean
Attribute CellSelected.VB_Description = "Gets/sets whether a cell is selected
or not."
If pbValid(lRow, lCol) Then
CellSelected = m_tCells(lCol, lRow).bSelected
End If
End Property
Public Property Let CellSelected(ByVal lRow As Long, ByVal lCol As Long, ByVal
bState As Boolean)
Dim iInitSelCOl As Long
Dim iInitSelRow As Long
Dim iCol As Long
If pbValid(lRow, lCol) Then
' for single select mode, bstate is ignored.
If (m_bMultiSelect) Then
iInitSelCOl = m_iSelCol
iInitSelRow = m_iSelRow
m_iSelRow = lRow
m_iSelCol = lCol
If (m_bRowMode) Then
For iCol = 1 To m_iCols
m_tCells(iCol, m_iSelRow).bDirtyFlag = (m_tCells(iCol,
m_iSelRow).bSelected <> bState)
m_tCells(iCol, m_iSelRow).bSelected = bState
Next iCol
Else
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = (m_tCells(m_iSelCol,
m_iSelRow).bSelected <> bState)
m_tCells(m_iSelCol, m_iSelRow).bSelected = bState
End If
Else
iInitSelCOl = m_iSelCol
iInitSelRow = m_iSelRow
m_iSelRow = lRow
m_iSelCol = lCol
pSingleModeSelect
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
If (iInitSelCOl <> m_iSelCol) Or (iInitSelRow <> m_iSelRow) Then
RaiseEvent SelectionChange(m_iSelRow, m_iSelCol)
End If
End If
End If
End Property
Public Property Get CellIcon(ByVal lRow As Long, ByVal lCol As Long) As Long
Attribute CellIcon.VB_Description = "Gets/sets the icon for a cell. If the
cell has an icon set via the CellExtraIcon property, this icon will appear
after it. Set CellIcon to -1 to remove an icon. CellIcons represent
ImageList icon indexes and run from 0 to Count-1."
If pbValid(lRow, lCol) Then
CellIcon = m_tCells(lCol, lRow).iIconIndex
End If
End Property
Public Property Let CellIcon(ByVal lRow As Long, ByVal lCol As Long, ByVal
lIconIndex As Long)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).iIconIndex = lIconIndex
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Property
Public Property Get CellBackColor(ByVal lRow As Long, ByVal lCol As Long) As
OLE_COLOR
Attribute CellBackColor.VB_Description = "Gets/sets the background colour for a
cell. Set to -1 to make the cell transparent."
If pbValid(lRow, lCol) Then
CellBackColor = m_tCells(lCol, lRow).oBackColor
End If
End Property
Public Property Let CellBackColor(ByVal lRow As Long, ByVal lCol As Long, ByVal
oColor As OLE_COLOR)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).oBackColor = oColor
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Property
Public Property Get CellForeColor(ByVal lRow As Long, ByVal lCol As Long) As
OLE_COLOR
Attribute CellForeColor.VB_Description = "Gets/sets the foreground colour to
draw a cell in. Set to -1 to use the default foreground colour."
If pbValid(lRow, lCol) Then
CellForeColor = m_tCells(lCol, lRow).oForeColor
End If
End Property
Public Property Let CellForeColor(ByVal lRow As Long, ByVal lCol As Long, ByVal
oColor As OLE_COLOR)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).oForeColor = oColor
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Property
Public Sub CellDefaultForeColor(ByVal lRow As Long, ByVal lCol As Long)
Attribute CellDefaultForeColor.VB_Description = "Sets a cell to use the default
foreground colour (the fore colour of the control)."
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).oForeColor = CLR_NONE
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Sub
Public Sub CellDefaultBackColor(ByVal lRow As Long, ByVal lCol As Long)
Attribute CellDefaultBackColor.VB_Description = "Sets a cell to use the default
background colour (transparent)."
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).oBackColor = CLR_NONE
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Sub
Public Property Get CellFont(ByVal lRow As Long, ByVal lCol As Long) As StdFont
Attribute CellFont.VB_Description = "Gets/sets the font to use to draw a cell."
If pbValid(lRow, lCol) Then
If (m_tCells(lCol, lRow).iFntIndex = 0) Then
Set CellFont = UserControl.Font
Else
Set CellFont = m_Fnt(m_tCells(lCol, lRow).iFntIndex)
End If
End If
End Property
Public Property Let CellFont(ByVal lRow As Long, ByVal lCol As Long, ByVal sFnt
As StdFont)
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).iFntIndex = plAddFontIfRequired(sFnt)
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Property
Public Sub CellDefaultFont(ByVal lRow As Long, ByVal lCol As Long)
Attribute CellDefaultFont.VB_Description = "Sets a cell to use the default
font."
If pbValid(lRow, lCol) Then
m_tCells(lCol, lRow).iFntIndex = 0
m_tCells(lCol, lRow).bDirtyFlag = True
Draw
End If
End Sub
Public Property Get MultiSelect() As Boolean
Attribute MultiSelect.VB_Description = "Gets/sets whether multiple grid cells
or rows can be selected or not."
Attribute MultiSelect.VB_ProcData.VB_Invoke_Property = ";Behavior"
MultiSelect = m_bMultiSelect
End Property
Public Property Let MultiSelect(ByVal bState As Boolean)
Dim iCol As Long
Dim iRow As Long
If (bState <> m_bMultiSelect) Then
If Not (bState) Then
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (m_bRowMode) Then
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected <> (iRow = m_iSelRow))
m_tCells(iCol, iRow).bSelected = (iRow = m_iSelRow)
Else
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected <> ((iRow = m_iSelRow) And (iCol =
m_iSelCol)))
m_tCells(iCol, iRow).bSelected = ((iRow = m_iSelRow) And
(iCol = m_iSelCol))
End If
Next iCol
Next iRow
End If
End If
m_bMultiSelect = bState
Draw
PropertyChanged "MultiSelect"
End Property
Public Property Get RowMode() As Boolean
Attribute RowMode.VB_Description = "Gets/sets whether cells can be selected in
the grid (False) or rows (True)."
Attribute RowMode.VB_ProcData.VB_Invoke_Property = ";Behavior"
RowMode = m_bRowMode
End Property
Public Property Let RowMode(ByVal bState As Boolean)
Dim iCol As Long
Dim iRow As Long
Dim bSelRow As Boolean
m_bRowMode = bState
If Not (m_bMultiSelect) Then
If (m_iSelRow > 0) And (m_iSelCol > 0) Then
For iCol = 1 To m_iCols
m_tCells(iCol, m_iSelRow).bDirtyFlag = True
If (bState) Then
m_tCells(iCol, m_iSelRow).bSelected = True
Else
m_tCells(iCol, m_iSelRow).bSelected = (iCol = m_iSelCol)
End If
Next iCol
End If
Else
If (bState) Then
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (m_tCells(iCol, iRow).bSelected) Then
bSelRow = True
Exit For
End If
Next iCol
If (bSelRow) Then
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bSelected = True
m_tCells(iCol, iRow).bDirtyFlag = True
Next iCol
End If
Next iRow
End If
End If
m_bDirty = True
Draw
PropertyChanged "RowMode"
End Property
Public Property Get RowIsGroup(ByVal lRow As Long) As Boolean
Attribute RowIsGroup.VB_Description = "Gets/sets whether a row should be
regarded as a group row."
If (lRow > 0) And (lRow <= m_iRows) Then
RowIsGroup = m_tRows(lRow).bGroupRow
Else
Err.Raise 9, App.EXEName, "Invalid Row Subscript"
End If
End Property
Public Property Let RowIsGroup(ByVal lRow As Long, ByVal bState As Boolean)
Dim iCol As Long
If (lRow > 0) And (lRow <= m_iRows) Then
If m_tRows(lRow).bGroupRow <> bState Then
m_tRows(lRow).bGroupRow = bState
For iCol = 1 To m_iCols
m_tCells(iCol, lRow).bDirtyFlag = True
Next iCol
Draw
End If
Else
Err.Raise 9, App.EXEName, "Invalid Row Subscript"
End If
End Property
Public Property Get RowGroupStartColumn(ByVal lRow As Long) As Long
If (lRow > 0) And (lRow <= m_iRows) Then
RowGroupStartColumn = m_tRows(lRow).lGroupStartColIndex
Else
Err.Raise 9, App.EXEName, "Invalid Row Subscript"
End If
End Property
Public Property Let RowGroupStartColumn(ByVal lRow As Long, ByVal lColumn As
Long)
Dim iCol As Long
If (lRow > 0) And (lRow <= m_iRows) Then
If m_tRows(lRow).lGroupStartColIndex <> lColumn Then
m_tRows(lRow).lGroupStartColIndex = lColumn
For iCol = 1 To m_iCols
m_tCells(iCol, lRow).bDirtyFlag = True
Next iCol
Draw
End If
Else
Err.Raise 9, App.EXEName, "Invalid Row Subscript"
End If
End Property
Public Property Get GridLines() As Boolean
Attribute GridLines.VB_Description = "Gets/sets whether grid-lines are drawn or
not."
Attribute GridLines.VB_ProcData.VB_Invoke_Property = ";Appearance"
GridLines = m_bGridLines
End Property
Public Property Let GridLines(ByVal bState As Boolean)
m_bGridLines = bState
m_bDirty = True
Draw
PropertyChanged "GridLines"
End Property
Public Property Let ImageList(vThis As Variant)
Attribute ImageList.VB_Description = "Sets an ImageList as the source of icons
for the control. The ImageList can be either a VB ImageList, a vbAccelerator
ImageList or an API hIml handle. If it is a VB Image List, the Image List
must have had at least one icon in it before using this prop"
Attribute ImageList.VB_ProcData.VB_Invoke_PropertyPut = ";Behavior"
Dim hIml As Long
' Set the ImageList handle property either from a VB
' image list or directly:
If VarType(vThis) = vbObject Then
' Assume VB ImageList control. Note that unless
' some call has been made to an object within a
' VB ImageList the image list itself is not
' created. Therefore hImageList returns error. So
' ensure that the ImageList has been initialised by
' drawing into nowhere:
On Error Resume Next
' Get the image list initialised..
vThis.ListImages(1).Draw 0, 0, 0, 1
hIml = vThis.hImageList
If (Err.Number <> 0) Then
hIml = 0
End If
On Error GoTo 0
ElseIf VarType(vThis) = vbLong Then
' Assume ImageList handle:
hIml = vThis
Else
Err.Raise vbObjectError + 1049, "cToolbar." & App.EXEName, "ImageList
property expects ImageList object or long hImageList handle."
End If
' If we have a valid image list, then associate it with the control:
If (hIml <> 0) Then
m_hIml = hIml
m_cHeader.SetImageList UserControl.hdc, hIml
ImageList_GetIconSize m_hIml, m_lIconSizeX, m_lIconSizeY
End If
End Property
Public Property Set BackgroundPicture(sPic As StdPicture)
Attribute BackgroundPicture.VB_Description = "Gets/sets a picture to be used as
the grid's background."
Attribute BackgroundPicture.VB_ProcData.VB_Invoke_PropertyPutRef = ";Appearance"
On Error Resume Next
Set picImage.Picture = sPic
picImage.Refresh
If (Err.Number <> 0) Or (picImage.ScaleWidth = 0) Or (sPic Is Nothing) Then
m_hDCSrc = 0
m_bBitmap = False
Else
m_bBitmap = True
m_hDCSrc = picImage.hdc
m_lBitmapW = picImage.ScaleWidth \ Screen.TwipsPerPixelX
m_lBitmapH = picImage.ScaleHeight \ Screen.TwipsPerPixelY
End If
m_bDirty = True
Draw
PropertyChanged "BackgroundPicture"
End Property
Public Property Get BackgroundPictureHeight() As Long
Attribute BackgroundPictureHeight.VB_Description = "Gets/sets the height of the
background picture."
Attribute BackgroundPictureHeight.VB_ProcData.VB_Invoke_Property = ";Appearance"
Attribute BackgroundPictureHeight.VB_MemberFlags = "400"
BackgroundPictureHeight = m_lBitmapH
End Property
Public Property Let BackgroundPictureHeight(ByVal lHeight As Long)
m_lBitmapH = lHeight
PropertyChanged "BackgroundPictureHeight"
End Property
Public Property Get BackgroundPictureWidth() As Long
Attribute BackgroundPictureWidth.VB_Description = "Gets/sets the width of the
background picture."
Attribute BackgroundPictureWidth.VB_ProcData.VB_Invoke_Property = ";Appearance"
Attribute BackgroundPictureWidth.VB_MemberFlags = "400"
BackgroundPictureWidth = m_lBitmapW
End Property
Public Property Let BackgroundPictureWidth(ByVal lWidth As Long)
m_lBitmapW = lWidth
PropertyChanged "BackgroundPictureWidth"
End Property
Public Property Get BackgroundPicture() As StdPicture
Set BackgroundPicture = picImage.Picture
End Property
Public Property Get BackColor() As OLE_COLOR
Attribute BackColor.VB_Description = "Gets/sets the background color of the
grid."
Attribute BackColor.VB_ProcData.VB_Invoke_Property = ";Appearance"
Attribute BackColor.VB_UserMemId = -501
BackColor = UserControl.BackColor
End Property
Public Property Let BackColor(ByVal oColor As OLE_COLOR)
UserControl.BackColor = oColor
If (m_hDC <> 0) Then
SetBkColor m_hDC, TranslateColor(UserControl.BackColor)
End If
PropertyChanged "BackColor"
End Property
Public Property Get HighlightBackColor() As OLE_COLOR
' 19/10/1999 (8)
HighlightBackColor = m_oHighlightBackColor
End Property
Public Property Let HighlightBackColor(oColor As OLE_COLOR)
' 19/10/1999 (8)
m_oHighlightBackColor = oColor
PropertyChanged "HighlightBackColor"
End Property
Public Property Get HighlightForeColor() As OLE_COLOR
' 19/10/1999 (8)
HighlightForeColor = m_oHighlightForeColor
End Property
Public Property Let HighlightForeColor(oColor As OLE_COLOR)
' 19/10/1999 (8)
m_oHighlightForeColor = oColor
PropertyChanged "HighlightForeColor"
End Property
Public Property Get ForeColor() As OLE_COLOR
Attribute ForeColor.VB_Description = "Gets/sets the foreground color used to
draw the control."
Attribute ForeColor.VB_ProcData.VB_Invoke_Property = ";Appearance"
Attribute ForeColor.VB_UserMemId = -513
ForeColor = UserControl.ForeColor
End Property
Public Property Let ForeColor(ByVal oColor As OLE_COLOR)
UserControl.ForeColor = oColor
If (m_hDC <> 0) Then
SetTextColor m_hDC, TranslateColor(oColor)
End If
PropertyChanged "ForeColor"
End Property
Public Property Get GridLineColor() As OLE_COLOR
Attribute GridLineColor.VB_Description = "Gets/sets the colour used to draw
grid lines."
Attribute GridLineColor.VB_ProcData.VB_Invoke_Property = ";Appearance"
GridLineColor = m_oGridLineColor
End Property
Public Property Let GridLineColor(ByVal oColor As OLE_COLOR)
m_oGridLineColor = oColor
m_bDirty = True
Draw
PropertyChanged "GridLineColor"
End Property
Public Property Get Font() As StdFont
Attribute Font.VB_Description = "Gets/sets the font used by the control."
Attribute Font.VB_ProcData.VB_Invoke_Property = ";Appearance"
Attribute Font.VB_UserMemId = -512
Dim tLF As LOGFONT
Set Font = UserControl.Font
End Property
Public Property Set Font(ByVal sFont As StdFont)
Dim tLF As LOGFONT
Set UserControl.Font = sFont
m_cHeader.SetFont UserControl.hdc, sFont
If (m_hFntDC <> 0) Then
If (m_hDC <> 0) Then
If (m_hFntOldDC <> 0) Then
SelectObject m_hDC, m_hFntOldDC
End If
DeleteObject m_hFntDC
End If
End If
pOLEFontToLogFont sFont, UserControl.hdc, tLF
m_hFntDC = CreateFontIndirect(tLF)
If (m_hDC <> 0) Then
m_hFntOldDC = SelectObject(m_hDC, m_hFntDC)
End If
PropertyChanged "Font"
End Property
Public Property Get Virtual() As Boolean
Attribute Virtual.VB_Description = "Gets/sets whether the grid is in Virtual
Mode (i.e. rows are added as required via the RequestRow and RequestRowData
events)."
Virtual = m_bIsVirtual
End Property
Public Property Let Virtual(ByVal bVirtual As Boolean)
m_bIsVirtual = bVirtual
If Not m_bIsVirtual Then
m_bInVirtualRequest = False
Else
m_bInVirtualRequest = True
End If
PropertyChanged "Virtual"
End Property
Public Sub Draw()
Attribute Draw.VB_Description = "Draws the control."
Dim iStartRow As Long, iStartCol As Long
Dim iStartX As Long, iStartY As Long
Dim lRowStartX As Long, lThisRowStartX As Long, lRowEndX As Long
Dim iEndRow As Long, iEndCol As Long
Dim lStartX As Long
Dim iEndX As Long, iEndY As Long, iY As Long
Dim iRow As Long, iCol As Long
Dim iCellCol As Long, iCRowTextCol As Long, iFirstColInSelect As Long
Dim tR As RECT, tTR As RECT, tBR As RECT, tFR As RECT
Dim sText As String, sCopy As String
Dim lHDC As Long, lHDCC As Long
Dim hBr As Long, hBrGrid As Long
Dim hFntOld As Long
Dim lLastPos As Long, lOffset As Long
Dim bSel As Boolean, bDoIt As Boolean, bDrawBack As Boolean, bCellSelected As
Boolean
Dim lStartColIndex As Long
Dim sKey As String, bVisible As Boolean, bGroupRow As Boolean, bNoMoreRows As
Boolean, lHeight As Long
Dim bRecall As Boolean
Dim bDefaultStartCol As Boolean
If m_bRedraw And m_bUserMode Then
If (m_cHeader.Visible) Then
lOffset = m_cHeader.Height
End If
GetClientRect UserControl.hwnd, tR
If (m_hDC <> 0) Then
lHDC = m_hDC
lHDCC = UserControl.hdc
tBR.Right = m_lAvailWidth + 24 + Abs(m_tCols(iStartCol).lStartX -
m_lStartX)
tBR.Bottom = m_lMaxRowHeight
Else
lHDC = UserControl.hdc
pFillBackground lHDC, tR, 0, 0
End If
' Ensure the scroll bars are set correctly:
pScrollVisible
' Find the start and end of drawing:
GetStartEndCell _
iStartRow, iStartCol, iStartX, iStartY, _
iEndRow, iEndCol, iEndX, iEndY
' If in virtual mode then we prepare for more rows:
If (m_bIsVirtual And m_bInVirtualRequest) Then
If (iEndY < m_lAvailheight) Then
iY = iEndY
Do
iEndRow = iEndRow + 1
iY = iY + m_lDefaultRowHeight
Loop While iY < m_lAvailheight
End If
End If
' Evaluate the default group column start & end:
lStartColIndex = m_lRowTextStartCol
bDefaultStartCol = (lStartColIndex = 0)
For iCol = 1 To m_iCols
If iFirstColInSelect = 0 Then
If (m_tCols(iCol).bIncludeInSelect) Then
iFirstColInSelect = iCol
iCRowTextCol = iCol
lRowStartX = m_tCols(iCol).lStartX - m_lStartX
If (m_lRowTextStartCol = 0) Then
lStartColIndex = iCol
End If
End If
End If
If (m_tCols(iCol).lCellColIndex = lStartColIndex) And Not
(bDefaultStartCol) Then
lRowStartX = m_tCols(iCol).lStartX - m_lStartX
ElseIf (m_tCols(iCol).lCellColIndex = m_iRowTextCol) Then
iCRowTextCol = iCol
ElseIf m_tCols(iCol).bVisible Then
If (m_tCols(iCol).lStartX + m_tCols(iCol).lWidth - m_lStartX) >
lRowEndX Then
lRowEndX = m_tCols(iCol).lStartX + m_tCols(iCol).lWidth -
m_lStartX
End If
End If
Next iCol
'Set up for grid lines:
If (m_bGridLines) Then
If (m_bEnabled) Then
hBrGrid = CreateSolidBrush(TranslateColor(m_oGridLineColor))
'GetSysColorBrush(vb3DLight And &H1F&)
Else
hBrGrid = GetSysColorBrush(vbGrayText And &H1F&)
End If
End If
' Text colour for disabled grid:
If Not (m_bEnabled) Then
SetTextColor m_hDC, TranslateColor(vbGrayText)
End If
' Draw the dirty cells:
For iRow = iStartRow To iEndRow
' Request new row if in virtual mode:
If (iRow > m_iRows) Then
If m_iCols > 0 Then
If (m_bIsVirtual) Then
lHeight = m_lDefaultRowHeight
bVisible = True
bGroupRow = False
RaiseEvent RequestRow(iRow, sKey, bVisible, lHeight,
bGroupRow, bNoMoreRows)
If bNoMoreRows Then
' that's it
m_bInVirtualRequest = False
pScrollVisible
bRecall = True
Exit For
Else
AddRow , sKey, bVisible, lHeight, bGroupRow
pScrollVisible
RaiseEvent RequestRowData(iRow)
End If
Else
' This does not occur:
Debug.Assert iRow <= m_iRows
Exit For
End If
Else
' Can't do it until cols are set up
Exit Sub
End If
End If
If (m_tRows(iRow).bVisible) Then
If (m_hDC <> 0) Then
tR.Top = 0
Else
tR.Top = m_tRows(iRow).lStartY - m_lStartY
End If
tR.Bottom = tR.Top + m_tRows(iRow).lHeight
If (m_hDC <> 0) Then
pFillBackground lHDC, tBR, 0, m_tRows(iRow).lStartY - m_lStartY
End If
bDoIt = m_bDirty
If Not (bDoIt) Then
' Any dirty cells on this row?
If m_tRows(iRow).bGroupRow Then
If m_tCells(m_iRowTextCol, iRow).bDirtyFlag Then
bDoIt = True
m_tCells(m_iRowTextCol, iRow).bDirtyFlag = False
End If
Else
For iCol = iStartCol To iEndCol
iCellCol = m_tCols(iCol).lCellColIndex
If m_tCells(iCellCol, iRow).bDirtyFlag Then
bDoIt = True
m_tCells(iCellCol, iRow).bDirtyFlag = False
End If
Next iCol
End If
End If
If (bDoIt) Then
' Draw individual columns unless this row has the group row
style, in
' which case we draw only the RowTextColumn.
If Not (m_tRows(iRow).bGroupRow) Then
For iCol = iStartCol To iEndCol
If (m_tCols(iCol).bVisible) And (iCol <> m_iRowTextCol)
Then
bCellSelected = False
iCellCol = m_tCols(iCol).lCellColIndex
tR.Left = m_tCols(iCol).lStartX - m_lStartX +
m_tCells(iCellCol, iRow).lIndent
tR.Right = tR.Left + m_tCols(iCol).lWidth -
m_tCells(iCellCol, iRow).lIndent
bDrawBack = False
If (m_tCells(iCellCol, iRow).bSelected) And
(m_bEnabled) Then
If (m_tCols(iCol).bIncludeInSelect) Or (iCol >
iFirstColInSelect) Then
If (m_bInFocus) Then
'hBr = GetSysColorBrush(vbHighlight And &H1F&)
hBr =
CreateSolidBrush(TranslateColor(m_oHighlightBa
ckColor))
bCellSelected = True
Else
hBr = GetSysColorBrush(vbButtonFace And &H1F&)
End If
LSet tTR = tR
If (m_bGridLines) Then
InflateRect tTR, -1, -1
End If
If (m_bRowMode) Then
If (iCol > iFirstColInSelect) Then
tTR.Left = tTR.Left - m_tCells(iCellCol,
iRow).lIndent
End If
End If
LSet tFR = tTR
If Not (m_bRowMode) Or m_bGridLines And
(m_bEnabled) Then
If (iCellCol = m_iSelCol) And (iRow =
m_iSelRow) Then
If m_bDrawFocusRectangle Then
LSet tFR = tTR
InflateRect tFR, -1, -1
End If
End If
ElseIf m_bRowMode And Not (m_bGridLines) Then
tFR.Top = tFR.Top + 1
End If
FillRect lHDC, tFR, hBr
DeleteObject hBr
Else
bDrawBack = True
End If
bSel = True
Else
bDrawBack = m_bEnabled
End If
If (bDrawBack) Then
If (m_tCells(iCellCol, iRow).oBackColor <> CLR_NONE)
Then
hBr =
CreateSolidBrush(TranslateColor(m_tCells(iCellCol
, iRow).oBackColor))
LSet tTR = tR
If (m_tCells(iCellCol, iRow).lIndent <> 0) Then
tTR.Left = tTR.Left - m_tCells(iCellCol,
iRow).lIndent
End If
FillRect lHDC, tTR, hBr
DeleteObject hBr
End If
If (m_tCells(iCellCol, iRow).oForeColor <> CLR_NONE)
Then
SetTextColor lHDC,
TranslateColor(m_tCells(iCellCol,
iRow).oForeColor)
bSel = True
Else
If (bSel) Then
SetTextColor lHDC,
TranslateColor(UserControl.ForeColor)
bSel = False
End If
End If
End If
If (m_bGridLines) Then
LSet tTR = tR
tTR.Left = tTR.Left - m_tCells(iCellCol,
iRow).lIndent
tTR.Right = tR.Right + 1
If (iRow <> iEndRow) Then
tTR.Bottom = tR.Bottom + 1
End If
FrameRect lHDC, tTR, hBrGrid
LSet tTR = tR
InflateRect tTR, -2, -2
Else
LSet tTR = tR
InflateRect tTR, -1, -1
End If
If Not (m_bRowMode) Or m_bGridLines And (m_bEnabled)
Then
If (iCellCol = m_iSelCol) And (iRow = m_iSelRow) Then
' 19/10/1999 (14):
If m_bDrawFocusRectangle And m_bInFocus And
m_bEnabled Then
LSet tFR = tTR
InflateRect tFR, 1, 1
DrawFocusRect lHDC, tFR
m_tCells(iCellCol, iRow).bDirtyFlag = True
End If
End If
End If
If (m_tCells(iCellCol, iRow).lExtraIconIndex > -1) Then
DrawImage m_hIml, m_tCells(iCellCol,
iRow).lExtraIconIndex, lHDC, tTR.Left, tTR.Top,
m_lIconSizeX, m_lIconSizeY, m_tCells(iCellCol,
iRow).bSelected And m_bHighlightSelectedIcons, ,
Not (m_bEnabled) And m_bDisableIcons
tTR.Left = tTR.Left + m_lIconSizeX + 2
End If
If (m_tCells(iCellCol, iRow).iIconIndex > -1) Then
DrawImage m_hIml, m_tCells(iCellCol,
iRow).iIconIndex, lHDC, tTR.Left, tTR.Top,
m_lIconSizeX, m_lIconSizeY, m_tCells(iCellCol,
iRow).bSelected And m_bHighlightSelectedIcons, ,
Not (m_bEnabled) And m_bDisableIcons
tTR.Left = tTR.Left + m_lIconSizeX + 2
End If
If Not (IsMissing(m_tCells(iCellCol, iRow).sText)) Then
If (Len(m_tCells(iCellCol, iRow).sText) > 0) Then
If (m_tCells(iCellCol, iRow).iFntIndex <> 0) Then
hFntOld = SelectObject(m_hDC,
m_hFnt(m_tCells(iCellCol, iRow).iFntIndex))
End If
sCopy = m_tCells(iCellCol, iRow).sText
If (Len(m_tCols(iCol).sFmtString) > 0) Then
sCopy = Format$(sCopy,
m_tCols(iCol).sFmtString)
End If
If bCellSelected Then
' 19/10/1999 (8):
'SetTextColor lHDC,
TranslateColor(vbHighlightText)
SetTextColor lHDC,
TranslateColor(m_oHighlightForeColor)
End If
DrawText lHDC, sCopy & vbNullChar, -1, tTR,
m_tCells(iCellCol, iRow).eTextFlags
If bCellSelected Then
SetTextColor lHDC,
TranslateColor(UserControl.ForeColor)
End If
If Len(m_sSearchString) > 0 And m_bEnabled Then
If (iRow = m_iSelRow) And (iCellCol =
m_iSearchCol) Then
SetBkMode m_hDC, OPAQUE
SetBkColor m_hDC,
TranslateColor(UserControl.BackColor)
SetTextColor m_hDC,
TranslateColor(UserControl.ForeColor)
'Debug.Print "'" & left$(m_tCells(iCellCol,
iRow).sText, Len(m_sSearchString)) & "'"
sCopy = Left$(m_tCells(iCellCol,
iRow).sText, Len(m_sSearchString))
DrawText m_hDC, sCopy & vbNullChar, -1,
tTR, m_tCells(iCellCol, iRow).eTextFlags
SetBkMode m_hDC, TRANSPARENT
End If
End If
If (hFntOld <> 0) Then
SelectObject m_hDC, hFntOld
hFntOld = 0
End If
End If
End If
End If
Next iCol
End If
If (m_bGridLines) Then
' If grid lines requested ensure we continue them off RHS of the
grid:
If (tR.Right < m_lAvailWidth + 32) Then
tTR.Left = tR.Right
tTR.Top = tR.Top
tTR.Right = m_lAvailWidth + 32
If (iRow <> iEndRow) Then
tTR.Bottom = tR.Bottom + 1
Else
tTR.Bottom = tR.Bottom
End If
FrameRect lHDC, tTR, hBrGrid
If (iRow = m_iRows) Then
'Debug.Print tTR.bottom
End If
End If
Else
' Draw focus rectangle for row mode to cover
' all the cells:
If (m_bRowMode) And Not (m_tRows(iRow).bGroupRow) Then
If (iRow = m_iSelRow) Then
tTR.Top = 1
tTR.Bottom = tR.Bottom
tTR.Left = m_tCols(iFirstColInSelect).lStartX -
m_lStartX +
m_tCells(m_tCols(iFirstColInSelect).lCellColIndex,
iRow).lIndent
tTR.Right = tR.Right
' 19/10/1999 (14):
If m_bDrawFocusRectangle And m_bInFocus And m_bEnabled
Then
LSet tFR = tTR
tFR.Top = 0
DrawFocusRect lHDC, tTR
For iCol = 1 To m_iCols
m_tCells(iCol, m_iSelRow).bDirtyFlag = True
Next iCol
End If
End If
End If
End If
' Draw the grouped cells:
If (m_bRowMode) Or (m_tRows(iRow).bGroupRow) Then
If (m_iRowTextCol <> 0) Then
LSet tTR = tR
If Not m_tRows(iRow).bGroupRow Then
tTR.Top = m_lDefaultRowHeight
Else
tTR.Top = 1
bSel = False
End If
lThisRowStartX = lRowStartX
If m_tRows(iRow).bGroupRow And
m_tRows(iRow).lGroupStartColIndex <> 0 Then
' Must evaluate the correct start and end points:
For iCol = 1 To m_iCols
If m_tCols(iCol).lCellColIndex =
m_tRows(iRow).lGroupStartColIndex Then
lThisRowStartX = m_tCols(iCol).lStartX - m_lStartX
End If
Next iCol
End If
tTR.Left = lThisRowStartX + m_tCells(m_iRowTextCol,
iRow).lIndent
tTR.Right = lRowEndX
'Debug.Print tTR.left, tTR.right
If Not IsMissing(m_tCells(m_iRowTextCol, iRow).sText) Then
sCopy = m_tCells(m_iRowTextCol, iRow).sText
Else
sCopy = ""
End If
If (m_tCols(iCRowTextCol).sFmtString <> "") Then
sCopy = Format$(sCopy, m_tCols(iCRowTextCol).sFmtString)
End If
If Not (bSel) Then
If m_tRows(iRow).bGroupRow Then
If m_tCells(m_iRowTextCol, iRow).bSelected Then
hBr =
CreateSolidBrush(TranslateColor(m_oHighlightBackC
olor))
'hBr = GetSysColorBrush(vbHighlight And &H1F&)
FillRect m_hDC, tTR, hBr
DeleteObject hBr
' 19/10/1999 (14):
If m_bDrawFocusRectangle And m_bInFocus And
m_bEnabled Then
DrawFocusRect lHDC, tTR
End If
'SetTextColor m_hDC,
TranslateColor(vbHighlightText)
' 19/10/1999 (8)
SetTextColor m_hDC,
TranslateColor(m_oHighlightForeColor)
Else
If (m_tCells(m_iRowTextCol, iRow).oBackColor <>
CLR_NONE) Then
hBr =
CreateSolidBrush(TranslateColor(m_tCells(m_iRo
wTextCol, iRow).oBackColor))
FillRect m_hDC, tTR, hBr
DeleteObject hBr
End If
If (m_tCells(m_iRowTextCol, iRow).oForeColor <>
CLR_NONE) Then
SetTextColor m_hDC,
TranslateColor(m_tCells(m_iRowTextCol,
iRow).oForeColor)
Else
SetTextColor m_hDC,
TranslateColor(UserControl.ForeColor)
End If
End If
Else
If (m_tCells(m_iRowTextCol, iRow).oBackColor <>
CLR_NONE) Then
hBr =
CreateSolidBrush(TranslateColor(m_tCells(m_iRowTe
xtCol, iRow).oBackColor))
FillRect m_hDC, tTR, hBr
DeleteObject hBr
End If
If (m_tCells(m_iRowTextCol, iRow).oForeColor <>
CLR_NONE) Then
SetTextColor m_hDC,
TranslateColor(m_tCells(m_iRowTextCol,
iRow).oForeColor)
End If
End If
End If
If (m_tCells(m_iRowTextCol, iRow).lExtraIconIndex > -1)
Then
DrawImage m_hIml, m_tCells(m_iRowTextCol,
iRow).lExtraIconIndex, lHDC, tTR.Left, tTR.Top,
m_lIconSizeX, m_lIconSizeY, m_tCells(m_iRowTextCol,
iRow).bSelected And m_bHighlightSelectedIcons, , Not
(m_bEnabled) And m_bDisableIcons
tTR.Left = tTR.Left + m_lIconSizeX + 2
End If
If (m_tCells(m_iRowTextCol, iRow).iIconIndex > -1) Then
DrawImage m_hIml, m_tCells(m_iRowTextCol,
iRow).iIconIndex, lHDC, tTR.Left, tTR.Top,
m_lIconSizeX, m_lIconSizeY, m_tCells(m_iRowTextCol,
iRow).bSelected And m_bHighlightSelectedIcons, , Not
(m_bEnabled) And m_bDisableIcons
tTR.Left = tTR.Left + m_lIconSizeX + 2
End If
If (m_tCells(m_iRowTextCol, iRow).iFntIndex <> 0) Then
hFntOld = SelectObject(m_hDC,
m_hFnt(m_tCells(m_iRowTextCol, iRow).iFntIndex))
End If
If bCellSelected Then
'SetTextColor lHDC, TranslateColor(vbHighlightText)
' 19/10/1999 (8)
SetTextColor lHDC, TranslateColor(m_oHighlightForeColor)
End If
DrawText m_hDC, sCopy, Len(sCopy), tTR,
m_tCells(m_iRowTextCol, iRow).eTextFlags
' Fix for row getting selection colour after group row:
SetTextColor lHDC, TranslateColor(UserControl.ForeColor)
If (hFntOld <> 0) Then
SelectObject m_hDC, hFntOld
hFntOld = 0
End If
End If
End If
If (m_hDC <> 0) Then
BitBlt lHDCC, 0, m_tRows(iRow).lStartY - m_lStartY + lOffset,
m_lAvailWidth + Abs(m_tCols(iStartCol).lStartX - m_lStartX)
+ 32, m_tRows(iRow).lHeight, m_hDC, 0, 0, vbSrcCopy
End If
End If ' row not dirty
lLastPos = m_tRows(iRow).lStartY - m_lStartY + m_tRows(iRow).lHeight
bCellSelected = False
End If
Next iRow
' Is there any space left over at the bottom?
tR.Bottom = UserControl.Height \ Screen.TwipsPerPixelY
If (lLastPos < tR.Bottom) Then
tR.Left = 0
tR.Top = lLastPos + lOffset
tR.Right = m_lAvailWidth + 32
pFillBackground lHDCC, tR, 0, lLastPos
End If
If (m_bGridLines) Then
DeleteObject hBrGrid
End If
If (bSel) Then
SetTextColor lHDC, TranslateColor(UserControl.ForeColor)
End If
m_iLastSelRow = m_iSelRow
m_iLastSelCol = m_iSelCol
m_bDirty = False
If bRecall Then
bRecall = False
m_bDirty = True
Draw
End If
End If
End Sub
Private Sub pFillBackground( _
ByVal lHDC As Long, _
ByRef tR As RECT, _
ByVal lOffsetX As Long, _
ByVal lOffsetY As Long _
)
Dim hBr As Long
If (m_bBitmap) Then
TileArea lHDC, tR.Left, tR.Top, tR.Right - tR.Left, tR.Bottom - tR.Top,
m_hDCSrc, m_lBitmapW, m_lBitmapH, lOffsetX, lOffsetY
Else
If Not (m_bEnabled) Then
hBr = GetSysColorBrush(vbButtonFace And &H1F&)
Else
If (UserControl.BackColor And &H80000000) = &H80000000 Then
hBr = GetSysColorBrush(UserControl.BackColor And &H1F&)
Else
hBr = CreateSolidBrush(TranslateColor(UserControl.BackColor))
End If
End If
FillRect lHDC, tR, hBr
DeleteObject hBr
End If
End Sub
Private Sub pCreateHeader()
Set m_cHeader = New cHeaderControl
m_cHeader.Init UserControl.hwnd, UserControl.Ambient.UserMode
End Sub
Private Function pbEnsureVisible( _
ByVal lRow As Long, _
ByVal lCol As Long _
) As Boolean
Dim lXStart As Long
Dim lXEnd As Long
Dim lYStart As Long
Dim lYEnd As Long
Dim lOffset As Long
Dim lValue As Long
Dim iCellCol As Long
Dim lStartColIndex As Long
' Check x:
If Not (m_bRowMode) Or (m_bMouseDown) Then
For iCellCol = 1 To m_iCols
If (m_tCols(iCellCol).lCellColIndex = lCol) Then
lCol = iCellCol
If lStartColIndex <> 0 Then
Exit For
End If
End If
If m_lRowTextStartCol = 0 Then
If m_tCols(iCellCol).bIncludeInSelect Then
lStartColIndex = iCellCol
End If
End If
Next iCellCol
If m_tRows(lRow).bGroupRow Then
If m_tRows(lRow).lGroupStartColIndex = 0 Then
lStartColIndex = m_lRowTextStartCol
Else
If m_tRows(lRow).lGroupStartColIndex <> 0 Then
lStartColIndex = m_tRows(lRow).lGroupStartColIndex
End If
End If
lXStart = m_tCols(lStartColIndex).lStartX
If m_bTryToFitGroupRows Then
lXEnd = m_tCols(m_iCols).lStartX + m_tCols(m_iCols).lWidth
Else
lXEnd = lXStart + 1
End If
Else
lXStart = m_tCols(lCol).lStartX
lXEnd = lXStart + m_tCols(lCol).lWidth
End If
If (lXStart > m_lStartX) Then
If (lXEnd < m_lStartX + m_lAvailWidth) Then
' Ok
Else
' Have to shift x rightwards:
If (m_tCols(lCol).lWidth > m_lAvailWidth) Then
' Ensure start of column is visible:
lOffset = lXStart - m_lStartX
lValue = m_cScroll.Value(efsHorizontal)
m_cScroll.Value(efsHorizontal) = m_cScroll.Value(efsHorizontal)
+ lOffset
pbEnsureVisible = (m_cScroll.Value(efsHorizontal) <> lValue)
Else
' Make entire cell visible:
lOffset = lXEnd - (m_lStartX + m_lAvailWidth) + 8
lValue = m_cScroll.Value(efsHorizontal)
m_cScroll.Value(efsHorizontal) = m_cScroll.Value(efsHorizontal)
+ lOffset
pbEnsureVisible = (m_cScroll.Value(efsHorizontal) <> lValue)
End If
End If
Else
' have to shift x leftwards:
If (lXStart < m_lStartX) Then
lOffset = lXStart - m_lStartX - 8
lValue = m_cScroll.Value(efsHorizontal)
m_cScroll.Value(efsHorizontal) = m_cScroll.Value(efsHorizontal) +
lOffset
pbEnsureVisible = (m_cScroll.Value(efsHorizontal) <> lValue)
End If
End If
End If
' Check y
lYStart = m_tRows(lRow).lStartY
lYEnd = lYStart + m_tRows(lRow).lHeight
If (lYStart > m_lStartY) Then
If (lYEnd < m_lStartY + m_lAvailheight) Then
' Ok
Else
' Have to shift y downwards:
If (m_tRows(lRow).lHeight < m_lAvailheight) Then
lOffset = lYEnd - (m_lStartY + m_lAvailheight) + 8
lValue = m_cScroll.Value(efsVertical)
m_cScroll.Value(efsVertical) = m_cScroll.Value(efsVertical) +
lOffset
pbEnsureVisible = (m_cScroll.Value(efsVertical) <> lValue)
End If
End If
Else
' Have to shift y upwards:
If (lYStart < m_lStartY) Then
lOffset = lYStart - m_lStartY - 8
lValue = m_cScroll.Value(efsVertical)
m_cScroll.Value(efsVertical) = m_cScroll.Value(efsVertical) + lOffset
pbEnsureVisible = (m_cScroll.Value(efsVertical) <> lValue)
End If
End If
End Function
Private Sub GetStartEndCell( _
ByRef iStartRow As Long, ByRef iStartCol As Long, _
ByRef iStartX As Long, ByRef iStartY As Long, _
ByRef iEndRow As Long, ByRef iEndCol As Long, _
ByRef iEndX As Long, ByRef iEndY As Long _
)
Dim i As Long
iStartCol = 0: iEndCol = m_iCols
For i = 1 To m_iCols
If (m_tCols(i).bVisible) And (i <> m_iRowTextCol) Then
If (iStartCol = 0) Then
If (m_tCols(i).lStartX + m_tCols(i).lWidth > m_lStartX) Then
iStartCol = i
iStartX = m_tCols(i).lStartX - m_lStartX
End If
End If
iEndCol = i
iEndX = m_tCols(i).lStartX - m_lStartX + m_tCols(i).lWidth
If (m_tCols(i).lStartX > m_lStartX + m_lAvailWidth) Then
Exit For
End If
End If
Next i
iStartRow = 0: iEndRow = m_iRows
For i = 1 To m_iRows
If (m_tRows(i).bVisible) Then
If (iStartRow = 0) Then
If m_tRows(i).lStartY + m_tRows(i).lHeight > m_lStartY Then
iStartRow = i
iStartY = m_tRows(i).lStartY - m_lStartY
If m_tRows(i).bGroupRow Then
iEndCol = m_iCols
End If
End If
Else
If m_tRows(i).bGroupRow Then
iEndCol = m_iCols
End If
iEndRow = i
iEndY = m_tRows(i).lStartY - m_lStartY + m_tRows(i).lHeight
If (m_tRows(i).lStartY > m_lStartY + m_lAvailheight) Then
Exit For
End If
End If
End If
Next i
End Sub
Public Sub CellFromPoint( _
ByVal xPixels As Long, _
ByVal yPixels As Long, _
ByRef lRow As Long, _
ByRef lCol As Long _
)
Attribute CellFromPoint.VB_Description = "Gets the cell which contains the
given X,Y coordinates (relative to the grid) in pixels."
Dim iCol As Long
Dim iRow As Long
Dim lOffset As Long
lOffset = Abs(m_cHeader.Visible) * m_cHeader.Height
xPixels = xPixels + m_lStartX
yPixels = yPixels + m_lStartY - lOffset
lCol = 0: lRow = 0
For iRow = 1 To m_iRows
If (m_tRows(iRow).bVisible) Then
If (yPixels > m_tRows(iRow).lStartY) And (yPixels <=
m_tRows(iRow).lStartY + m_tRows(iRow).lHeight) Then
lRow = iRow
Exit For
End If
End If
Next iRow
If (iRow = 0) Then
iCol = 0
End If
For iCol = 1 To m_iCols
If m_tRows(lRow).bGroupRow Then
lCol = m_iRowTextCol
Else
If (m_tCols(iCol).bVisible) And (iCol <> m_iRowTextCol) Then
If (xPixels > m_tCols(iCol).lStartX) And (xPixels <=
m_tCols(iCol).lStartX + m_tCols(iCol).lWidth) Then
lCol = m_tCols(iCol).lCellColIndex
Exit For
End If
End If
End If
Next iCol
If (lCol = 0) Then
Exit Sub
End If
End Sub
Public Sub CellBoundary( _
ByVal lRow As Long, _
ByVal lCol As Long, _
ByRef lLeft As Long, _
ByRef lTop As Long, _
ByRef lWidth As Long, _
ByRef lHeight As Long _
)
Attribute CellBoundary.VB_Description = "Gets the co-ordinates of the bounding
rectangle for a cell in the grid, in twips."
Dim lOffsetY As Long
Dim lOffsetX As Long
Dim iCol As Long
Dim lCellCol As Long
For iCol = 1 To m_iCols
If (m_tCols(iCol).lCellColIndex = lCol) Then
lCellCol = iCol
Exit For
End If
Next iCol
lOffsetY = Abs(m_bHeader) * m_cHeader.Height
lOffsetX = m_tCells(lCol, lRow).lIndent + (Abs(m_tCells(lCol,
lRow).iIconIndex <> -1) * m_lIconSizeX) + (Abs(m_tCells(lCol,
lRow).lExtraIconIndex <> -1) * m_lIconSizeX)
lLeft = (m_tCols(lCellCol).lStartX - m_lStartX + lOffsetX) *
Screen.TwipsPerPixelX
lTop = ((m_tRows(lRow).lStartY - m_lStartY) + lOffsetY) *
Screen.TwipsPerPixelY
lWidth = (m_tCols(lCellCol).lWidth - lOffsetX) * Screen.TwipsPerPixelX
lHeight = m_tRows(lRow).lHeight * Screen.TwipsPerPixelY
End Sub
Public Sub EnsureVisible( _
ByVal lRow As Long, _
ByVal lCol As Long _
)
Dim iCol As Long
If pbValid(lRow, lCol) Then
If m_tRows(lRow).bVisible Then
If m_tCols(lCol).bVisible Or m_tRows(lRow).bGroupRow Then
' If rowtext column, choose the start pos based on the
' grid's settings:
If m_tCols(lCol).bRowTextCol Or m_tRows(lRow).bGroupRow Then
lCol = 0
If m_lRowTextStartCol > 0 Then
lCol = m_lRowTextStartCol
Else
For iCol = 1 To m_iCols
If m_tCols(iCol).bIncludeInSelect And
m_tCols(iCol).bVisible Then
lCol = iCol
Exit For
End If
Next iCol
End If
End If
' Call inbuild ensure visible method:
If lCol > 0 Then
pbEnsureVisible lRow, lCol
End If
Else
' can't ensure an invisible col visible... Don't raise error
End If
Else
' can't ensure an invisible row visible... Don't raise error
End If
End If
End Sub
Public Sub ClearSelection()
' 19/10/99 4)
Dim lRow As Long
Dim lCol As Long
If m_bMultiSelect Then
For lRow = 1 To m_iRows
For lCol = 1 To m_iCols
m_tCells(lCol, lRow).bDirtyFlag = m_tCells(lCol, lRow).bSelected
m_tCells(lCol, lRow).bSelected = False
Next lCol
Next lRow
Draw
Else
If m_iSelRow > 0 And m_iSelRow <= m_iRows Then
If m_bRowMode Then
For lCol = 1 To m_iCols
m_tCells(lCol, m_iSelRow).bDirtyFlag = m_tCells(lCol,
m_iSelRow).bSelected
m_tCells(lCol, m_iSelRow).bSelected = False
Next lCol
Else
If m_iSelCol > 0 And m_iSelCol <= m_iCols Then
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
m_tCells(m_iSelCol, m_iSelRow).bSelected = False
End If
End If
End If
m_iSelRow = 0: m_iSelCol = 0
Draw
End If
End Sub
Public Property Get hwnd() As Long
' 19/10/99 1)
hwnd = UserControl.hwnd
End Property
Public Function AddColumn( _
Optional ByVal vKey As String, _
Optional ByVal sHeader As String, _
Optional ByVal eAlign As ECGHdrTextAlignFlags, _
Optional ByVal iIconIndex As Long = -1, _
Optional ByVal lColumnWidth As Long = -1, _
Optional ByVal bVisible As Boolean = True, _
Optional ByVal bFixed As Boolean = False, _
Optional ByVal vKeyBefore As Variant, _
Optional ByVal bIncludeInSelect As Boolean = True, _
Optional ByVal sFmtString As String, _
Optional ByVal bRowTextColumn As Boolean = False, _
Optional ByVal eSortType As cShellSortTypeConstants = CCLSortString _
) As Long
Dim i As Long
Dim lColBefore As Long
Dim lCol As Long
Dim iRow As Long
' Check for valid key:
If Not (pbIsValidColumnKey(vKey)) Then
Exit Function
End If
If (bRowTextColumn) Then
m_bHasRowText = True
End If
' If key valid then check for valid key after:
If Not IsMissing(vKeyBefore) Then
lColBefore = ColumnIndex(vKeyBefore)
If (lColBefore < 1) Then
Exit Function
End If
End If
' Correct missing params:
If (lColumnWidth = -1) Then
lColumnWidth = m_lDefaultColumnWidth
End If
' All ok, add the column:
ReDim Preserve m_tCols(0 To m_iCols + 1) As tColPosition
If (lColBefore <> 0) Then
For lCol = m_iCols + 1 To lColBefore Step -1
LSet m_tCols(lCol) = m_tCols(lCol - 1)
m_tCols(lCol).lCellColIndex = m_tCols(lCol).lCellColIndex + 1
Next lCol
lCol = lColBefore
Else
lCol = m_iCols + 1
End If
With m_tCols(lCol)
.lCellColIndex = lCol
.sKey = vKey
.bIncludeInSelect = bIncludeInSelect
.sHeader = sHeader
.iIconIndex = iIconIndex
.eTextAlign = eAlign
.sFmtString = sFmtString
.bVisible = bVisible
.eSortType = eSortType
End With
If (bRowTextColumn) Then
m_iRowTextCol = lCol
End If
m_iCols = m_iCols + 1
ColumnWidth(lCol) = lColumnWidth
'
If m_iRows > 0 Then
' (12) We need to add the extra data to the grid!
pAddColToGridArray lCol
End If
' Add to header:
If (m_tCols(lCol).bVisible) Then
SetHeaders
End If
End Function
Private Sub pAddColToGridArray(ByVal lCol As Long)
Dim iRow As Long
Dim iCol As Long
Dim iACol As Long
Dim tGridCopy() As tGridCell
' As with removing rows, this is quite a painful proc!
' you are advised to add columns first then rows...
ReDim tGridCopy(1 To m_iCols, 1 To m_iRows) As tGridCell
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols - 1
If (iCol > lCol) Then
iACol = iCol + 1
Else
iACol = iCol
End If
LSet tGridCopy(iACol, iRow) = m_tCells(iCol, iRow)
Next iCol
Next iRow
ReDim m_tCells(1 To m_iCols, 1 To m_iRows) As tGridCell
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If iCol = lCol Then
LSet m_tCells(iCol, iRow) = m_tDefaultCell
Else
LSet m_tCells(iCol, iRow) = tGridCopy(iCol, iRow)
End If
Next iCol
Next iRow
End Sub
Public Sub RemoveColumn( _
ByVal vKey As Variant _
)
Attribute RemoveColumn.VB_Description = "Permanently removes a column from the
grid. If all columns are removed, the grid will be cleared. If you want to
temporarily remove a column, use the ColumnVisible property."
Dim lCol As Long
Dim iRow As Long
Dim iCol As Long
Dim iCCol As Long
Dim lGridCol As Long
Dim tGridCopy() As tGridCell
lCol = ColumnIndex(vKey)
If (lCol <> 0) Then
' 19/10/99: (7)
If m_tCols(lCol).bRowTextCol Then
m_iRowTextCol = 0
m_lRowTextStartCol = 0
m_bHasRowText = False
End If
' Quite a lot of hacking to do here!
If (m_iCols > 1) Then
' Make a copy of the grid:
ReDim tGridCopy(1 To m_iCols, 1 To m_iRows) As tGridCell
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
LSet tGridCopy(iCol, iRow) = m_tCells(iCol, iRow)
Next iCol
Next iRow
' Now remove the column:
For iCol = 1 To m_iCols
If (m_tCols(iCol).lCellColIndex = lCol) Then
iCCol = iCol
Exit For
End If
Next iCol
For iCol = iCCol To m_iCols - 1
LSet m_tCols(iCol) = m_tCols(iCol + 1)
Next iCol
m_iCols = m_iCols - 1
For iCol = 1 To m_iCols
If (m_tCols(iCol).lCellColIndex > lCol) Then
m_tCols(iCol).lCellColIndex = m_tCols(iCol).lCellColIndex - 1
End If
Next iCol
ReDim Preserve m_tCols(0 To m_iCols) As tColPosition
m_tCols(1).lStartX = 0
ColumnWidth(1) = ColumnWidth(1)
' Having removed the column, rebuild the grid cells:
ReDim m_tCells(1 To m_iCols, 1 To m_iRows) As tGridCell
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (iCol >= lCol) Then
lGridCol = iCol + 1
Else
lGridCol = iCol
End If
LSet m_tCells(iCol, iRow) = tGridCopy(lGridCol, iRow)
Next iCol
Next iRow
' Set the headers back up if required:
If (m_bHeader) Then
SetHeaders
End If
' Now redraw:
m_bDirty = True
Draw
Else
' No columns, no grid!
m_iCols = 0
m_iRows = 0
ReDim m_tRows(0 To 0) As tRowPosition
ReDim m_tCols(0 To 0) As tColPosition
Erase m_tCells
' Set the headers back up if required:
If (m_bHeader) Then
SetHeaders
End If
m_bDirty = True
Draw
End If
End If
End Sub
Public Sub SetHeaders()
Attribute SetHeaders.VB_Description = "Populates the headers in the control
based on the columns in the grid. Called automatically by the control when
Headers is set to True."
Dim i As Long
For i = m_cHeader.ColumnCount To 1 Step -1
m_cHeader.RemoveColumn i - 1
Next i
For i = 1 To m_iCols
If (m_tCols(i).bVisible) And (i <> m_iRowTextCol) Then
m_cHeader.AddColumn m_tCols(i).sHeader, m_tCols(i).lWidth,
m_tCols(i).eTextAlign, , m_tCols(i).iIconIndex
If (m_tCols(i).bImageOnRight) Then
m_cHeader.ColumnImageOnRight(m_cHeader.ColumnCount - 1) = True
End If
m_tCols(i).lHeadercolIndex = m_cHeader.ColumnCount
Else
m_tCols(i).lHeadercolIndex = 0
End If
Next i
pResizeHeader
End Sub
Public Property Get ColumnIndex(ByVal vKey As Variant)
Attribute ColumnIndex.VB_Description = "Gets the index of a column with the
specified key."
Dim lIndex As Long
lIndex = plColumnIndex(vKey)
If (lIndex > 0) And (lIndex <= m_iCols) Then
ColumnIndex = lIndex
Else
ColumnIndex = 0
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Property
Private Function plColumnIndex(ByVal vKey As Variant)
Dim i As Long
Dim lIndex As Long
If IsNumeric(vKey) Then
' return the index of this column in the column header array
For i = 1 To m_iCols
If (m_tCols(i).lCellColIndex = vKey) Then
lIndex = i
Exit For
End If
Next i
Else
For i = 1 To m_iCols
If (m_tCols(i).sKey = vKey) Then
lIndex = i
Exit For
End If
Next i
End If
plColumnIndex = lIndex
End Function
Public Property Get ColumnImage(ByVal vKey As Variant) As Long
Attribute ColumnImage.VB_Description = "Gets/sets the image index to show in a
column's header. Image indexes are 0 based indexes of the images in an
ImageList."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol <> 0) Then
ColumnImage = m_tCols(lCol).iIconIndex
End If
End Property
Public Property Let ColumnImage(ByVal vKey As Variant, ByVal lImage As Long)
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol <> 0) Then
m_tCols(lCol).iIconIndex = lImage
If (m_tCols(lCol).bVisible) And lCol <> m_iRowTextCol Then
m_cHeader.ColumnImage(m_tCols(lCol).lHeadercolIndex - 1) = lImage
End If
End If
End Property
Public Property Get ColumnImageOnRight(ByVal vKey As Variant) As Boolean
Attribute ColumnImageOnRight.VB_Description = "Gets/sets whether images (if
any) will be shown on the right or not in a column header."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol <> 0) Then
ColumnImageOnRight = m_tCols(lCol).bImageOnRight
End If
End Property
Public Property Let ColumnImageOnRight(ByVal vKey As Variant, ByVal bState As
Boolean)
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol <> 0) Then
m_tCols(lCol).bImageOnRight = bState
If (m_tCols(lCol).bVisible) And lCol <> m_iRowTextCol Then
m_cHeader.ColumnImageOnRight(m_tCols(lCol).lHeadercolIndex - 1) =
bState
End If
End If
End Property
Public Property Get ColumnAlign(ByVal vKey As Variant) As ECGHdrTextAlignFlags
Attribute ColumnAlign.VB_Description = "Gets/sets the alignment used to draw
the column header for a column."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol <> 0) Then
ColumnAlign = m_tCols(lCol).eTextAlign
End If
End Property
Public Property Let ColumnAlign(ByVal vKey As Variant, ByVal eAlign As
ECGHdrTextAlignFlags)
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol <> 0) Then
m_tCols(lCol).eTextAlign = eAlign
If (m_tCols(lCol).bVisible) And lCol <> m_iRowTextCol Then
m_cHeader.ColumnTextAlign(m_tCols(lCol).lHeadercolIndex - 1) = eAlign
End If
End If
End Property
Public Property Get ColumnKey(ByVal lCol As Long) As String
Attribute ColumnKey.VB_Description = "Gets/sets the key for column."
Dim iCol As Long
If (lCol > 0) Then
For iCol = 1 To m_iCols
If (m_tCols(iCol).lCellColIndex = lCol) Then
ColumnKey = m_tCols(iCol).sKey
Exit For
End If
Next iCol
Else
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Property
Public Property Let ColumnKey(ByVal lCol As Long, ByVal sKey As String)
If (lCol > 0) Then
If (m_tCols(lCol).sKey <> sKey) Then
If (pbIsValidColumnKey(sKey)) Then
m_tCols(lCol).sKey = sKey
End If
End If
Else
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Property
Public Property Get ColumnTag(ByVal lCol As Long) As String
Attribute ColumnTag.VB_Description = "Gets/sets a tag string associated with a
column in the grid."
If (lCol > 0) Then
ColumnTag = m_tCols(lCol).sTag
Else
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Property
Public Property Let ColumnTag(ByVal lCol As Long, ByVal sTag As String)
If (lCol > 0) Then
If (m_tCols(lCol).sTag <> sTag) Then
m_tCols(lCol).sTag = sTag
End If
Else
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Property
Private Function pbIsValidColumnKey(ByVal sKey As String) As Boolean
Dim i As Long
If (sKey <> "") Then
For i = 1 To m_iCols
If (m_tCols(i).sKey = sKey) Then
Err.Raise 457, App.EXEName & ".vbalGrid"
Exit Function
End If
Next i
End If
pbIsValidColumnKey = True
End Function
Private Sub pScrollVisible()
Dim tR As RECT
Dim bHorz As Boolean
Dim bVert As Boolean
Dim lProportion As Long
Dim iLastRow As Long
Dim iCol As Long
GetWindowRect UserControl.hwnd, tR
m_lAvailWidth = tR.Right - tR.Left - (UserControl.BorderStyle * 4)
m_lAvailheight = tR.Bottom - tR.Top - (UserControl.BorderStyle * 4)
If (m_bHeader) Then
m_lAvailheight = m_lAvailheight - m_cHeader.Height
End If
For iCol = 1 To m_iCols
If (m_tCols(iCol).bVisible) And (m_tCols(iCol).lCellColIndex <>
m_iRowTextCol) Then
m_lGridWidth = m_tCols(iCol).lStartX + m_tCols(iCol).lWidth
End If
Next iCol
iLastRow = plGetLastVisibleRow()
If (m_bIsVirtual And m_bInVirtualRequest) Then
' Make the grid pretend to be bigger than it is:
m_lGridHeight = m_tRows(m_iRows).lStartY + m_tRows(m_iRows).lHeight +
m_lDefaultRowHeight
Else
m_lGridHeight = m_tRows(iLastRow).lStartY + m_tRows(iLastRow).lHeight
End If
' Check horizontal:
If (m_lGridWidth > m_lAvailWidth) Then
bHorz = True
End If
If (m_lGridHeight > m_lAvailheight) Then
bVert = True
End If
If Not (bVert And bHorz) Then
If (bVert) Then
If (m_bAllowVert) Then
m_lAvailWidth = m_lAvailWidth - GetSystemMetrics(SM_CXVSCROLL) - 4
End If
If (m_lGridWidth > m_lAvailWidth) Then
bHorz = True
End If
ElseIf (bHorz) Then
If (m_bAllowHorz) Then
m_lAvailheight = m_lAvailheight - GetSystemMetrics(SM_CYHSCROLL) - 4
End If
If (m_lGridHeight > m_lAvailheight) Then
bVert = True
End If
End If
Else
If (m_bAllowHorz) Then
m_lAvailWidth = m_lAvailWidth - GetSystemMetrics(SM_CXVSCROLL) - 4
End If
If (m_bAllowVert) Then
m_lAvailheight = m_lAvailheight - GetSystemMetrics(SM_CYHSCROLL) - 4
End If
End If
' Set visibility:
If m_cScroll.Visible(efsHorizontal) <> bHorz Then
If Not (bHorz And m_bAllowHorz) Then
m_cScroll.Value(efsHorizontal) = 0
End If
m_cScroll.Visible(efsHorizontal) = bHorz And m_bAllowHorz
pResizeHeader
End If
If m_cScroll.Visible(efsVertical) <> bVert Then
If Not (bVert And m_bAllowVert) Then
m_cScroll.Value(efsHorizontal) = 0
End If
m_cScroll.Visible(efsVertical) = bVert And m_bAllowVert
End If
' Check scaling:
m_lStartX = 0: m_lStartY = 0
If (bHorz) Then
With m_cScroll
If (bVert) Then
m_lAvailWidth = m_lAvailWidth - GetSystemMetrics(SM_CXVSCROLL) + 4
End If
If (.Max(efsHorizontal) <> m_lGridWidth - m_lAvailWidth) Then
.Max(efsHorizontal) = m_lGridWidth - m_lAvailWidth
If (m_lAvailWidth > 0) Then
lProportion = ((m_lGridWidth - m_lAvailWidth) \ m_lAvailWidth) +
1
.LargeChange(efsHorizontal) = (m_lGridWidth - m_lAvailWidth) \
lProportion
.SmallChange(efsHorizontal) = 20
End If
pResizeHeader
End If
m_lStartX = m_cScroll.Value(efsHorizontal)
End With
End If
If (bVert) Then
With m_cScroll
If (bHorz) Then
m_lAvailheight = m_lAvailheight - GetSystemMetrics(SM_CYHSCROLL) + 4
End If
If (m_bIsVirtual And m_bInVirtualRequest) Then
.Max(efsVertical) = m_lGridHeight + m_lDefaultRowHeight -
m_lAvailheight
Else
.Max(efsVertical) = m_lGridHeight - m_lAvailheight
End If
If (m_lAvailheight > 0) Then
lProportion = ((m_lGridHeight - m_lAvailheight) \ m_lAvailheight) +
1
.LargeChange(efsVertical) = (m_lGridHeight - m_lAvailheight) \
lProportion
.SmallChange(efsVertical) = m_lDefaultRowHeight
End If
m_lStartY = m_cScroll.Value(efsVertical)
End With
End If
End Sub
Public Property Get Header() As Boolean
Attribute Header.VB_Description = "Gets/sets whether the grid has a header or
not."
Attribute Header.VB_ProcData.VB_Invoke_Property = ";Behavior"
Header = m_bHeader
End Property
Public Property Let Header(ByVal bState As Boolean)
m_bHeader = bState
m_cHeader.Visible = bState
pResizeHeader
PropertyChanged "Header"
End Property
Public Property Get HeaderFlat() As Boolean
HeaderFlat = m_bHeaderFlat
End Property
Public Property Let HeaderFlat(ByVal bState As Boolean)
m_bHeaderFlat = bState
If Not (m_cFlatHeader Is Nothing) Then
If bState Then
m_cFlatHeader.Attach UserControl.hwnd
Else
m_cFlatHeader.Detach
End If
End If
PropertyChanged "Header"
End Property
Public Property Get HeaderHeight() As Long
HeaderHeight = m_cHeader.Height
End Property
Public Property Let HeaderHeight(ByVal lHeight As Long)
m_cHeader.Height = lHeight
pResizeHeader
Draw
PropertyChanged "HeaderHeight"
End Property
Public Property Get HeaderDragReOrderColumns() As Boolean
Attribute HeaderDragReOrderColumns.VB_Description = "Gets/sets whether the
grid's header columns can be dragged around to reorder them."
Attribute HeaderDragReOrderColumns.VB_ProcData.VB_Invoke_Property = ";Behavior"
HeaderDragReOrderColumns = m_cHeader.DragReOrderColumns
End Property
Public Property Let HeaderDragReOrderColumns(ByVal bState As Boolean)
m_cHeader.DragReOrderColumns = bState
SetHeaders
PropertyChanged "HeaderDragReOrderColumns"
End Property
Public Property Get HeaderButtons() As Boolean
Attribute HeaderButtons.VB_Description = "Gets/sets whether the grid's header
has clickable buttons or not."
Attribute HeaderButtons.VB_ProcData.VB_Invoke_Property = ";Behavior"
HeaderButtons = m_cHeader.HasButtons
End Property
Public Property Let HeaderButtons(ByVal bState As Boolean)
m_cHeader.HasButtons = bState
SetHeaders
PropertyChanged "HeaderButtons"
End Property
Public Property Get HeaderHotTrack() As Boolean
Attribute HeaderHotTrack.VB_Description = "Gets/sets whether the grid's header
tracks mouse movements and highlights the header column the mouse is over or
not."
Attribute HeaderHotTrack.VB_ProcData.VB_Invoke_Property = ";Behavior"
HeaderHotTrack = m_cHeader.HotTrack
End Property
Public Property Let HeaderHotTrack(ByVal bState As Boolean)
m_cHeader.HotTrack = bState
SetHeaders
PropertyChanged "HeaderHotTrack"
End Property
Private Function pbValid(ByVal lRow As Long, ByVal lCol As Long) As Boolean
If (lCol > 0) And (lCol <= m_iCols) Then
If (lRow > 0) And (lRow <= m_iRows) Then
pbValid = True
Else
Err.Raise 9, App.EXEName & ".vbalGrid", "Invalid Row Index"
End If
Else
Err.Raise 9, App.EXEName & ".vbalGrid", "Invalid Column Index"
End If
End Function
Public Sub CellDetails( _
ByVal lRow As Long, ByVal lCol As Long, _
Optional ByVal sText As Variant, _
Optional ByVal eTextAlign As ECGTextAlignFlags = DT_WORD_ELLIPSIS Or
DT_SINGLELINE, _
Optional ByVal lIconIndex As Long = -1, _
Optional ByVal oBackColor As OLE_COLOR = CLR_NONE, _
Optional ByVal oForeColor As OLE_COLOR = CLR_NONE, _
Optional ByVal oFont As StdFont = Nothing, _
Optional ByVal lIndent As Long = 0, _
Optional ByVal lExtraIconIndex As Long = -1, _
Optional ByVal lItemData As Long = 0 _
)
Attribute CellDetails.VB_Description = "Sets multiple format details for a cell
at the same time. Quicker than calling the properties individually."
If (lRow > m_iRows) Then
Rows = lRow
End If
If pbValid(lRow, lCol) Then
With m_tCells(lCol, lRow)
.sText = sText
.eTextFlags = eTextAlign Or DT_NOPREFIX
.bDirtyFlag = True
.oBackColor = oBackColor
.oForeColor = oForeColor
.iIconIndex = lIconIndex
.lExtraIconIndex = lExtraIconIndex
.lIndent = lIndent
If Not (oFont Is Nothing) Then
.iFntIndex = plAddFontIfRequired(oFont)
End If
.bDirtyFlag = True
.lItemData = lItemData
End With
Draw
End If
End Sub
Public Property Get Cell(ByVal lRow As Long, ByVal lCol As Long) As cGridCell
If pbValid(lRow, lCol) Then
Dim cS As New cGridCell
With cS
.BackColor = CellBackColor(lRow, lCol)
.ForeColor = CellForeColor(lRow, lCol)
If (m_tCells(lCol, lRow).iFntIndex = 0) Then
If Not .Font Is Nothing Then
.Font = Nothing
End If
Else
.Font = CellFont(lRow, lCol)
End If
.IconIndex = CellIcon(lRow, lCol)
.ExtraIconIndex = CellExtraIcon(lRow, lCol)
.Indent = CellIndent(lRow, lCol)
.TextAlign = CellTextAlign(lRow, lCol)
.Text = CellText(lRow, lCol)
.ItemData = CellItemData(lRow, lCol)
.Init Me, lRow, lCol
End With
Set Cell = ObjectFromPtr(ObjPtr(cS))
End If
End Property
Public Property Let Cell(ByVal lRow As Long, ByVal lCol As Long, ByRef cG As
cGridCell)
CellDetails lRow, lCol, cG.Text, cG.TextAlign, cG.IconIndex, cG.BackColor,
cG.ForeColor, cG.Font, cG.Indent, cG.ExtraIconIndex
End Property
Public Property Get NewCellFormatObject() As cGridCell
Dim cS As New cGridCell
Set NewCellFormatObject = ObjectFromPtr(ObjPtr(cS))
End Property
Private Function plAddFontIfRequired(ByVal oFont As StdFont) As Long
Dim iFnt As Long
Dim tULF As LOGFONT
For iFnt = 1 To m_iFontCount
If (oFont.Name = m_Fnt(iFnt).Name) And (oFont.Bold = m_Fnt(iFnt).Bold)
And (oFont.Italic = m_Fnt(iFnt).Italic) And (oFont.Underline =
m_Fnt(iFnt).Underline) And (oFont.Size = m_Fnt(iFnt).Size) And
(oFont.Strikethrough = m_Fnt(iFnt).Strikethrough) Then
plAddFontIfRequired = iFnt
Exit Function
End If
Next iFnt
m_iFontCount = m_iFontCount + 1
ReDim Preserve m_Fnt(1 To m_iFontCount) As StdFont
ReDim Preserve m_hFnt(1 To m_iFontCount) As Long
Set m_Fnt(m_iFontCount) = New StdFont
With m_Fnt(m_iFontCount)
.Name = oFont.Name
.Size = oFont.Size
.Bold = oFont.Bold
.Italic = oFont.Italic
.Underline = oFont.Underline
.Strikethrough = oFont.Strikethrough
End With
pOLEFontToLogFont m_Fnt(m_iFontCount), UserControl.hdc, tULF
m_hFnt(m_iFontCount) = CreateFontIndirect(tULF)
plAddFontIfRequired = m_iFontCount
End Function
Public Property Get RowHeight(ByVal lRow As Long) As Long
Attribute RowHeight.VB_Description = "Gets/sets the height of a row in the
grid."
If (lRow > 0) And (lRow <= m_iRows) Then
RowHeight = m_tRows(lRow).lHeight
Else
Err.Raise 9, App.EXEName, "Invalid Row Subscript"
End If
End Property
Public Property Let RowHeight(ByVal lRow As Long, ByVal lHeight As Long)
Dim lCalcRow As Long
Dim lPreviousRowHeight As Long
Dim lPreviousStartY As Long
If (lRow > 0) Then
If (lRow > m_iRows) Then
ReDim Preserve m_tRows(0 To lRow) As tRowPosition
For lCalcRow = m_iRows + 1 To lRow
m_tRows(lCalcRow).bVisible = True
m_tRows(lCalcRow).lHeight = m_lDefaultRowHeight
m_tRows(lCalcRow).lStartY = m_tRows(lCalcRow - 1).lStartY +
m_tRows(lCalcRow - 1).lHeight
Next lCalcRow
m_iRows = lRow
End If
m_tRows(lRow).lHeight = lHeight
m_tRows(0).lHeight = 0
For lCalcRow = lRow To m_iRows
If (m_tRows(lCalcRow - 1).bVisible) Then
m_tRows(lCalcRow).lStartY = m_tRows(lCalcRow - 1).lStartY +
m_tRows(lCalcRow - 1).lHeight
Else
m_tRows(lCalcRow).lStartY = m_tRows(lCalcRow - 1).lStartY
End If
Next lCalcRow
If (lHeight > m_lMaxRowHeight) Then
BuildMemDC lHeight
End If
Else
Err.Raise 9, App.EXEName & ".vbalGrid", "Row subscript out of range"
End If
End Property
Private Sub BuildMemDC(ByVal lHeight As Long)
Dim tR As RECT
Dim hBr As Long
If (m_hBmp <> 0) Then
If (m_hBmpOld <> 0) Then
SelectObject m_hDC, m_hBmpOld
End If
If (m_hBmp <> 0) Then
DeleteObject m_hBmp
End If
m_hBmp = 0
m_hBmpOld = 0
End If
If (m_hDC = 0) Then
m_hDC = CreateCompatibleDC(UserControl.hdc)
Else
SelectObject m_hDC, m_hFntOldDC
End If
If (m_hDC <> 0) Then
m_lMaxRowHeight = lHeight
m_hBmp = CreateCompatibleBitmap(UserControl.hdc, Screen.Width \
Screen.TwipsPerPixelX, lHeight)
If (m_hBmp <> 0) Then
m_hBmpOld = SelectObject(m_hDC, m_hBmp)
If (m_hBmpOld = 0) Then
DeleteObject m_hBmp
DeleteObject m_hDC
m_hBmp = 0
m_hDC = 0
Else
SetTextColor m_hDC, TranslateColor(UserControl.ForeColor)
SetBkColor m_hDC, TranslateColor(UserControl.BackColor)
SetBkMode m_hDC, TRANSPARENT
m_hFntOldDC = SelectObject(m_hDC, m_hFntDC)
tR.Right = Screen.Width \ Screen.TwipsPerPixelX
tR.Bottom = lHeight
hBr = CreateSolidBrush(TranslateColor(UserControl.BackColor))
FillRect m_hDC, tR, hBr
DeleteObject hBr
End If
Else
DeleteObject m_hDC
m_hDC = 0
End If
End If
End Sub
Public Property Get ColumnOrder(ByVal vKey As Variant) As Long
Attribute ColumnOrder.VB_Description = "Gets/sets the order of a column in the
control."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
ColumnOrder = lCol
End If
End Property
Public Property Let ColumnOrder(ByVal vKey As Variant, ByVal lOrder As Long)
Dim lCol As Long
Dim tSwap As tColPosition
Dim lStartX As Long
Dim i As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
If (lCol <> lOrder) Then
' We want to swap item lCol in the m_tCols array with
' the item at position lOrder, then recreate the header
LSet tSwap = m_tCols(lCol)
LSet m_tCols(lCol) = m_tCols(lOrder)
LSet m_tCols(lOrder) = tSwap
For i = 1 To m_iCols
m_tCols(i).lStartX = lStartX
If (m_tCols(i).bVisible) Then
lStartX = lStartX + m_tCols(i).lWidth
End If
Next i
SetHeaders
m_bDirty = True
Draw
End If
End If
End Property
Public Property Get ColumnSortType(ByVal vKey As Variant) As
cShellSortTypeConstants
Attribute ColumnSortType.VB_Description = "Gets/sets a variable which you can
use to store the current column sort type."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
ColumnSortType = m_tCols(lCol).eSortType
End If
End Property
Public Property Let ColumnSortType(ByVal vKey As Variant, ByVal eSortType As
cShellSortTypeConstants)
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
m_tCols(lCol).eSortType = eSortType
End If
End Property
Public Property Get ColumnSortOrder(ByVal vKey As Variant) As
cShellSortOrderCOnstants
Attribute ColumnSortOrder.VB_Description = "Gets/sets a variable which you can
use to store the current column sort order."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
ColumnSortOrder = m_tCols(lCol).eSortOrder
End If
End Property
Public Property Let ColumnSortOrder(ByVal vKey As Variant, ByVal eSortOrder As
cShellSortOrderCOnstants)
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
m_tCols(lCol).eSortOrder = eSortOrder
End If
End Property
Public Property Get KeySearchColumn() As Long
Attribute KeySearchColumn.VB_Description = "Gets/sets the column in the grid to
be used for automatic searching when the grid is not being edited. Set to 0
to prevent automatic searching."
Attribute KeySearchColumn.VB_MemberFlags = "400"
KeySearchColumn = m_iSearchCol
End Property
Public Property Let KeySearchColumn(ByVal lCol As Long)
m_iSearchCol = lCol
End Property
Public Property Get ColumnWidth(ByVal vKey As Variant) As Long
Attribute ColumnWidth.VB_Description = "Gets/sets the width of a column in the
grid."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
ColumnWidth = m_tCols(lCol).lWidth
End If
End Property
Public Property Let ColumnWidth(ByVal vKey As Variant, ByVal lWidth As Long)
Dim lCalcCol As Long
Dim lCellColIndex As Long
Dim lCol As Long
Dim lLastWidth As Long
Dim iVisibleCols As Long
lCol = plColumnIndex(vKey)
If (lCol > 0) Then
If (lCol > m_iCols) Then
ReDim Preserve m_tCols(0 To lCol) As tColPosition
For lCalcCol = m_iCols + 1 To lCol
m_tCols(lCalcCol).lWidth = m_lDefaultColumnWidth
m_tCols(lCalcCol).bVisible = True
Next lCalcCol
m_iCols = lCol
End If
m_tCols(0).lWidth = 0
m_tCols(lCol).lWidth = lWidth
For lCalcCol = 1 To m_iCols
If (m_tCols(lCalcCol).bVisible) Then
m_tCols(lCalcCol).lStartX = m_tCols(lCalcCol - 1).lStartX +
lLastWidth
lLastWidth = m_tCols(lCalcCol).lWidth
Else
m_tCols(lCalcCol).lStartX = m_tCols(lCalcCol - 1).lStartX
End If
Next lCalcCol
If (m_tCols(lCol).lHeadercolIndex - 1) > 0 Then
If m_cHeader.ColumnWidth(m_tCols(lCol).lHeadercolIndex - 1) <> lWidth
Then
m_cHeader.ColumnWidth(m_tCols(lCol).lHeadercolIndex - 1) = lWidth
End If
End If
Else
Err.Raise 9, App.EXEName & ".vbalGrid", "Column subscript out of range"
End If
End Property
Public Property Get ColumnHeader(ByVal vKey As Variant) As String
Attribute ColumnHeader.VB_Description = "Gets/sets the text to appear in a
column header."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
ColumnHeader = m_tCols(lCol).sHeader
End If
End Property
Public Property Let ColumnHeader(ByVal vKey As Variant, ByVal sHeader As String)
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
m_tCols(lCol).sHeader = sHeader
If (m_tCols(lCol).bVisible) And lCol <> m_iRowTextCol Then
m_cHeader.ColumnHeader(m_tCols(lCol).lHeadercolIndex - 1) = sHeader
End If
End If
End Property
Public Property Get ColumnFormatString(ByVal vKey As Variant) As String
Attribute ColumnFormatString.VB_Description = "Gets/sets a format string used
to format all text in the column. Format strings are the same as those used
in the VB Format$ function."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
ColumnFormatString = m_tCols(lCol).sFmtString
End If
End Property
Public Property Let ColumnFormatString(ByVal vKey As Variant, ByVal sFmtString
As String)
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
m_tCols(lCol).sFmtString = sFmtString
If (m_tCols(lCol).bVisible) Then
m_bDirty = True
Draw
End If
End If
End Property
Public Property Get ColumnVisible(ByVal vKey As Variant) As Boolean
Attribute ColumnVisible.VB_Description = "Gets/sets whether a column will be
visible or not in the grid."
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
ColumnVisible = m_tCols(lCol).bVisible
End If
End Property
Public Property Let ColumnVisible(ByVal vKey As Variant, ByVal bState As
Boolean)
Dim lCol As Long
lCol = ColumnIndex(vKey)
If (lCol > 0) Then
If (bState <> m_tCols(lCol).bVisible) Then
m_tCols(lCol).bVisible = bState
If Not bState Then
m_tCols(lCol).lHeadercolIndex = 0
End If
If (lCol <> m_iRowTextCol) Then
ColumnWidth(m_tCols(lCol).lCellColIndex) = m_tCols(lCol).lWidth
SetHeaders
m_bDirty = True
Draw
End If
End If
End If
End Property
Public Property Get Columns() As Long
Attribute Columns.VB_Description = "Gets the number of columns in the grid,
including hidden and RowText columns."
Columns = m_iCols
End Property
Public Property Get Rows() As Long
Attribute Rows.VB_Description = "Gets/sets the number of rows in the grid."
Rows = m_iRows
End Property
Public Property Let Rows(ByVal lRows As Long)
Dim lStartRow As Long
Dim lRow As Long
Dim iCol As Long
If (lRows > 0) Then
If (m_iCols = 0) Then
Err.Raise 9, App.EXEName & ".vbalGrid", "Attempt to add rows with no
columns."
Else
ReDim Preserve m_tCells(1 To m_iCols, 1 To lRows) As tGridCell
If (lRows > m_iRows) Then
lStartRow = m_iRows + 1
RowHeight(lRows) = m_lDefaultRowHeight
For iCol = 1 To m_iCols
For lRow = lStartRow To lRows
pInitCell lRow, iCol
Next lRow
Next iCol
Else
ReDim Preserve m_tRows(0 To lRows) As tRowPosition
m_iRows = lRows
If (m_iLastSelRow > m_iRows) Then
m_iLastSelRow = m_iRows
End If
End If
m_bDirty = True
Draw
End If
Else
Err.Raise 9, App.EXEName & ".vbalGrid", "Row subscript out of range"
End If
End Property
Public Sub AddRow( _
Optional ByVal lRowBefore As Long = -1, _
Optional ByVal sKey As String, _
Optional ByVal bVisible As Boolean = True, _
Optional ByVal lHeight As Long = -1, _
Optional ByVal bGroupRow As Boolean = False, _
Optional ByVal lGroupColStartIndex As Long = 0 _
)
Attribute AddRow.VB_Description = "Adds or inserts a row to the grid."
Dim iRow As Long
Dim iCol As Long
Dim lOffset As Long
Dim lStartY As Long
Dim bSelDone As Boolean
If (lHeight < 0) Then
lHeight = m_lDefaultRowHeight
End If
If (lRowBefore > 0) And (m_iRows > 0) Then
' Inserting a row:
m_iRows = m_iRows + 1
If (bVisible) Then
lOffset = lHeight
End If
lStartY = m_tRows(lRowBefore).lStartY
ReDim Preserve m_tRows(0 To m_iRows) As tRowPosition
ReDim Preserve m_tCells(1 To m_iCols, 1 To m_iRows) As tGridCell
For iRow = m_iRows - 1 To lRowBefore Step -1
LSet m_tRows(iRow + 1) = m_tRows(iRow)
m_tRows(iRow + 1).lStartY = m_tRows(iRow + 1).lStartY + lOffset
For iCol = 1 To m_iCols
LSet m_tCells(iCol, iRow + 1) = m_tCells(iCol, iRow)
Next iCol
Next iRow
With m_tRows(lRowBefore)
.sKey = sKey
.bGroupRow = bGroupRow
.lGroupStartColIndex = lGroupColStartIndex
.bVisible = bVisible
.lHeight = lHeight
.lStartY = lStartY
End With
For iCol = 1 To m_iCols
pInitCell lRowBefore, iCol
If Not (bSelDone) Then
If m_tCells(iCol, lRowBefore + 1).bSelected Then
If Not (m_bMultiSelect) Then
m_iSelRow = lRowBefore + 1
m_iSelCol = iCol
pSingleModeSelect
End If
bSelDone = True
End If
End If
Next iCol
Else
' Add row to end:
m_iRows = m_iRows + 1
ReDim Preserve m_tRows(0 To m_iRows) As tRowPosition
ReDim Preserve m_tCells(1 To m_iCols, 1 To m_iRows) As tGridCell
With m_tRows(m_iRows)
.sKey = sKey
.bGroupRow = bGroupRow
.lGroupStartColIndex = lGroupColStartIndex
.bVisible = bVisible
.lHeight = lHeight
If (m_iRows > 1) Then
.lStartY = m_tRows(m_iRows - 1).lStartY - (m_tRows(m_iRows -
1).bVisible * m_tRows(m_iRows - 1).lHeight)
Else
.lStartY = 0
End If
End With
For iCol = 1 To m_iCols
pInitCell m_iRows, iCol
Next iCol
End If
If (lHeight > m_lMaxRowHeight) Then
BuildMemDC lHeight
End If
m_bDirty = True
Draw
End Sub
Private Sub pInitCell( _
ByVal lRow As Long, _
ByVal lCol As Long _
)
LSet m_tCells(lCol, lRow) = m_tDefaultCell
End Sub
Public Sub RemoveRow( _
ByVal lRow As Long _
)
Attribute RemoveRow.VB_Description = "Deletes a row from the grid."
Dim iRow As Long
Dim iCol As Long
Dim lOffset As Long
If (m_iRows = 1) Then
' Clear grid:
Clear False
Else
' Remove this row:
If (lRow = m_iRows) Then
' Last row:
m_iRows = m_iRows - 1
ReDim Preserve m_tRows(0 To m_iRows) As tRowPosition
ReDim Preserve m_tCells(1 To m_iCols, 1 To m_iRows) As tGridCell
m_bDirty = True
Draw
Else
If (m_tRows(lRow).bVisible) Then
lOffset = m_tRows(lRow).lHeight
End If
' Have to shift rows:
For iRow = lRow + 1 To m_iRows
LSet m_tRows(iRow - 1) = m_tRows(iRow)
m_tRows(iRow - 1).lStartY = m_tRows(iRow - 1).lStartY - lOffset
For iCol = 1 To m_iCols
LSet m_tCells(iCol, iRow - 1) = m_tCells(iCol, iRow)
Next iCol
Next iRow
If m_iSelRow = lRow Then
pSingleModeSelect
End If
m_iRows = m_iRows - 1
ReDim Preserve m_tRows(0 To m_iRows) As tRowPosition
ReDim Preserve m_tCells(1 To m_iCols, 1 To m_iRows) As tGridCell
m_bDirty = True
Draw
End If
End If
End Sub
Public Property Get RowVisible(ByVal lRow As Long) As Boolean
Attribute RowVisible.VB_Description = "Gets/sets whether a row is visible in
the grid or not."
If (lRow > 0) And (lRow <= m_iRows) Then
RowVisible = m_tRows(lRow).bVisible
Else
Err.Raise 9, App.EXEName, "Invalid Row Subscript"
End If
End Property
Public Property Let RowVisible(ByVal lRow As Long, ByVal bState As Boolean)
Dim lStartY As Long
Dim lCalcRow As Long
If (lRow > 0) And (lRow <= m_iRows) Then
m_tRows(lRow).bVisible = bState
lStartY = m_tRows(lRow).lStartY
' Re-evaluate row sizes:
For lCalcRow = lRow + 1 To m_iRows
If (m_tRows(lCalcRow - 1).bVisible) Then
lStartY = lStartY + m_tRows(lCalcRow - 1).lHeight
End If
m_tRows(lCalcRow).lStartY = lStartY
Next lCalcRow
m_bDirty = True
Draw
Else
Err.Raise 9, App.EXEName, "Invalid Row Subscript"
End If
End Property
Public Sub Clear(Optional ByVal bRemoveCols As Boolean = False)
Attribute Clear.VB_Description = "Clears the rows from the grid, optionally
removing the columns too."
Erase m_tCells
ReDim m_tRow(0 To 0) As tRowPosition
m_iRows = 0
If (bRemoveCols) Then
' 19/10/99: (7)
ReDim m_tCols(0 To 0) As tColPosition
m_iCols = 0
m_iRowTextCol = 0
m_lRowTextStartCol = 0
m_bHasRowText = False
End If
m_iSelRow = 0
m_iSelCol = 0
m_iLastSelRow = 0
m_iLastSelCol = 0
m_bDirty = True
m_bInVirtualRequest = m_bIsVirtual
m_cScroll.Value(efsVertical) = 0
m_cScroll.Value(efsHorizontal) = 0
Draw
End Sub
Public Property Get BorderStyle() As ECGBorderStyle
Attribute BorderStyle.VB_Description = "Gets/sets the border style for the
control."
Attribute BorderStyle.VB_ProcData.VB_Invoke_Property = ";Appearance"
Attribute BorderStyle.VB_UserMemId = -504
BorderStyle = m_eBorderStyle
End Property
Public Property Let BorderStyle(ByVal eStyle As ECGBorderStyle)
Dim lStyle As Long
m_eBorderStyle = eStyle
If (eStyle = ecgBorderStyleNone) Then
UserControl.BorderStyle() = 0
Else
UserControl.BorderStyle() = 1
lStyle = GetWindowLong(UserControl.hwnd, GWL_EXSTYLE)
If (eStyle = ecgBorderStyle3dThin) Then
lStyle = lStyle And Not WS_EX_CLIENTEDGE Or WS_EX_STATICEDGE
Else
lStyle = lStyle Or WS_EX_CLIENTEDGE And Not WS_EX_STATICEDGE
End If
SetWindowLong UserControl.hwnd, GWL_EXSTYLE, lStyle
SetWindowPos UserControl.hwnd, 0, 0, 0, 0, 0, SWP_NOACTIVATE Or
SWP_NOZORDER Or SWP_FRAMECHANGED Or SWP_NOSIZE Or SWP_NOMOVE
End If
PropertyChanged "BorderStyle"
End Property
Private Sub pScrollSetDirty(ByVal bNoOptimise As Boolean)
Dim iStartX As Long, iEndX As Long, iStartY As Long, iEndY As Long
Dim iStartRow As Long, iEndRow As Long
Dim iStartCol As Long, iEndCol As Long
Dim iRow As Long, iCol As Long
Dim iRowCount As Long
Dim iH As Long, iV As Long
Static s_iLastStartRow As Long, s_iLastEndRow As Long
Static s_iLastStartCol As Long, s_iLastEndCol As Long
Static s_iLastH As Long, s_iLastV As Long
Dim iToDirtyX As Long, iToDirtyY As Long
Dim iXStart As Long, iXEnd As Long
Dim iYStart As Long, iYEnd As Long
Dim tSR As RECT, tR As RECT, tJunk As RECT
'm_bDirty = True
'Exit Sub
If (m_iRows = 0) Or (m_iCols = 0) Then
Exit Sub
End If
GetStartEndCell iStartRow, iStartCol, iStartX, iStartY, iEndRow, iEndCol,
iEndX, iEndY
iStartRow = iStartRow - 1
If (iStartRow < 1) Then iStartRow = 1
If (m_cScroll.Visible(efsHorizontal)) Then
iH = m_cScroll.Value(efsHorizontal)
End If
If (m_cScroll.Visible(efsVertical)) Then
iV = m_cScroll.Value(efsVertical)
End If
'Debug.Print s_iLastStartRow - iStartRow, s_iLastEndRow - iEndRow,
s_iLastStartCol - iStartCol, s_iLastEndCol - iEndCol, s_iLastH - iH,
s_iLastV - iV
iToDirtyY = Abs(s_iLastStartRow - iStartRow) + 1
If (Abs(s_iLastEndRow - iEndRow) + 1) > iToDirtyY Then
iToDirtyY = (Abs(s_iLastEndRow - iEndRow) + 1)
End If
iToDirtyX = Abs(s_iLastStartCol - iStartCol) + 1
If (Abs(s_iLastEndCol - iEndCol) + 1) > iToDirtyX Then
iToDirtyX = (Abs(s_iLastEndCol - iEndCol) + 1)
End If
bNoOptimise = bNoOptimise Or m_bNoOptimiseScroll
If (m_bBitmap) Then
' Can't optimise with a background bitmap as it has to stay in place:
bNoOptimise = True
End If
If Not (bNoOptimise) Then
'GetClientRect UserControl.hwnd, tR
tR.Top = 0: tR.Bottom = 0: tR.Right = UserControl.ScaleWidth \
Screen.TwipsPerPixelX: tR.Bottom = UserControl.ScaleHeight \
Screen.TwipsPerPixelY
tR.Top = tR.Top + m_cHeader.Height * Abs(m_bHeader)
If (Abs(s_iLastH - iH) < (tR.Right - tR.Left) \ 2) And (Abs(s_iLastV -
iV) < (tR.Bottom - tR.Top) \ 2) Then
' We can optimise using ScrollDC:
'Debug.Print "Optimise!", iToDirtyX, iToDirtyY
LSet tSR = tR
If (Abs(s_iLastH - iH) > 0) Then
' scrolling in X:
iYStart = iStartRow
iYEnd = iEndRow
If Sgn(s_iLastH - iH) = -1 Then
iXStart = iEndCol - iToDirtyX
iXEnd = iEndCol
tSR.Left = tSR.Left - (s_iLastH - iH)
Else
iXStart = iStartCol
iXEnd = iStartCol + iToDirtyX
tSR.Right = tSR.Right - (s_iLastH - iH)
End If
Else
' scrolling in Y
iXStart = iStartCol
iXEnd = iEndCol
If Sgn(s_iLastV - iV) = -1 Then
iYStart = iEndRow
iRowCount = 0
Do While iRowCount < iToDirtyY
iYStart = iYStart - 1
If iYStart < 1 Then
Exit Do
Else
If m_tRows(iYStart).bVisible Then
iRowCount = iRowCount + 1
End If
End If
Loop
If (iYStart < 1) Then iYStart = 1
iYEnd = iEndRow
tSR.Top = tSR.Top - (s_iLastV - iV)
Else
iYStart = iStartRow
iYEnd = iStartRow
iRowCount = 0
Do While iRowCount < iToDirtyY
iYEnd = iYEnd + 1
If iYEnd > m_iRows Then
Exit Do
Else
If m_tRows(iYEnd).bVisible Then
iRowCount = iRowCount + 1
End If
End If
Loop
tSR.Bottom = tSR.Bottom - (s_iLastV - iV)
End If
End If
If (iXStart < 1) Then iXStart = 1
If (iYStart < 1) Then iYStart = 1
If (iXEnd > m_iCols) Then iXEnd = m_iCols
If (iYEnd > m_iRows) Then iYEnd = m_iRows
ScrollDC UserControl.hdc, s_iLastH - iH, s_iLastV - iV, tSR, tR, 0,
tJunk
For iRow = iYStart To iYEnd
For iCol = iXStart To iXEnd
m_tCells(iCol, iRow).bDirtyFlag = True
Next iCol
Next iRow
Else
bNoOptimise = True
End If
End If
If (bNoOptimise) Then
For iRow = iStartRow To iEndRow
For iCol = iStartCol To iEndCol
m_tCells(iCol, iRow).bDirtyFlag = True
Next iCol
Next iRow
End If
s_iLastStartRow = iStartRow
s_iLastEndRow = iEndRow
s_iLastStartCol = iStartCol
s_iLastEndCol = iEndCol
If (m_cScroll.Visible(efsHorizontal)) Then
s_iLastH = m_cScroll.Value(efsHorizontal)
Else
s_iLastH = 0
End If
If (m_cScroll.Visible(efsVertical)) Then
s_iLastV = m_cScroll.Value(efsVertical)
Else
s_iLastV = 0
End If
End Sub
Private Sub pResizeHeader()
Dim lWidth As Long
Dim lLeft As Long
If (m_bHeader) Then
If Not (m_cScroll Is Nothing) Then
lWidth = UserControl.ScaleWidth \ Screen.TwipsPerPixelX +
m_cScroll.Max(efsHorizontal)
If (m_cScroll.Visible(efsHorizontal)) Then
lLeft = -m_cScroll.Value(efsHorizontal)
Else
lLeft = 0
End If
'Debug.Print lLeft, lWidth, m_cScroll.Max(efsHorizontal),
m_cScroll.Value(efsHorizontal)
Else
lWidth = UserControl.ScaleWidth \ Screen.TwipsPerPixelX
lLeft = 0
End If
m_cHeader.Move lLeft, 0, lWidth, m_cHeader.Height
End If
End Sub
Private Sub pRequestEdit(Optional ByVal iKeyAscii As Integer = 0)
Dim iRow As Long
Dim iCol As Long
Dim iNextROw As Long
Dim sOrigSearch As String
If (m_bEnabled) Then
If (m_iSelRow <> 0) And (m_iSelCol <> 0) Then
If (m_bEditable) Then
m_bInEdit = True
RaiseEvent RequestEdit(m_iSelRow, m_iSelCol, iKeyAscii, m_bInEdit)
Else
If (iKeyAscii <> 0) Then
' Search in the search col for the item:
If (m_iSearchCol > 0) Then
sOrigSearch = m_sSearchString
If (iKeyAscii = 8) Then
If Len(m_sSearchString) > 0 Then
If (Len(m_sSearchString) = 1) Then
m_sSearchString = ""
Else
m_sSearchString = Left$(m_sSearchString,
Len(m_sSearchString) - 1)
End If
End If
Else
m_sSearchString = m_sSearchString & Chr$(iKeyAscii)
End If
m_sSearchString = UCase$(m_sSearchString)
If Len(m_sSearchString) > 0 Then
iRow = FindSearchMatchRow(m_sSearchString)
If (iRow = 0) Then
m_sSearchString = sOrigSearch
iNextROw = FindSearchMatchRow(m_sSearchString)
If (iNextROw <> iRow) Then
iRow = iNextROw
End If
End If
'Debug.Print m_sSearchString, iRow
If (iRow <> 0) Then
If (m_bMultiSelect) Then
m_iSelRow = iRow
m_iSelCol = m_iSearchCol
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (m_bRowMode) Then
m_tCells(iCol, iRow).bDirtyFlag =
(m_tCells(iCol, iRow).bSelected <> (iRow =
m_iSelRow))
m_tCells(iCol, iRow).bSelected = (iRow =
m_iSelRow)
Else
m_tCells(iCol, iRow).bDirtyFlag =
(m_tCells(iCol, iRow).bSelected <> ((iRow
= m_iSelRow) And (iCol = m_iSelCol)))
m_tCells(iCol, iRow).bSelected = ((iRow =
m_iSelRow) And (iCol = m_iSelCol))
End If
Next iCol
Next iRow
m_tCells(m_iSearchCol, m_iSelRow).bDirtyFlag = True
Else
m_iSelRow = iRow
m_iSelCol = m_iSearchCol
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Else
m_sSearchString = sOrigSearch
End If
End If
End If
End If
End If
End If
End If
End Sub
Public Function FindSearchMatchRow( _
ByVal sSearchString As String, _
Optional ByVal bLoop As Boolean = True, _
Optional ByVal bVisibleRowsOnly As Boolean = True _
) As Long
Attribute FindSearchMatchRow.VB_Description = "Finds the first matching row for
a given search string."
Dim iRow As Long
Dim iFindRow As Long
Dim iStart As Long
Dim sText As String
If (m_iSearchCol > 0) And (m_iSearchCol < m_iCols) Then
If (m_iSelRow = 0) Then
If (bLoop) Then
iStart = m_iSelRow + 1
Else
iStart = m_iSelRow
End If
Else
iStart = 1
End If
For iRow = iStart To m_iRows
If (m_tRows(iRow).bVisible) Or Not (bVisibleRowsOnly) Then
If Not IsMissing(m_tCells(m_iSearchCol, iRow).sText) Then
sText = UCase$(m_tCells(m_iSearchCol, iRow).sText)
If (Len(sText) >= Len(sSearchString)) Then
If (InStr(sText, sSearchString) = 1) Then
iFindRow = iRow
Exit For
End If
End If
End If
End If
Next iRow
If (iFindRow = 0) Then
If (bLoop) Then
For iRow = 1 To iStart
If (m_tRows(iRow).bVisible) Or Not (bVisibleRowsOnly) Then
If Not IsMissing(m_tCells(m_iSearchCol, iRow).sText) Then
sText = UCase$(m_tCells(m_iSearchCol, iRow).sText)
If (Len(sText) >= Len(sSearchString)) Then
If (InStr(sText, sSearchString) = 1) Then
iFindRow = iRow
Exit For
End If
End If
End If
End If
Next iRow
End If
End If
FindSearchMatchRow = iFindRow
End If
End Function
Public Sub CancelEdit()
Attribute CancelEdit.VB_Description = "Call to cancel an edit request when the
control you are using to edit a cell looses focus."
If (m_bInEdit) Then
RaiseEvent CancelEdit
m_bInEdit = False
End If
End Sub
Private Sub pSingleModeSelect()
Dim iCol As Long
If (m_iRows = 0) Or (m_iCols = 0) Then
Exit Sub
End If
If (m_iSelRow <= 0) Then
m_iSelRow = 1
End If
If (m_iSelCol <= 0) Then
m_iSelCol = 1
End If
If (m_bRowMode) Then
For iCol = 1 To m_iCols
If (m_iLastSelRow <> 0) Then
If (m_iLastSelRow > m_iRows) Then
m_iLastSelRow = m_iRows
End If
m_tCells(iCol, m_iLastSelRow).bDirtyFlag = True
m_tCells(iCol, m_iLastSelRow).bSelected = False
End If
m_tCells(iCol, m_iSelRow).bDirtyFlag = True
m_tCells(iCol, m_iSelRow).bSelected = True
Next iCol
Else
If (m_iLastSelRow > 0) And (m_iLastSelCol > 0) Then
If (m_iLastSelRow > m_iRows) Then
m_iLastSelRow = m_iRows
End If
If (m_iLastSelCol > m_iCols) Then
m_iLastSelCol = m_iCols
End If
m_tCells(m_iLastSelCol, m_iLastSelRow).bDirtyFlag = True
m_tCells(m_iLastSelCol, m_iLastSelRow).bSelected = False
End If
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
m_tCells(m_iSelCol, m_iSelRow).bSelected = True
End If
End Sub
Private Sub pGetNextVisibleCell( _
ByVal cx As Long, _
ByVal cy As Long _
)
Dim i As Long
Dim iColIndex As Long
Dim iNew As Long
Dim iOrigRow As Long
Dim bCheckRowVisible As Boolean
Dim bFound As Boolean
Dim iIter As Long
Dim iRowTextCol As Long
If (cx <> 0) Then
For i = 1 To m_iCols
If m_tCols(i).lCellColIndex = m_iSelCol Then
iColIndex = i
Exit For
End If
Next i
iNew = iColIndex + cx
If (iNew > 0) And (iNew <= m_iCols) Then
If m_tRows(m_iSelRow).bGroupRow Then
iNew = 0
Else
If Not (m_bRowMode) Then
iRowTextCol = m_iRowTextCol
Else
iRowTextCol = 0
End If
Do
If m_tCols(iNew).bVisible Or iNew = iRowTextCol Then
Exit Do
Else
iNew = iNew + cx
If iNew > m_iCols Or iNew < 0 Then
Exit Do
End If
End If
Loop
End If
End If
If (iNew < 1) Then
For i = m_iCols To 1 Step -1
If m_tCols(i).bVisible Or i = iRowTextCol Then
iNew = i
iOrigRow = m_iSelRow
Do
iOrigRow = iOrigRow - 1
If Not (m_bRowMode) Then
iRowTextCol = m_iRowTextCol
Else
iRowTextCol = 0
End If
If (iOrigRow < 1) Then
Exit Do
Else
If m_tRows(iOrigRow).bVisible Then
If m_tRows(iOrigRow).bGroupRow Then
m_iSelCol = m_tCols(m_iRowTextCol).lCellColIndex
m_iSelRow = iOrigRow
Exit Do
Else
m_iSelCol = m_tCols(iNew).lCellColIndex
m_iSelRow = iOrigRow
Exit Do
End If
End If
End If
Loop
Exit For
End If
Next i
ElseIf (iNew > m_iCols) Then
For i = 1 To m_iCols
If m_tCols(i).bVisible Or i = iRowTextCol Then
iNew = i
iOrigRow = m_iSelRow
Do
iOrigRow = iOrigRow + 1
If Not (m_bRowMode) Then
iRowTextCol = m_iRowTextCol
Else
iRowTextCol = 0
End If
If (iOrigRow > m_iRows) Then
Exit Do
Else
If m_tRows(iOrigRow).bVisible Then
If m_tRows(iOrigRow).bGroupRow Then
m_iSelCol = m_tCols(m_iRowTextCol).lCellColIndex
m_iSelRow = iOrigRow
Exit Do
Else
m_iSelCol = m_tCols(iNew).lCellColIndex
m_iSelRow = iOrigRow
Exit Do
End If
End If
End If
Loop
Exit For
End If
Next i
Else
m_iSelCol = m_tCols(iNew).lCellColIndex
End If
End If
If (cy <> 0) Or (bCheckRowVisible) Then
iOrigRow = m_iSelRow
bFound = False
Do
m_iSelRow = m_iSelRow + cy
iIter = iIter + 1
If (iIter > m_iRows) Then
' No visible rows
m_iSelCol = 0: m_iSelRow = 0
Exit Sub
End If
If (m_iSelRow > m_iRows) Then
m_iSelRow = iOrigRow
Exit Sub
ElseIf (m_iSelRow < 1) Then
m_iSelRow = iOrigRow
Exit Sub
End If
If (m_tRows(m_iSelRow).bVisible) Then
If (m_tRows(m_iSelRow).bGroupRow) Then
m_iSelCol = m_iRowTextCol
ElseIf (m_iSelCol = m_iRowTextCol) Then
For i = 1 To m_iCols
If m_tCols(i).bVisible Then
m_iSelCol = m_tCols(i).lCellColIndex
Exit For
End If
Next i
End If
bFound = True
End If
Loop While Not bFound
End If
End Sub
Private Function plGetFirstVisibleRow() As Long
Dim bFound As Boolean
Dim iRow As Long
iRow = 1
Do
If (m_tRows(iRow).bVisible) Then
bFound = True
Else
iRow = iRow + 1
If (iRow > m_iRows) Then
iRow = 0
bFound = True
End If
End If
Loop While Not bFound
plGetFirstVisibleRow = iRow
End Function
Private Function plGetLastVisibleRow() As Long
Dim bFound As Boolean
Dim iRow As Long
iRow = m_iRows
Do
If (m_tRows(iRow).bVisible) Then
bFound = True
Else
iRow = iRow - 1
If (iRow < 1) Then
iRow = 0
bFound = True
End If
End If
Loop While Not bFound
plGetLastVisibleRow = iRow
End Function
Public Sub AutoWidthColumn(ByVal vKey As Variant)
Attribute AutoWidthColumn.VB_Description = "Automatically resizes a column to
accommodate the largest item."
Dim iRow As Long
Dim lWidth As Long
Dim lMaxWidth As Long
Dim lMaxTextWidth As Long
Dim iCol As Long
Dim iCCol As Long
iCol = plColumnIndex(vKey)
If (iCol > 0) Then
iCCol = m_tCols(iCol).lCellColIndex
For iRow = 1 To m_iRows
If (m_tRows(iRow).bVisible) Then
' lMaxTextWidth is an optimisation for multi-line rows
lWidth = plEvaluateTextWidth(iRow, iCCol, True, lMaxTextWidth)
If (lWidth > lMaxTextWidth) Then
lMaxTextWidth = lWidth
End If
lWidth = lWidth + m_tCells(iCCol, iRow).lIndent
lWidth = lWidth + ((m_tCells(iCCol, iRow).iIconIndex > 0) *
-m_lIconSizeX)
lWidth = lWidth + ((m_tCells(iCCol, iRow).lExtraIconIndex > 0) *
-m_lIconSizeY)
lWidth = lWidth + 4
lWidth = lWidth + m_bGridLines * -4
If (lWidth > lMaxWidth) Then
lMaxWidth = lWidth
End If
End If
Next iRow
If (lMaxWidth < 26) Then
lMaxWidth = 26
End If
ColumnWidth(iCCol) = lMaxWidth
Else
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Sub
Public Sub AutoHeightRow(ByVal lRow As Long, Optional ByVal lMinimumHeight As
Long = -1)
Attribute AutoHeightRow.VB_Description = "Automatically sets the height of a
row based on the contents of the cells."
Dim lCol As Long
Dim lHeight As Long
Dim lMaxHeight As Long
If lMinimumHeight <= 8 Then
lMinimumHeight = m_lDefaultRowHeight
If lMinimumHeight <= 8 Then
lMinimumHeight = 8
End If
End If
If (lRow > 0) And (lRow <= m_iRows) Then
For lCol = 1 To m_iCols
lHeight = EvaluateTextHeight(lRow, lCol)
If (m_tCells(lCol, lRow).iIconIndex >= 0) Then
If lHeight < m_lIconSizeY Then
lHeight = m_lIconSizeY
End If
End If
If (lHeight < lMinimumHeight) Then
lHeight = lMinimumHeight
End If
If (lHeight > lMaxHeight) Then
lMaxHeight = lHeight
End If
Next lCol
RowHeight(lRow) = lMaxHeight + Abs(m_bGridLines) * 2 + 2
Else
Err.Raise 9, App.EXEName & ".vbalGrid"
End If
End Sub
Private Sub pGetDragImageRect(ByVal lCol As Long, ByVal lWidth As Long, ByRef
tR As RECT, ByVal bFirst As Boolean)
Dim iCol As Long, iGCol As Long
Dim tp As POINTAPI
' Find start position for header column index lCol:
'Debug.Print lCol, lWidth
For iCol = 1 To m_iCols
If (m_tCols(iCol).lHeadercolIndex = lCol + 1) Then
iGCol = iCol
Exit For
End If
Next iCol
If (iGCol > 0) Then
' Add the width:
If (bFirst) Then
tR.Left = m_tCols(iGCol).lStartX + m_tCols(iCol).lWidth - 1
Else
tR.Left = m_tCols(iGCol).lStartX + lWidth - 1
End If
tR.Left = tR.Left - m_lStartX
tR.Right = tR.Left + 2
tR.Top = m_cHeader.Height
tR.Bottom = UserControl.ScaleHeight \ Screen.TwipsPerPixelY
' Return the rectangle relative to the screen:
tp.x = tR.Left: tp.y = tR.Top
ClientToScreen UserControl.hwnd, tp
tR.Left = tp.x: tR.Top = tp.y
tp.x = tR.Right: tp.y = tR.Bottom
ClientToScreen UserControl.hwnd, tp
tR.Right = tp.x: tR.Bottom = tp.y
End If
End Sub
Private Sub m_cHeader_ColumnBeginDrag(lColumn As Long)
CancelEdit
End Sub
Private Sub m_cHeader_ColumnClick(lColumn As Long)
Dim iCol As Long
CancelEdit
For iCol = 1 To m_iCols
If (m_tCols(iCol).lHeadercolIndex = lColumn + 1) Then
lColumn = m_tCols(iCol).lCellColIndex
Exit For
End If
Next iCol
RaiseEvent ColumnClick(lColumn)
End Sub
Private Sub m_cHeader_ColumnEndDrag(lColumn As Long, lOrder As Long)
Dim iCol As Long
Dim lColPosition As Long
Dim lOrderPosition As Long
Dim tSwap As tColPosition
Dim lStartX As Long
If (lOrder <> -1) Then ' Dropped off the grid...
lColumn = lColumn + 1
lOrderPosition = lOrder + 1
' Find this column in the column array:
For iCol = 1 To m_iCols
If m_tCols(iCol).bVisible Then
If (m_tCols(iCol).lHeadercolIndex = lColumn) Then
lColPosition = iCol
End If
ElseIf (lOrderPosition >= iCol) Then
lOrderPosition = lOrderPosition + 1
End If
Next iCol
If (lColPosition = lOrderPosition) Then
'Debug.Print "No Change"
Else
' Swap around til the array is correct:
If (lColPosition > lOrderPosition) Then
LSet tSwap = m_tCols(lColPosition)
For iCol = lColPosition To lOrderPosition + 1 Step -1
LSet m_tCols(iCol) = m_tCols(iCol - 1)
Next iCol
LSet m_tCols(lOrderPosition) = tSwap
Else
LSet tSwap = m_tCols(lColPosition)
For iCol = lColPosition + 1 To lOrderPosition
LSet m_tCols(iCol - 1) = m_tCols(iCol)
Next iCol
LSet m_tCols(lOrderPosition) = tSwap
End If
' Ensure positions are correct:
lStartX = 0
For iCol = 1 To m_iCols
m_tCols(iCol).lStartX = lStartX
If (m_tCols(iCol).bVisible) And (iCol <> m_iRowTextCol) Then
lStartX = lStartX + m_tCols(iCol).lWidth
End If
Next iCol
' Redraw grid:
m_bDirty = True
Draw
End If
End If
RaiseEvent ColumnOrderChanged
End Sub
Private Sub m_cHeader_ColumnWidthChanged(lColumn As Long, ByVal lWidth As Long)
Dim lCol As Long
Dim lColIndex As Long
Dim lCCol As Long
Dim tR As RECT
Dim bCancel As Boolean
DrawDragImage tR, False, True
lCCol = lColumn + 1
For lCol = 1 To m_iCols
If (m_tCols(lCol).bVisible) And (m_tCols(lCol).lHeadercolIndex = lCCol)
Then
lColIndex = m_tCols(lCol).lCellColIndex
Exit For
End If
Next lCol
'If (lWidth < 26) Then
' lWidth = 26
'End If
' 19/10/1999 (13)
RaiseEvent ColumnWidthChanged(lColumn, lWidth, bCancel)
If Not bCancel Then
ColumnWidth(lColIndex) = lWidth
m_bDirty = True
Draw
pResizeHeader
End If
End Sub
Private Sub m_cHeader_ColumnWidthChanging(lColumn As Long, ByVal lWidth As
Long, bCancel As Boolean)
Dim iCol As Long
Dim tR As RECT
pGetDragImageRect lColumn, lWidth, tR, False
For iCol = 1 To m_iCols
If (m_tCols(iCol).lHeadercolIndex = lColumn + 1) Then
lColumn = m_tCols(iCol).lCellColIndex
Exit For
End If
Next iCol
DrawDragImage tR, False, False
RaiseEvent ColumnWidthChanging(lColumn, lWidth, bCancel)
If (bCancel) Then
DrawDragImage tR, False, True
End If
End Sub
Private Sub m_cHeader_DividerDblClick(lColumn As Long)
Dim iCCol As Long
Dim iCol As Long
CancelEdit
' Autosize column here
For iCol = 1 To m_iCols
If (m_tCols(iCol).lHeadercolIndex = lColumn + 1) Then
iCCol = m_tCols(iCol).lCellColIndex
Exit For
End If
Next iCol
AutoWidthColumn iCCol
End Sub
Private Sub m_cHeader_RecreateControl()
SetHeaders
m_cHeader.SetFont UserControl.hdc, UserControl.Font
m_cHeader.SetImageList UserControl.hdc, m_hIml
End Sub
Private Sub m_cHeader_RightClick(x As Single, y As Single)
CancelEdit
RaiseEvent HeaderRightClick(x, y)
End Sub
Private Sub m_cHeader_StartColumnWidthChange(lColumn As Long, ByVal lWidth As
Long, bCancel As Boolean)
Dim tR As RECT
CancelEdit
RaiseEvent ColumnWidthStartChange(lColumn + 1, lWidth, bCancel)
If Not (bCancel) Then
pGetDragImageRect lColumn, lWidth, tR, True
DrawDragImage tR, True, False
End If
End Sub
Private Sub m_cScroll_Change(eBar As EFSScrollBarConstants)
Dim bRedraw As Boolean
CancelEdit
If (eBar = efsHorizontal) Then
m_lStartX = m_cScroll.Value(eBar)
Else
m_lStartY = m_cScroll.Value(eBar)
End If
If (eBar = efsHorizontal) Then
If (m_cHeader.Visible) Then
m_cHeader.Left = -m_cScroll.Value(efsHorizontal)
Else
m_cHeader.Left = 0
End If
End If
pScrollSetDirty False
Draw
End Sub
Private Sub m_cScroll_Scroll(eBar As EFSScrollBarConstants)
m_cScroll_Change eBar
End Sub
Private Sub UserControl_DblClick()
On Error GoTo ErrorHandler
If (m_bEnabled) Then
RaiseEvent DblClick(m_iSelRow, m_iSelCol)
If (m_iSelRow > 0) And (m_iSelCol > 0) Then
If (m_iSelRow <= m_iRows) And (m_iSelCol <= m_iCols) Then
pRequestEdit
End If
End If
End If
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_GotFocus()
On Error GoTo ErrorHandler
m_bInFocus = True
pScrollSetDirty True
Draw
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_Initialize()
debugmsg "vbalGrid:Initialize"
With m_tDefaultCell
.iIconIndex = -1
.lExtraIconIndex = -1
.oBackColor = CLR_NONE
.oForeColor = CLR_NONE
.eTextFlags = DT_SINGLELINE Or DT_WORD_ELLIPSIS Or DT_LEFT Or DT_NOPREFIX
.sText = Empty
.lIndent = 0
.bDirtyFlag = True
.bSelected = False
.lItemData = 0
End With
ReDim m_tRows(0 To 0) As tRowPosition
ReDim m_tCols(0 To 0) As tColPosition
m_lDefaultColumnWidth = 64
m_lDefaultRowHeight = 20
m_oGridLineColor = vbButtonFace
m_oHighlightBackColor = vbHighlight ' 19/10/1999 (8)
m_oHighlightForeColor = vbHighlightText
m_bAllowVert = True
m_bAllowHorz = True
m_eBorderStyle = ecgBorderStyle3d
m_bRedraw = True
m_bDrawFocusRectangle = True
m_bDisableIcons = True
m_bHighlightSelectedIcons = True
End Sub
Private Sub UserControl_InitProperties()
pCreateHeader
BackColor = vbWindowBackground
ForeColor = vbWindowText
Set Font = Ambient.Font
BorderStyle = ecgBorderStyle3d
Header = True
Enabled = True
End Sub
Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer)
Dim iRow As Long, iCol As Long
Dim iInitSelCOl As Long, iInitSelRow As Long
Dim lNextPage As Long
Dim bFound As Boolean
Dim iSelRow As Long
Dim bSingleGroupRowScroll As Boolean
Dim bDoDefault As Boolean
On Error GoTo ErrorHandler
If (KeyCode = vbKeyTab) Then
If (Shift And vbShiftMask) = vbShiftMask Then
If (m_bRowMode) Then
KeyCode = vbKeyUp
Else
KeyCode = vbKeyLeft
End If
Else
If (m_bRowMode) Then
KeyCode = vbKeyDown
Else
KeyCode = vbKeyRight
End If
End If
End If
If Not (m_bEnabled) Then
Select Case KeyCode
Case vbKeyUp
If (m_cScroll.Visible(efsVertical)) Then
m_cScroll.Value(efsVertical) = m_cScroll.Value(efsVertical) -
m_cScroll.SmallChange(efsVertical)
End If
Case vbKeyDown
If (m_cScroll.Visible(efsVertical)) Then
m_cScroll.Value(efsVertical) = m_cScroll.Value(efsVertical) +
m_cScroll.SmallChange(efsVertical)
End If
Case vbKeyLeft
If (m_cScroll.Visible(efsHorizontal)) Then
m_cScroll.Value(efsHorizontal) = m_cScroll.Value(efsHorizontal) -
m_cScroll.SmallChange(efsHorizontal)
End If
Case vbKeyRight
If (m_cScroll.Visible(efsHorizontal)) Then
m_cScroll.Value(efsHorizontal) = m_cScroll.Value(efsHorizontal) +
m_cScroll.SmallChange(efsHorizontal)
End If
Case vbKeyPageUp
If (m_cScroll.Visible(efsVertical)) Then
m_cScroll.Value(efsVertical) = m_cScroll.Value(efsVertical) -
m_cScroll.LargeChange(efsVertical)
End If
Case vbKeyPageDown
If (m_cScroll.Visible(efsVertical)) Then
m_cScroll.Value(efsVertical) = m_cScroll.Value(efsVertical) +
m_cScroll.LargeChange(efsVertical)
End If
End Select
Exit Sub
End If
If m_iRows > 0 And m_iCols > 0 Then
bDoDefault = True
End If
RaiseEvent KeyDown(KeyCode, Shift, bDoDefault)
If (bDoDefault) Then
'
If (m_iRows = 0) Or (m_iCols = 0) Then
Exit Sub
End If
If m_iSelRow <= 0 Or m_iSelRow <= 0 Then
Exit Sub
End If
If (KeyCode = vbKeyLeft Or KeyCode = vbKeyRight) And Shift = 0 Then
If (m_tRows(m_iSelRow).bGroupRow) Then
If m_cScroll.Visible(efsHorizontal) Then
If KeyCode = vbKeyLeft Then
If m_cScroll.Value(efsHorizontal) <> 0 Then
bSingleGroupRowScroll = True
End If
Else
If m_cScroll.Value(efsHorizontal) <>
m_cScroll.Max(efsHorizontal) Then
bSingleGroupRowScroll = True
End If
End If
End If
End If
End If
iInitSelCOl = m_iSelCol
iInitSelRow = m_iSelRow
Select Case KeyCode
Case vbKeySpace
If (Shift And vbCtrlMask) = vbCtrlMask Then
If (m_bMultiSelect) Then
' Select/deselect this cell
If (m_bRowMode) Then
For iCol = 1 To m_iCols
m_tCells(iCol, m_iSelRow).bSelected = Not (m_tCells(iCol,
m_iSelRow).bSelected)
m_tCells(iCol, m_iSelRow).bDirtyFlag = True
Next iCol
Else
m_tCells(m_iSelCol, m_iSelRow).bSelected = Not
(m_tCells(m_iSelCol, m_iSelRow).bSelected)
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
End If
Draw
pRequestEdit
End If
End If
Case vbKeyLeft
m_sSearchString = ""
If (m_bRowMode) Or bSingleGroupRowScroll Then
' Equivalent to scrolling left
m_cScroll.Value(efsHorizontal) = m_cScroll.Value(efsHorizontal) -
m_cScroll.SmallChange(efsHorizontal)
Else
pGetNextVisibleCell -1, 0
If (m_bMultiSelect) Then
If (Shift And vbShiftMask) = vbShiftMask Then
' Add this cell to the selection:
m_tCells(m_iSelCol, m_iSelRow).bSelected = Not
(m_tCells(m_iSelCol, m_iSelRow).bSelected)
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift And vbCtrlMask) = vbCtrlMask Then
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift = 0) Then
' This is the selected cell:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = (((iRow = m_iSelRow)
And (iCol = m_iSelCol)) <> m_tCells(iCol,
iRow).bSelected)
m_tCells(iCol, iRow).bSelected = ((iRow = m_iSelRow)
And (iCol = m_iSelCol))
Next iCol
Next iRow
End If
Else
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
End If
Case vbKeyRight
m_sSearchString = ""
If (m_bRowMode) Or bSingleGroupRowScroll Then
' Equivalent to scrolling right
m_cScroll.Value(efsHorizontal) = m_cScroll.Value(efsHorizontal) +
m_cScroll.SmallChange(efsHorizontal)
Else
pGetNextVisibleCell 1, 0
If (m_bMultiSelect) Then
If (Shift And vbShiftMask) = vbShiftMask Then
' Add this cell to the selection:
m_tCells(m_iSelCol, m_iSelRow).bSelected = Not
(m_tCells(m_iSelCol, m_iSelRow).bSelected)
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift And vbCtrlMask) = vbCtrlMask Then
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift = 0) Then
' This is the selected cell:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = (((iRow = m_iSelRow)
And (iCol = m_iSelCol)) <> m_tCells(iCol,
iRow).bSelected)
m_tCells(iCol, iRow).bSelected = ((iRow = m_iSelRow)
And (iCol = m_iSelCol))
Next iCol
Next iRow
End If
Else
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
End If
Case vbKeyUp
' Move selection up if there is one, otherwise scroll:
m_sSearchString = ""
If (m_iSelRow <> 0) Then
If (m_iSelRow > 1) Then
pGetNextVisibleCell 0, -1
If (m_bMultiSelect) Then
If (m_bRowMode) Then
If (Shift And vbShiftMask) = vbShiftMask Then
' Add this row to the selection:
For iCol = 1 To m_iCols
m_tCells(iCol, m_iSelRow).bSelected = Not
(m_tCells(iCol, m_iSelRow).bSelected)
m_tCells(iCol, m_iSelRow).bDirtyFlag = True
Next iCol
ElseIf (Shift And vbCtrlMask) = vbCtrlMask Then
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift = 0) Then
' Switch selected row to current:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = ((iRow =
m_iSelRow) <> m_tCells(iCol, iRow).bSelected)
m_tCells(iCol, iRow).bSelected = (iRow =
m_iSelRow)
Next iCol
Next iRow
End If
Else
If (Shift And vbShiftMask) = vbShiftMask Then
' Add/remove this cell from the selection:
m_tCells(m_iSelCol, m_iSelRow).bSelected = Not
(m_tCells(m_iSelCol, m_iSelRow).bSelected)
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift And vbCtrlMask) = vbCtrlMask Then
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift = 0) Then
' Switch selected cell to current:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = (((iRow =
m_iSelRow) And (iCol = m_iSelCol)) <>
m_tCells(iCol, iRow).bSelected)
m_tCells(iCol, iRow).bSelected = ((iRow =
m_iSelRow) And (iCol = m_iSelCol))
Next iCol
Next iRow
End If
End If
Else
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
End If
Else
m_cScroll.Value(efsVertical) = m_cScroll.Value(efsVertical) -
m_cScroll.SmallChange(efsVertical)
End If
Case vbKeyDown
' Move selection up if there is one, otherwise scroll:
m_sSearchString = ""
If (m_iSelRow <> 0) Then
If (m_iSelRow < m_iRows) Then
pGetNextVisibleCell 0, 1
If (m_bMultiSelect) Then
If (m_bRowMode) Then
If (Shift And vbShiftMask) = vbShiftMask Then
' Add this row to the selection:
For iCol = 1 To m_iCols
m_tCells(iCol, m_iSelRow).bSelected = Not
(m_tCells(iCol, m_iSelRow).bSelected)
m_tCells(iCol, m_iSelRow).bDirtyFlag = True
Next iCol
ElseIf (Shift And vbCtrlMask) = vbCtrlMask Then
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift = 0) Then
' Switch selected row to current:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = ((iRow =
m_iSelRow) <> m_tCells(iCol, iRow).bSelected)
m_tCells(iCol, iRow).bSelected = (iRow =
m_iSelRow)
Next iCol
Next iRow
End If
Else
If (Shift And vbShiftMask) = vbShiftMask Then
' Add/remove this cell from the selection:
m_tCells(m_iSelCol, m_iSelRow).bSelected = Not
(m_tCells(m_iSelCol, m_iSelRow).bSelected)
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift And vbCtrlMask) = vbCtrlMask Then
m_tCells(m_iSelCol, m_iSelRow).bDirtyFlag = True
ElseIf (Shift = 0) Then
' Switch selected cell to current:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected <> ((iRow = m_iSelRow) And (iCol
= m_iSelCol)))
m_tCells(iCol, iRow).bSelected = ((iRow =
m_iSelRow) And (iCol = m_iSelCol))
Next iCol
Next iRow
End If
End If
Else
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
End If
Else
m_cScroll.Value(efsVertical) = m_cScroll.Value(efsVertical) -
m_cScroll.SmallChange(efsVertical)
End If
Case vbKeyPageUp
' Move up by the equivalent of one page:
m_sSearchString = ""
iRow = m_iSelRow
lNextPage = m_tRows(iRow).lStartY - m_lAvailheight +
m_tRows(iRow).lHeight
Do
iRow = iRow - 1
If (iRow < 1) Then
iRow = plGetFirstVisibleRow()
bFound = True
Else
If (m_tRows(iRow).bVisible) Then
If (m_tRows(iRow).lStartY < lNextPage) Then
bFound = True
End If
End If
End If
Loop While Not bFound
If (m_bMultiSelect) Then
iSelRow = iRow
If (Shift And vbShiftMask) = vbShiftMask Then
' Toggle everything between m_iSelRow and iRow to the selection
If (m_bRowMode) Then
For iRow = m_iSelRow - 1 To iRow Step -1
For iCol = 1 To m_iCols
m_tCells(m_iSelCol, iRow).bDirtyFlag = True
m_tCells(iCol, iRow).bSelected = Not (m_tCells(iCol,
iRow).bSelected)
Next iCol
Next iRow
Else
For iRow = m_iSelRow - 1 To iRow Step -1
m_tCells(m_iSelCol, iRow).bDirtyFlag = True
m_tCells(m_iSelCol, iRow).bSelected = Not
(m_tCells(m_iSelCol, iRow).bSelected)
Next iRow
End If
ElseIf (Shift And vbCtrlMask) = vbCtrlMask Then
Else
If (m_bRowMode) Then
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected <> (iRow = iSelRow))
m_tCells(iCol, iRow).bSelected = (iRow = iSelRow)
Next iCol
Next iRow
Else
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected <> ((iRow = iSelRow) And (iCol =
m_iSelCol)))
m_tCells(iCol, iRow).bSelected = ((iRow = iSelRow) And
(iCol = m_iSelCol))
Next iCol
Next iRow
End If
End If
m_iSelRow = iSelRow
Else
m_iSelRow = iRow
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Case vbKeyPageDown
m_sSearchString = ""
' Move down by the equivalent of one page:
iRow = m_iSelRow
lNextPage = m_tRows(iRow).lStartY + m_lAvailheight -
m_tRows(iRow).lHeight
Do
iRow = iRow + 1
If (iRow > m_iRows) Then
iRow = plGetLastVisibleRow()
bFound = True
End If
If (m_tRows(iRow).bVisible) Then
If (m_tRows(iRow).lStartY > lNextPage) Then
bFound = True
End If
End If
Loop While Not bFound
If (m_bMultiSelect) Then
iSelRow = iRow
If (Shift And vbShiftMask) = vbShiftMask Then
' Toggle everything between m_iSelRow and iRow to the selection
If (m_bRowMode) Then
For iRow = m_iSelRow + 1 To iRow
For iCol = 1 To m_iCols
m_tCells(m_iSelCol, iRow).bDirtyFlag = True
m_tCells(iCol, iRow).bSelected = Not (m_tCells(iCol,
iRow).bSelected)
Next iCol
Next iRow
Else
For iRow = m_iSelRow + 1 To iRow
m_tCells(m_iSelCol, iRow).bDirtyFlag = True
m_tCells(m_iSelCol, iRow).bSelected = Not
(m_tCells(m_iSelCol, iRow).bSelected)
Next iRow
End If
ElseIf (Shift And vbCtrlMask) = vbCtrlMask Then
ElseIf (Shift = 0) Then
If (m_bRowMode) Then
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected <> (iRow = iSelRow))
m_tCells(iCol, iRow).bSelected = (iRow = iSelRow)
Next iCol
Next iRow
Else
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected <> ((iRow = iSelRow) And (iCol =
m_iSelCol)))
m_tCells(iCol, iRow).bSelected = ((iRow = iSelRow) And
(iCol = m_iSelCol))
Next iCol
Next iRow
End If
End If
m_iSelRow = iSelRow
Else
m_iSelRow = iRow
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Case vbKeyHome
m_sSearchString = ""
m_iSelRow = plGetFirstVisibleRow()
If (m_bMultiSelect) Then
If (Shift And vbShiftMask) = vbShiftMask Then
For iRow = m_iSelRow To 1 Step -1
If m_bRowMode Then
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = True
m_tCells(iCol, iRow).bSelected = Not (m_tCells(iCol,
iRow).bSelected)
Next iCol
Else
For iCol = 1 To m_iSelCol
m_tCells(iCol, iRow).bDirtyFlag = True
m_tCells(iCol, iRow).bSelected = Not (m_tCells(iCol,
iRow).bSelected)
Next iCol
End If
Next iRow
Else
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (m_bRowMode) Then
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected = (iRow = m_iSelRow))
m_tCells(iCol, iRow).bSelected = (iRow = m_iSelRow)
Else
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected = ((iRow = m_iSelRow) And (iCol =
m_iSelCol)))
m_tCells(iCol, iRow).bSelected = ((iRow = m_iSelRow)
And (iCol = m_iSelCol))
End If
Next iCol
Next iRow
End If
Else
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Case vbKeyEnd
m_sSearchString = ""
m_iSelRow = plGetLastVisibleRow()
If (m_bMultiSelect) Then
If (Shift And vbShiftMask) = vbShiftMask Then
For iRow = m_iSelRow To m_iRows
If m_bRowMode Then
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = True
m_tCells(iCol, iRow).bSelected = Not (m_tCells(iCol,
iRow).bSelected)
Next iCol
Else
For iCol = 1 To m_iSelCol
m_tCells(iCol, iRow).bDirtyFlag = True
m_tCells(iCol, iRow).bSelected = Not (m_tCells(iCol,
iRow).bSelected)
Next iCol
End If
Next iRow
Else
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (m_bRowMode) Then
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected = (iRow = m_iSelRow))
m_tCells(iCol, iRow).bSelected = (iRow = m_iSelRow)
Else
m_tCells(iCol, iRow).bDirtyFlag = (m_tCells(iCol,
iRow).bSelected = ((iRow = m_iSelRow) And (iCol =
m_iSelCol)))
m_tCells(iCol, iRow).bSelected = ((iRow = m_iSelRow)
And (iCol = m_iSelCol))
End If
Next iCol
Next iRow
End If
Else
pSingleModeSelect
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Case vbKeyReturn
' Equivalent to double-clicking the cell:
pRequestEdit
Case vbKeyEscape
' If in Edit then cancel editing:
m_sSearchString = ""
CancelEdit
End Select
If (iInitSelCOl <> m_iSelCol) Or (iInitSelRow <> m_iSelRow) Then
RaiseEvent SelectionChange(m_iSelRow, m_iSelCol)
End If
End If
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
Resume 0
End Sub
Private Sub UserControl_KeyPress(KeyAscii As Integer)
On Error GoTo ErrorHandler
pRequestEdit KeyAscii
RaiseEvent KeyPress(KeyAscii)
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_KeyUp(KeyCode As Integer, Shift As Integer)
On Error GoTo ErrorHandler
RaiseEvent KeyUp(KeyCode, Shift)
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_LostFocus()
On Error GoTo ErrorHandler
m_bInFocus = False
pScrollSetDirty True
Draw
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_MouseDown(Button As Integer, Shift As Integer, x As
Single, y As Single)
Dim lSelRow As Long, lSelCol As Long
Dim iRow As Long, iCol As Long
Dim iStartCol As Long, iEndCol As Long, iStartRow As Long, iEndRow As Long
Dim bS As Boolean
Dim iInitSelCOl As Long, iInitSelRow As Long
Dim bDefault As Boolean
On Error GoTo ErrorHandler
If Not (m_bEnabled) Then
Exit Sub
End If
bDefault = True
RaiseEvent MouseDown(Button, Shift, x, y, bDefault)
If (bDefault) Then
m_sSearchString = ""
m_bMouseDown = True
iInitSelCOl = m_iSelCol
iInitSelRow = m_iSelRow
CellFromPoint x \ Screen.TwipsPerPixelX, y \ Screen.TwipsPerPixelY,
lSelRow, lSelCol
If (lSelRow > 0) And (lSelCol > 0) Then
If (Shift And vbShiftMask) = vbShiftMask Then
If (m_iSelRow = 0) Or (m_iSelCol = 0) Then
m_iSelRow = lSelRow
m_iSelCol = lSelCol
End If
If (m_bMultiSelect) Then
If (lSelRow > 0) And (lSelCol > 0) Then
If (lSelRow = m_iSelRow) And (lSelCol = m_iSelCol) Then
pRequestEdit
Exit Sub
Else
' We have made a selection with shift held down.
' Select all the cells between here and the previous
selected point:
If (lSelCol > m_iSelCol) Then
If (m_bRowMode) Then
iStartCol = 1
iEndCol = m_iCols
Else
iStartCol = m_iSelCol
iEndCol = lSelCol
End If
Else
If (m_bRowMode) Then
iStartCol = 1
iEndCol = m_iCols
Else
iStartCol = lSelCol
iEndCol = m_iSelCol
End If
End If
If (lSelRow > m_iSelRow) Then
iStartRow = m_iSelRow
iEndRow = lSelRow
Else
iStartRow = lSelRow
iEndRow = m_iSelRow
End If
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (iRow >= iStartRow) And (iRow <= iEndRow) Then
If (iCol >= iStartCol) And (iCol <= iEndCol) Then
bS = True
Else
bS = False
End If
Else
bS = False
End If
m_tCells(iCol, iRow).bDirtyFlag = (bS <>
m_tCells(iCol, iRow).bSelected)
m_tCells(iCol, iRow).bSelected = bS
Next iCol
Next iRow
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Exit Sub
End If
End If
End If
Else
m_iSelRow = lSelRow
m_iSelCol = lSelCol
End If
' Select according to mode:
If (lSelRow = m_iLastSelRow) And (lSelCol = m_iLastSelCol) Then
pRequestEdit
Exit Sub
End If
If m_bMultiSelect Then
' we could be selecting entire grid:
If (m_tRows(lSelRow).bFixed) And (m_tCols(lSelCol).bFixed) Then
' Select entire grid:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
m_tCells(iCol, iRow).bDirtyFlag = True
m_tCells(iCol, iRow).bSelected = Not (m_tCells(iCol,
iRow).bSelected)
Next iCol
Next iRow
ElseIf (m_tRows(lSelRow).bFixed) Then
' Select entire col:
If (Shift And vbCtrlMask) = vbCtrlMask Then
' .. add to selection
For iRow = 1 To m_iRows
m_tCells(iCol, iRow).bDirtyFlag = True
m_tCells(lSelCol, iRow).bSelected = Not (m_tCells(lSelCol,
iRow).bSelected)
Next iRow
Else
' .. and deselect others:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (iCol = lSelCol) Then
bS = Not (m_tCells(iCol, iRow).bSelected)
Else
bS = False
End If
m_tCells(iCol, iRow).bDirtyFlag = (bS <> m_tCells(iCol,
iRow).bSelected)
m_tCells(iCol, iRow).bSelected = bS
Next iCol
Next iRow
End If
ElseIf (m_tCols(lSelCol).bFixed) Then
' Select entire row:
If (Shift And vbCtrlMask) = vbCtrlMask Then
' .. add to selection
For iCol = 1 To m_iCols
m_tCells(iCol, lSelRow).bDirtyFlag = True
m_tCells(iCol, lSelRow).bSelected = Not (m_tCells(iCol,
lSelRow).bSelected)
Next iCol
Else
' ... and deselect others:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (iRow = lSelRow) Then
bS = Not (m_tCells(iCol, iRow).bSelected)
Else
bS = False
End If
m_tCells(iCol, iRow).bDirtyFlag = (bS <> m_tCells(iCol,
iRow).bSelected)
m_tCells(iCol, iRow).bSelected = bS
Next iCol
Next iRow
End If
Else
' Select this cell or row depending on mode:
If (Shift And vbCtrlMask) = vbCtrlMask Then
If (m_bRowMode) Then
' .. add row to selection:
For iCol = 1 To m_iCols
m_tCells(iCol, lSelRow).bDirtyFlag = True
m_tCells(iCol, lSelRow).bSelected = Not (m_tCells(iCol,
lSelRow).bSelected)
Next iCol
Else
' .. add cell to selection:
m_tCells(lSelCol, lSelRow).bDirtyFlag = True
m_tCells(lSelCol, lSelRow).bSelected = Not
(m_tCells(lSelCol, lSelRow).bSelected)
End If
Else
If (m_bRowMode) Then
' .. add row to selection and remove others:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If (iRow = lSelRow) Then
m_tCells(iCol, iRow).bDirtyFlag = True
bS = True 'Not (m_tCells(iCol, iRow).bSelected)
Else
bS = False
m_tCells(iCol, iRow).bDirtyFlag = (bS <>
m_tCells(iCol, iRow).bSelected)
End If
m_tCells(iCol, iRow).bSelected = bS
Next iCol
Next iRow
Else
' .. Add cell to selection and remove others:
For iRow = 1 To m_iRows
For iCol = 1 To m_iCols
If ((iRow = lSelRow) And (iCol = lSelCol)) Then
bS = Not (m_tCells(iCol, iRow).bSelected)
Else
bS = False
End If
m_tCells(iCol, iRow).bDirtyFlag = (bS <>
m_tCells(iCol, iRow).bSelected)
m_tCells(iCol, iRow).bSelected = bS
Next iCol
Next iRow
End If
End If
End If
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
Else
pSingleModeSelect
If Not (pbEnsureVisible(m_iSelRow, m_iSelCol)) Then
Draw
End If
End If
End If
If (iInitSelCOl <> m_iSelCol) Or (iInitSelRow <> m_iSelRow) Then
RaiseEvent SelectionChange(m_iSelRow, m_iSelCol)
End If
End If
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
' The classic :)
' I thought of adding a quote mark each time I got in there but there might
be more
' quotes than code...
Resume 0
End Sub
Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, x As
Single, y As Single)
On Error GoTo ErrorHandler
If Not (m_bEnabled) Then
Exit Sub
End If
RaiseEvent MouseMove(Button, Shift, x, y)
If (Button <> 0) Then
' Drag down!
End If
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, x As
Single, y As Single)
Dim lSelRow As Long, lSelCol As Long
Dim iRow As Long, iCol As Long
Dim bS As Boolean
On Error GoTo ErrorHandler
If Not (m_bEnabled) Then
Exit Sub
End If
m_bMouseDown = False
RaiseEvent MouseUp(Button, Shift, x, y)
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_Paint()
On Error GoTo ErrorHandler
If m_bRedraw And m_bUserMode Then
pScrollSetDirty True
Draw
End If
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
pCreateHeader
If (UserControl.Ambient.UserMode) Then
m_bUserMode = True
Set m_cScroll = New cScrollBars
With m_cScroll
.Create UserControl.hwnd
.Orientation = efsoBoth
.Visible(efsHorizontal) = False
.Visible(efsVertical) = False
End With
Set m_cFlatHeader = New cFlatHeader
m_cFlatHeader.Attach hwnd
Else
m_bUserMode = False
End If
MultiSelect = PropBag.ReadProperty("MultiSelect", False)
RowMode = PropBag.ReadProperty("RowMode", False)
GridLines = PropBag.ReadProperty("GridLines", False)
Set BackgroundPicture = PropBag.ReadProperty("BackgroundPicture", Nothing)
BackgroundPictureHeight = PropBag.ReadProperty("BackgroundPictureHeight", 0)
BackgroundPictureWidth = PropBag.ReadProperty("BackgroundPictureWidth", 0)
BackColor = PropBag.ReadProperty("BackColor", vbWindowBackground)
ForeColor = PropBag.ReadProperty("ForeColor", vbWindowText)
GridLineColor = PropBag.ReadProperty("GridLineColor", vbButtonFace)
HighlightBackColor = PropBag.ReadProperty("HighlightBackColor", vbHighlight)
' 19/10/1999 (8)
HighlightForeColor = PropBag.ReadProperty("HighlightForeColor",
vbHighlightText)
Dim sFnt As New StdFont
sFnt.Name = "MS Sans Serif"
sFnt.Size = 8
Set Font = PropBag.ReadProperty("Font", sFnt)
Header = PropBag.ReadProperty("Header", True)
HeaderButtons = PropBag.ReadProperty("HeaderButtons", True)
' 19/10/1999 (9): ensure persist all header vals
HeaderDragReOrderColumns = PropBag.ReadProperty("HeaderDragReorderColumns",
True)
HeaderHotTrack = PropBag.ReadProperty("HeaderHotTrack", True)
' 19/10/1999 (10): allow to change the height of the header (may not look ok
with icons, watch it)
HeaderHeight = PropBag.ReadProperty("HeaderHeight", 20)
' 19/10/1999 (2): flat headers:
HeaderFlat = PropBag.ReadProperty("HeaderFlat", False)
BorderStyle = PropBag.ReadProperty("BorderStyle", ecgBorderStyle3d)
ScrollBarStyle = PropBag.ReadProperty("ScrollBarStyle", efsRegular)
Editable = PropBag.ReadProperty("Editable", False)
Enabled = PropBag.ReadProperty("Enabled", True)
DisableIcons = PropBag.ReadProperty("DisableIcons", False)
HighlightSelectedIcons = PropBag.ReadProperty("HighlightSelectedIcons", True)
DrawFocusRectangle = PropBag.ReadProperty("DrawFocusRectangle", True)
Virtual = PropBag.ReadProperty("Virtual", False)
DefaultRowHeight = PropBag.ReadProperty("DefaultRowHeight", 20)
UserControl_Resize
End Sub
Private Sub UserControl_Resize()
Dim lWidth As Long
On Error GoTo ErrorHandler
If m_bRedraw And m_bUserMode Then
m_bDirty = True
Draw
pResizeHeader
ElseIf Not (UserControl.Ambient.UserMode) Then
If (m_bHeader) Then
lWidth = UserControl.ScaleWidth \ Screen.TwipsPerPixelX
m_cHeader.Move 0, 0, lWidth, m_cHeader.Height
End If
End If
Exit Sub
ErrorHandler:
Debug.Assert False
Exit Sub
End Sub
Private Sub UserControl_Show()
Dim lS As Long
Static s_bNotFirst As Boolean
'
If Not (s_bNotFirst) Then
lS = GetWindowLong(UserControl.hwnd, GWL_STYLE)
lS = lS And Not (WS_HSCROLL Or WS_VSCROLL)
SetWindowLong UserControl.hwnd, GWL_STYLE, lS
SetWindowPos UserControl.hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or
SWP_NOZORDER Or SWP_FRAMECHANGED
s_bNotFirst = True
End If
End Sub
Private Sub UserControl_Terminate()
Dim iFnt As Long
Set m_cFlatHeader = Nothing
Set m_cHeader = Nothing
Set m_cScroll = Nothing
If (m_hDC <> 0) Then
If (m_hBmpOld <> 0) Then
SelectObject m_hDC, m_hBmpOld
End If
If (m_hBmp <> 0) Then
DeleteObject m_hBmp
End If
If (m_hFntOldDC <> 0) Then
SelectObject m_hDC, m_hFntOldDC
End If
DeleteDC m_hDC
m_hDC = 0
End If
If (m_hFntDC <> 0) Then
DeleteObject m_hFntDC
m_hFntDC = 0
End If
For iFnt = 1 To m_iFontCount
DeleteObject m_hFnt(iFnt)
Next iFnt
debugmsg "vbalGrid:Terminate"
End Sub
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "MultiSelect", MultiSelect, False
PropBag.WriteProperty "RowMode", RowMode, False
PropBag.WriteProperty "GridLines", GridLines, False
PropBag.WriteProperty "BackgroundPicture", BackgroundPicture, Nothing
PropBag.WriteProperty "BackgroundPictureHeight", BackgroundPictureHeight
PropBag.WriteProperty "BackgroundPictureWidth", BackgroundPictureWidth
PropBag.WriteProperty "BackColor", BackColor, vbWindowBackground
PropBag.WriteProperty "ForeColor", ForeColor, vbWindowText
PropBag.WriteProperty "GridLineColor", GridLineColor, vbButtonFace
PropBag.WriteProperty "HighlightBackColor", HighlightBackColor, vbHighlight
' 19/10/1999 (8)
PropBag.WriteProperty "HighlightForeColor", HighlightForeColor,
vbHighlightText
Dim sFnt As New StdFont
sFnt.Name = "MS Sans Serif"
sFnt.Size = 8
PropBag.WriteProperty "Font", Font, sFnt
PropBag.WriteProperty "Header", Header, True
PropBag.WriteProperty "HeaderButtons", HeaderButtons, True
' 19/10/1999 (9): ensure persist all header vals
PropBag.WriteProperty "HeaderDragReorderColumns", HeaderDragReOrderColumns,
True
PropBag.WriteProperty "HeaderHotTrack", HeaderHotTrack, True
' 19/10/1999 (10): header height:
PropBag.WriteProperty "HeaderHeight", HeaderHeight, 20
' 19/10/1999 (2): flat headers:
PropBag.WriteProperty "HeaderFlat", HeaderFlat, False
PropBag.WriteProperty "BorderStyle", BorderStyle, ecgBorderStyle3d
PropBag.WriteProperty "ScrollBarStyle", ScrollBarStyle, efsRegular
PropBag.WriteProperty "Editable", Editable, False
PropBag.WriteProperty "Enabled", Enabled, True
PropBag.WriteProperty "DisableIcons", DisableIcons, False
PropBag.WriteProperty "HighlightSelectedIcons", HighlightSelectedIcons, True
PropBag.WriteProperty "DrawFocusRectangle", DrawFocusRectangle, True
PropBag.WriteProperty "Virtual", Virtual, False
PropBag.WriteProperty "DefaultRowHeight", DefaultRowHeight, 20
End Sub
|
|