Author Topic: Microsoft Flex Grid Control  (Read 5667 times)

0 Members and 1 Guest are viewing this topic.

Offline Josť Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2530
    • Josť Roca Software
Microsoft Flex Grid Control
« on: December 17, 2008, 06:06:34 AM »
 
The Microsoft FlexGrid (MSFlexGrid) control displays and operates on tabular data. It allows complete flexibility to sort, merge, and format tables containing strings and pictures.

You can put text, a picture, or both, in any cell of an MSFlexGrid. The Row and Col properties specify the current cell in an MSFlexGrid. You can specify the current cell in code, or the user can change it at run time using the mouse or the arrow keys. The Text property references the contents of the current cell.

If the text in a cell is too long to display in the cell, and the WordWrap property is set to True, the text wraps to the next line within the same cell. To display the wrapped text, you may need to increase the cells column width (ColWidth property) or row height (RowHeight property).

The following example demonstrates how to create a registration-free instance of the Microsoft Flex Grid Control using my OLE Container (OLECON.INC) to host it, how to fill rows and columns using an ADO recordset, how to connect to the events fired by the control (see the Click event for an example of how to sort the rows when the user clicks a row header), and how to set the default font for all the cells.

Registration-free means that you don't need to register the control to be able to use it. To use this registration-free version, you must copy Msflxgrd.ocx in the application folder, as if it was an standard DLL.

For using a registered version of the control, change the following code in the example:

Code: [Select]
' Create a registration-free instance of the MSHFlexGrid control
LOCAL  cp AS OC_CREATEPARAMS
cp.clsid = $CLSID_MSFlexGrid
cp.riid = $IID_IMSFlexGrid
cp.szLicKey = $RTLKEY_MSFlexGrid
cp.szLibName = EXE.Path$ & "Msflxgrd.ocx"
hGrid = CreateWindowEx(0, $OC_CLASSNAME, "", _
   %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR %WS_TABSTOP, _
   0, 0, 0, 0, CB.HNDL, %IDC_GRID, GetModuleHandle(BYVAL %NULL), cp)

to:

Code: [Select]
' Create an instance of the control
hGrid = CreateWindowEx(0, $OC_CLASSNAME, _
      "MSFlexGridLib.MSFlexGrid.1;RTLKEY:" & $RTLKEY_MSFlexGrid, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, 0, 0, 0, 0, hWnd, %IDC_GRID, GetModuleHandle(BYVAL %NULL), BYVAL %NULL)

Full example code (DDT version)

Code: [Select]
' ########################################################################################
' Microsoft Flex Grid Control Demo
' See the Click event for an example of how to sort the rows when the user clicks a row header.
' ########################################################################################

#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "ADO.INC"
#INCLUDE ONCE "MSFLXGRD.INC"
#INCLUDE ONCE "OLECON.INC"

