Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1448

[VB6] Extending the DataGrid Control

$
0
0
Been playing with the DataGrid control to see if it could be usable in a project of mine. It's not a bad control, just a bit under-powered.

Caveat: The code and this posting is 99% focused on using the Data Grid without bound data. In other words, how to use the control without having a database to connect to.

This control is unicode aware and has a professional appearance. It can be very useful in many cases as a simple spreadsheet or to display subsets of databases. There are a few drawbacks to using this control.

1. It requires a bound list. Unlike its older counterpart, the DBGrid which could create its own internal collection of data, this control requires a data source. However, if you are connecting to an established DB, then not much to worry about. If you want to display your own custom data (no database), you can still do that via disconnected recordsets. They aren't that difficult, but you lose the advantage of SQL that could be used with a real DB. Here is a good example of using that other grid control: DBGrid, provided by dilettante

2. The multiselect feature is 'simple' vs. 'extended'. You can't use the shift key to select a range of rows

3. It has no OLE drag/drop feature.

4. The scrollbar does not respond to mouse wheels.

Most of those deficiencies can be overcome.

In the sample project provided, you will find a class: cGridEx. Lot's of comments provided too. This class extends the DataGrid control a bit. It does offer workarounds for extended mutliselection and dragging records from the control. I did not include code to drag stuff into the DataGrid; but you could do that with lots of elbow grease. The mouse wheel is not addressed in the cGridEx class since that workaround requires subclassing, but shown below one way to handle it.

As far as the bound data... The class has an option that can help generate an empty ADO recordset where you fill in the data and assign the recordset to the data grid. Populating a recordset is not rocket science -- use your favorite method. Remember that Excel & CSVs can be loaded into recordsets also (nearly automatically), allowing you to view them via a DataGrid. Also, recordsets can be persisted to file.

To handle the mouse wheel, the cGridEx class has a function to be called from subclassing. Here is an example I am using (not included in the zip file)

1. In a bas module, include this code and the API declarations:
Code:

Private Declare Function DefSubclassProc Lib "comctl32.dll" (ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetWindowSubclass Lib "comctl32.dll" (ByVal hWnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
Private Declare Function RemoveWindowSubclass Lib "comctl32.dll" (ByVal hWnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long) As Long
Private Const WM_DESTROY As Long = &H2
Private Const WM_MOUSEWHEEL As Long = &H20A
Private Const WHEEL_DELTA As Long = 120

Public Sub UnSubclassGrid(hWnd As Long, Key As cGridEx)
    RemoveWindowSubclass hWnd, AddressOf pvWndProc, ObjPtr(Key)
End Sub
Public Sub SubclassGrid(hWnd As Long, Key As cGridEx)
    SetWindowSubclass hWnd, AddressOf pvWndProc, ObjPtr(Key), 0&
End Sub
Private Function pvWndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, _
                            ByVal uIdSubclass As cGridEx, ByVal dwRefData As Long) As Long
                           
    If uMsg = WM_MOUSEWHEEL Then
        wParam = (wParam And &HFFFF0000) \ &H10000
        uIdSubclass.ScrollGrid wParam \ -WHEEL_DELTA
    Else
        If uMsg = WM_DESTROY Then UnSubclassGrid hWnd, uIdSubclass
        pvWndProc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
    End If
   
End Function

2. After attaching the data grid control to the cGridEx class, subclass the control
Code:

' for example, in Form_Load
    Set m_GridEx = New cGridEx
    m_GridEx.Attach DataGrid1
    SubclassGrid DataGrid1.hWnd, m_GridEx

3. Remember to unsubclass the control before it is destroyed -- else a crash will occur, if you or VB sets the grid's cGridEx class to nothing before the control is unloaded by VB.
Code:

' for example, in Form_Unload
    Set DataGrid1.DataSource = Nothing
    UnSubclassGrid DataGrid1.hWnd, m_GridEx

Edited: For a slightly different version, see post #5 below.
Attached Files

Viewing all articles
Browse latest Browse all 1448

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>