%IDC_GRID = 1001                            ' // Grid's identifier
GLOBAL hGrid AS DWORD                       ' // Grid's handle

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   LOCAL hDlg AS DWORD

   ' Required: Initialize the Ole Container
   OC_WinInit

   DIALOG NEW 0, "Microsoft FlexGrid Control", , , 530, 346, %WS_OVERLAPPED OR %WS_THICKFRAME OR %WS_SYSMENU OR _
   %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE OR %DS_CENTER TO hDlg
   ' For icon from resource, instead use something like, LoadIcon(hInst, "APPICON")
   DIALOG SEND hDlg, %WM_SETICON, %ICON_SMALL, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   DIALOG SEND hDlg, %WM_SETICON, %ICON_BIG, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)

   ' We need to forward the messages to the control for keyboard handling
   ' and for that we need a message pump, so the dialog must be modeless.
   DIALOG SHOW MODELESS hDlg, CALL DlgProc

   ' Message handler loop
   LOCAL uMsg AS tagMsg
   WHILE GetMessage(uMsg, %NULL, 0, 0)
      IF ISFALSE OC_ForwardMessage(GetFocus, uMsg) THEN
         IF IsDialogMessage(hDlg, uMsg) = 0 THEN
            TranslateMessage uMsg
            DispatchMessage uMsg
         END IF
      END IF
   WEND

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main Dialog procedure
' ========================================================================================
CALLBACK FUNCTION DlgProc() AS LONG

   LOCAL  hr AS LONG                          ' // HRESULT code
   LOCAL  rc AS RECT                          ' // RECT structure
   LOCAL  pGrid AS IMSFlexGrid                ' // IMSFlexGrid interface reference
   STATIC pEvents AS DMSFlexGridEventsImpl    ' // Events interface

   SELECT CASE CB.MSG

      CASE %WM_INITDIALOG

         ' Create a registration-free instance of the MSFlexGrid control
         LOCAL  cp AS OC_CREATEPARAMS
         cp.clsid = $CLSID_MSFlexGrid
         cp.riid = $IID_IMSFlexGrid
         cp.szLicKey = $RTLKEY_MSFlexGrid
         cp.szLibName = EXE.Path$ & "Msflxgrd.ocx"
         hGrid = CreateWindowEx(0, $OC_CLASSNAME, "", _
            %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR %WS_TABSTOP, _
            0, 0, 0, 0, CB.HNDL, %IDC_GRID, GetModuleHandle(BYVAL %NULL), cp)

         ' Get a reference to the Grid control
         pGrid = OC_GetDispatch(hGrid)

         IF ISOBJECT(pGrid) THEN

            ' Create an ADO connection object
            LOCAL pCon AS ADOConnection
            pCon = NEWCOM "ADODB.Connection"

            IF ISOBJECT(pCon) THEN

               ' Connection string - Remember to change the path of the Data Source if needed
               LOCAL ConStr AS STRING
               ConStr = UCODE$("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & EXE.Path$ & "NWIND.mdb")
               ' Set the connection string
               pCon.ConnectionString = ConStr
               ' Open the connection
               pCon.Open

               IF OBJRESULT = %S_OK THEN

                  ' Create an ADO recordset object
                  LOCAL pRec AS ADORecordset
                  pRec = NEWCOM "ADODB.Recordset"

                  IF ISOBJECT(pRec) THEN

                     ' Open the recordset
                     LOCAL SqlStr AS STRING
                     SqlStr = "SELECT * FROM Customers"
                     pRec.Open SqlStr, pCon, %adOpenKeyset, %adLockOptimistic, %adCmdText
                     ' Move to the last record
                     pRec.MoveLast
                     ' Set the number of grid rows and columns
                     pGrid.Rows = pRec.RecordCount + 1
                     pGrid.Cols = 12

                     ' Set the headers
                     pGrid.TextMatrix(0,  1) = UCODE$("Customer ID")
                     pGrid.TextMatrix(0,  2) = UCODE$("Company Name")
                     pGrid.TextMatrix(0,  3) = UCODE$("Contact Name")
                     pGrid.TextMatrix(0,  4) = UCODE$("Contact Title")
                     pGrid.TextMatrix(0,  5) = UCODE$("Address")
                     pGrid.TextMatrix(0,  6) = UCODE$("City")
                     pGrid.TextMatrix(0,  7) = UCODE$("Region")
                     pGrid.TextMatrix(0,  8) = UCODE$("Postal Code")
                     pGrid.TextMatrix(0,  9) = UCODE$("Country")
                     pGrid.TextMatrix(0, 10) = UCODE$("Phone")
                     pGrid.TextMatrix(0, 11) = UCODE$("Fax")

                     ' Change the width of the columns (measures are in twips)
                     pGrid.ColWidth( 0) = 500
                     pGrid.ColWidth( 1) = 1400
                     pGrid.ColWidth( 2) = 3000
                     pGrid.ColWidth( 3) = 2000
                     pGrid.ColWidth( 4) = 2000
                     pGrid.ColWidth( 5) = 3000
                     pGrid.ColWidth( 6) = 1500
                     pGrid.ColWidth( 7) = 800
                     pGrid.ColWidth( 8) = 1300
                     pGrid.ColWidth( 9) = 1200
                     pGrid.ColWidth(10) = 1500
                     pGrid.ColWidth(11) = 1500

                     ' Allow to resize columns
                     pGrid.AllowUserResizing = %flexResizeColumns

                     ' Set the default font for all the cells
                     LOCAL pFont AS IDispatch
                     hr = OleCreateFontDisp("Verdana", 8, %FW_BOLD, %ANSI_CHARSET, 0, 0, 0, pFont)
                     IF ISOBJECT(pFont) THEN
                        pGrid.putref_Font = pFont
                        pFont = NOTHING
                     END IF

                     ' Change the foreground and background colors
                     pGrid.ForeColor = %BLACK
                     pGrid.BackColor = RGB(255,255,235)

                     ' Move to the first record
                     pRec.MoveFirst

                     ' Parse the recordset and fill the grid
                     LOCAL row AS LONG
                     LOCAL vRes AS VARIANT
                     row = 1

                     WHILE NOT pRec.EOF
                        'Select the row
                        pGrid.Row = row
                        ' Set the content of cell 1
                        pGrid.Col = 1
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("CustomerID")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 2
                        pGrid.Col = 2
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("CompanyName")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 3
                        pGrid.Col = 3
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("ContactName")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 4
                        pGrid.Col = 4
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("ContactTitle")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 5
                        pGrid.Col = 5
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("Address")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 6
                        pGrid.Col = 6
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("City")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 7
                        pGrid.Col = 7
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("Region")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 8
                        pGrid.Col = 8
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("PostalCode")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 9
                        pGrid.Col = 9
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("Country")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 10
                        pGrid.Col = 10
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("Phone")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Set the content of cell 11
                        pGrid.Col = 11
                        pGrid.CellAlignment = %flexAlignLeftCenter
                        vRes = pRec.Collect("Fax")
                        pGrid.Text = UCODE$(VARIANT$(vRes))
                        ' Fetch the next row
                        pRec.MoveNext
                        ' Increment the counter
                        INCR row
                     WEND

                     ' Select the first cell
                     pGrid.Row = 1
                     pGrid.Col = 1

                     ' Close and release the recordset
                     pRec.Close
                     pRec = NOTHING

                  END IF

               END IF

               ' Close and release the connection
               pCon.Close
               pCon = NOTHING

            END IF

            ' Connect to the events fired by the control
            pEvents = CLASS "CDMSFlexGridEvents"
            EVENTS FROM pGrid CALL pEvents
            pGrid = NOTHING

         END IF

      CASE %WM_SIZE
         ' Resize the grid
         IF CB.WPARAM <> %SIZE_MINIMIZED THEN
            GetClientRect CB.HNDL, rc
            MoveWindow GetDlgItem(CB.HNDL, %IDC_GRID), 0, 0, (rc.nRight - rc.nLeft), (rc.nBottom - rc.nTop), %TRUE
         END IF

      CASE %WM_COMMAND
         SELECT CASE CB.CTL
            CASE %IDOK
               IF CB.CTLMSG = %BN_CLICKED THEN
               END IF
            CASE %IDCANCEL
               IF CB.CTLMSG = %BN_CLICKED THEN DIALOG END CB.HNDL, 0
         END SELECT

      ' --> Note: Both WM_SYSCOMMAND and WM_DESTROY are required with this control <--

      CASE %WM_SYSCOMMAND
         ' Capture this message and send a %WM_CLOSE message,
         ' or the program may remain in memory
         IF (CBWPARAM AND &HFFF0) = %SC_CLOSE THEN
            DIALOG SEND CB.HNDL, %WM_CLOSE, 0, 0
         END IF

      CASE %WM_DESTROY
         ' Disconnect events and quit
         EVENTS END pEvents
         PostQuitMessage 0

   END SELECT

END FUNCTION
' ========================================================================================


' ########################################################################################
' Class CDMSFlexGridEvents
' Interface name = DMSFlexGridEvents
' IID = {609602E0-531B-11CF-91F6-C2863C385E30}
' Event interface for Microsoft FlexGrid Control
' Attributes = 4112 [&H1010] [Hidden] [Dispatchable]
' ########################################################################################

CLASS CDMSFlexGridEvents GUID$("{82AFC6E9-56AF-43AD-8516-BDD81DECCF98}") AS EVENT

INTERFACE DMSFlexGridEventsImpl GUID$("{609602E0-531B-11CF-91F6-C2863C385E30}") AS EVENT

  INHERIT IDispatch

   ' =====================================================================================
   METHOD Click <-600>

      LOCAL pGrid AS IMSFlexGrid       ' // IMSFlexGrid interface reference
      LOCAL row AS LONG                ' // Row clicked

      OutputDebugString FUNCNAME$

      ' Get a reference to the Grid control
      pGrid = OC_GetDispatch(hGrid)
      IF ISOBJECT(pGrid) THEN
         row = pGrid.MouseRow
         IF row = 0 THEN               ' // User has clicked the header row
            ' Sort rows in ascending order
            pGrid.Sort = %flexSortGenericAscending
            pGrid = NOTHING
         END IF
      END IF

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD KeyDown <-602> ( _
     BYREF KeyCode AS INTEGER _                         ' [1] *KeyCode /* *VT_I2 <Integer> */
   , BYVAL iShift AS INTEGER _                          ' [0] Shift /* VT_I2 <Integer> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD DblClick <-601>

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD KeyPress <-603> ( _
     BYREF KeyAscii AS INTEGER _                        ' [1] *KeyAscii /* *VT_I2 <Integer> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD KeyUp <-604> ( _
     BYREF KeyCode AS INTEGER _                         ' [1] *KeyCode /* *VT_I2 <Integer> */
   , BYVAL iShift AS INTEGER _                          ' [0] Shift /* VT_I2 <Integer> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD MouseDown <-605> ( _
     BYVAL iButton AS INTEGER _                         ' [0] Button /* VT_I2 <Integer> */
   , BYVAL iShift AS INTEGER _                          ' [0] Shift /* VT_I2 <Integer> */
   , BYVAL x AS LONG _                                  ' [0] x /* OLE_XPOS_PIXELS <alias> <VT_I4> */
   , BYVAL y AS LONG _                                  ' [0] y /* OLE_YPOS_PIXELS <alias> <VT_I4> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD MouseMove <-606> ( _
     BYVAL iButton AS INTEGER _                         ' [0] Button /* VT_I2 <Integer> */
   , BYVAL iShift AS INTEGER _                          ' [0] Shift /* VT_I2 <Integer> */
   , BYVAL x AS LONG _                                  ' [0] x /* OLE_XPOS_PIXELS <alias> <VT_I4> */
   , BYVAL y AS LONG _                                  ' [0] y /* OLE_YPOS_PIXELS <alias> <VT_I4> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD MouseUp <-607> ( _
     BYVAL iButton AS INTEGER _                         ' [0] Button /* VT_I2 <Integer> */
   , BYVAL iShift AS INTEGER _                          ' [0] Shift /* VT_I2 <Integer> */
   , BYVAL x AS LONG _                                  ' [0] x /* OLE_XPOS_PIXELS <alias> <VT_I4> */
   , BYVAL y AS LONG _                                  ' [0] y /* OLE_YPOS_PIXELS <alias> <VT_I4> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SelChange <69>

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD RowColChange <70>

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD EnterCell <71>

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD LeaveCell <72>

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Scroll <73>

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Compare <74> ( _
     BYVAL Row1 AS LONG _                               ' [0] Row1 /* VT_I4 <Long> */
   , BYVAL Row2 AS LONG _                               ' [0] Row2 /* VT_I4 <Long> */
   , BYREF Cmp AS INTEGER _                             ' [1] *Cmp /* *VT_I2 <Integer> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD OLEStartDrag <1550> ( _
     BYREF pData AS IVBDataObject _                     ' [2] [in][out] **Data /* **DataObject <coclass> */
   , BYREF AllowedEffects AS LONG _                     ' [1] [in][out] *AllowedEffects /* *VT_I4 <Long> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD OLEGiveFeedback <1551> ( _
     BYREF Effect AS LONG _                             ' [1] [in][out] *Effect /* *VT_I4 <Long> */
   , BYREF DefaultCursors AS INTEGER _                  ' [1] [in][out] *DefaultCursors /* *VT_BOOL <Integer> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD OLESetData <1552> ( _
     BYREF pData AS IVBDataObject _                     ' [2] [in][out] **Data /* **DataObject <coclass> */
   , BYREF DataFormat AS INTEGER _                      ' [1] [in][out] *DataFormat /* *VT_I2 <Integer> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD OLECompleteDrag <1553> ( _
     BYREF Effect AS LONG _                             ' [1] [in][out] *Effect /* *VT_I4 <Long> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD OLEDragOver <1554> ( _
     BYREF pData AS IVBDataObject _                     ' [2] [in][out] **Data /* **DataObject <coclass> */
   , BYREF Effect AS LONG _                             ' [1] [in][out] *Effect /* *VT_I4 <Long> */
   , BYREF iButton AS INTEGER _                         ' [1] [in][out] *Button /* *VT_I2 <Integer> */
   , BYREF iShift AS INTEGER _                          ' [1] [in][out] *Shift /* *VT_I2 <Integer> */
   , BYREF x AS SINGLE _                                ' [1] [in][out] *x /* *VT_R4 <Single> */
   , BYREF y AS SINGLE _                                ' [1] [in][out] *y /* *VT_R4 <Single> */
   , BYREF State AS INTEGER _                           ' [1] [in][out] *State /* *VT_I2 <Integer> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD OLEDragDrop <1555> ( _
     BYREF pData AS IVBDataObject _                     ' [2] [in][out] **Data /* **DataObject <coclass> */
   , BYREF Effect AS LONG _                             ' [1] [in][out] *Effect /* *VT_I4 <Long> */
   , BYREF iButton AS INTEGER _                         ' [1] [in][out] *Button /* *VT_I2 <Integer> */
   , BYREF iShift AS INTEGER _                          ' [1] [in][out] *Shift /* *VT_I2 <Integer> */
   , BYREF x AS SINGLE _                                ' [1] [in][out] *x /* *VT_R4 <Single> */
   , BYREF y AS SINGLE _                                ' [1] [in][out] *y /* *VT_R4 <Single> */
   )                                                    ' VOID

     ' *** Insert your code here ***
      OutputDebugString FUNCNAME$

   END METHOD
   ' =====================================================================================

END INTERFACE

END CLASS
' ========================================================================================
« Last Edit: August 07, 2011, 05:45:53 AM by Josť Roca »