Click here to Skip to main content
11,437,713 members (35,931 online)
Click here to Skip to main content

Smart Grid

, 24 May 2000
Rate this:
Please Sign up or sign in to vote.
Build a grid using ATL, STL and Win32 API.

Introduction

This is a data grid built using ATL 3.0, STL and Win32 API. The article provides some explanation about the grid's capabilities. I will not describe in detail the implementation of my grid because there is a lot of code and I do not think that anybody would have enough patience to read something like that. Source code is commented and this should be enough.

Smart Grid

Data types

As one can see, every column of the grid has an associated data type. This means that every value in the same column will have the same type. Available types are:

   // These are the data types
   typedef [v1_enum] enum DataType 
   {
      DataType_Empty = 0,      // Not specified
      DataType_Null = 1,      // NULL
      DataType_I2 = 2,      // 2-byte signed int
      DataType_I4 = 3,      // 4-byte signed int
      DataType_R4 = 4,      // 4-byte real
      DataType_R8 = 5,      // 8-byte real
      DataType_Cy = 6,      // Currency
      DataType_Date = 7,      // Date
      DataType_BStr = 8,      // Binary string
      DataType_Dispatch = 9,   // IDispatch FAR*
      DataType_Error = 10,   // Scodes
      DataType_Bool = 11,      // Boolean; True=-1, False=0
      DataType_Variant = 12,   // VARIANT FAR*
      DataType_Unknown = 13,   // IUnknown FAR*
      DataType_UI1 = 17,      // Unsigned char   
      
      // My types
      DataType_Option = 0x0100,    // Combo box
      DataType_StrictOption     // Drop down list

   } DataType;

As everybody can see, these types are in fact almost all VARTYPEs. If the user tries to change the value of a cell with a value whose type is incompatible with the type associated with the column, the value of the cell will not change. I also added some custom types, like Option and StrictOption. Data of these types are edited using combo boxes and drop down lists, as you can see in the next picture.

Smart Grid

Range specifications

Every column has a type and a range for values. This means that you can enter in the cells, values that have the type associated with the column and are in the specified range. For example, you can specify ranges for numeric values:"18,49" or you can specify options that are available for an Option or StrictOption type: "Male|Female". For numeric values, the possibilities to specify ranges are:

  • ",nMax"

    This means that values in the column are restricted to be less or equal than nMax value

  • "nMin,"

    Values in the column are restricted to be greater or equal than nMax value

  • "nMin,nMax"

    Values in the column cannot be changed by the user in order to be outside of the interval [nMin,nMax]

User operations

Row selection is also available. You can select multiple rows of the grid using right-click. Clicking the upper-left corner of the grid selects all rows in the grid. Double clicking the same area unselects all lines. From VB, for example, you can test if a row is selected or not. Optionally, rows can be numbered on the left header. Pressing enter or F2 enters the grid in edit mode. Depending on the type of the data that is in the selected cell, on edit mode opens an edit control, combo box, drop down list or the value is automatically changed ( boolean values ). Sorting is available. If a column's property AllowUserToSort is set on TRUE, then double-clicking that column sorts the rows after the values on that column. If the user modifies that column and the content becomes unsorted, pressing F5 makes a resort.

Smart Grid

Static and dynamic resizing is available for top header height, left header width, row height and column width. In the previous image, I have marked with red dots the points that can be used for resizing.

Smart Grid

Colors are fully customizable. You can choose your favorite combination of colors for grid items, as you can see in the screenshot.

Data sources

You can fill the grid with data from code (VB is the easiest way to manipulate this grid). Also, there are two more ways to enter data into the grid: a previously opened ADO Recordset, a connection string or an SQL SELECT statement. Unfortunately, in this version of the grid, the databases are not automatically updated when the values of the cells change. This will be done in the next version.

   // This are data source types
   typedef [v1_enum] enum
   {
      DataSourceType_None = 0,
      DataSourceType_ADORecordset,
      DataSourceType_SQLStatement,
   } DataSourceType;

Database connection is not very well implemented yet, so I recommend this grid to be used with DataSourceType_None.

Grid manipulation

I will describe now the interfaces that can be used to manipulate grid elements.

ISmartGrid

   // Use this to manipulate grid properties
   interace ISmartGrid : IDispatch;

ISmartGrid interface is used to manipulate general properties of the grid. ISmartGrid is a big interface so I will describe its methods and properties without inserting the IDL code here.

Methods

AddColumn( [in] Name, [in] Type, [in, optional] ReadOnly, 
     [in, optional] Range, [out, optional] Column )
InsertColumn( [in] Name, [in] Type, [in] Position, [in, optional] ReadOnly, 
     [in, optional] Range, [out, optional] Column )
RemoveColumn( [in] Position )
      
AddRow( [out, optional] Row )
InsertRow( [in] Position, [out, optional] Row )
RemoveRow( [in] Position )
      
SelectAllRows()
UnselectAllRows()
Requery()

Properties

// State
ActiveColumn
ActiveRow
NumberOfColumns
NumberOfRows
ReadOnly
UILocked
      
// Data access
Column
ConnectionString
CursorType
DataSource
DataSourceType
LockType
Row
      
// User interface
ActiveRowColor
ContentBkColor
      
      
ContentForeColor
ContentLinesColor
      
DefaultColumnWidth
Font
HeaderBkCOlor
HeaderForeColor
HeaderLinesColor
LeftHeaderVisible
LeftHeaderWidth      
RowHeight
SelectedItemColor
TopHeaderHeight
TopHeaderVisible

Using methods from ISmartGrid interface, columns and rows can be added to the grid. When adding a column or a row, a reference to it is optionally returned, in order to be used immediately after it is inserted. I split the properties of the grid into three sections. One is called State and I grouped here all properties that refers to the state of the grid. The second group refers to Data Access and the third group of properties can be used to customize User Interface.

ICell

   [
      helpstring("ICell interface is used to access cells"),
      uuid(C6462BB2-E639-11d3-8138-0000B49DBD2E),
      pointer_default(unique)
   ]
   interface ICell : IUnknown
   {
      [propget, helpstring("property Value")] 
         HRESULT Value([out, retval] VARIANT *pVal);      
      [propput, helpstring("property Value")] 
         HRESULT Value([in] VARIANT newVal);
   };

As you can see ICell interface is designed to manipulate one cell. A cell has a Value property that is used to read or set the value of the cell.

IRow

[
  helpstring("IRow interface used to access rows from grid"),
  uuid(E18D7A91-E639-11d3-8138-0000B49DBD2E),
  pointer_default(unique)
]
interface IRow : IUnknown
{      
  [propget, helpstring("Get the specified cell of this row")] 
    HRESULT Cell(long nIndex, [out, retval] ICell **pVal);
      
  [propget, helpstring("Returs TRUE if this row is active and false otherwise")] 
    HRESULT Active([out, retval] BOOL *pVal);
  [propput, helpstring("Put this property TRUE if you wanna activate this row")] 
    HRESULT Active([in] BOOL newVal);
      
  [propget, helpstring("TRUE if this row is selected")] 
    HRESULT Selected([out, retval] BOOL *pVal);
  [propput, helpstring("Put this property on TRUE if you want to select this row")] 
    HRESULT Selected([in] BOOL newVal);
      
  [propget, helpstring("Returns the index of this row")] 
    HRESULT Index([out, retval] long *pVal);
};

IRow interface can be used to manipulate each row. A row is composed from cells. You can get a reference to a cell from a given row using the column index. Only one row can be active at a time. This row can be retrieved or changed through Active property. One or more rows can be selected. You can select or find if a row is selected through Selected property. The index of a row is accessible for reading by Index property.

IColumn

   [
      helpstring("IColumn interface used to access columns individually"),
      uuid(506580C1-E643-11d3-8138-0000B49DBD2E),
      pointer_default(unique)
   ]
   interface IColumn : IUnknown
   {
      [propget, helpstring("Access a cell from this column")] 
         HRESULT Cell(long nIndex, [out, retval] ICell** pVal);
      
      [propget, helpstring("Get the width of the column in pixels")] 
         HRESULT Width([out, retval] long *pVal);
      [propput, helpstring("Put the width of the column in pixels")] 
         HRESULT Width([in] long newVal);

      [propget, helpstring("Get the label of the column")] 
         HRESULT Name([out, retval] BSTR *pVal);
      [propput, helpstring("Put the label of the column")] 
         HRESULT Name([in] BSTR newVal);

      [propget, helpstring("Get data type used for this column")]
         HRESULT DataType([out, retval] DataType *pVal);

      [propget, helpstring("Put the values range")] 
         HRESULT Range([out, retval] BSTR *pVal);
      [propput, helpstring("Get the values range")] 
         HRESULT Range([in] BSTR newVal);

      [propget, helpstring("Get the index of the column")] 
         HRESULT Index([out, retval] long *pVal);
      
      [propget, helpstring("Get the ReadOnly state of the column")] 
         HRESULT ReadOnly([out, retval] BOOL *pVal);
      [propput, helpstring("Changes the ReadOnly state of the column")] 
         HRESULT ReadOnly([in] BOOL newVal);

      [propget, helpstring("Get SortOrder property of this column")] 
         HRESULT SortOrder([out, retval] SortOrder *pVal);
      [propput, helpstring("Changes the SortOrder property of the column")] 
         HRESULT SortOrder([in] SortOrder newVal);

      [propget, helpstring("Returns AllowUserToSort value")] 
         HRESULT AllowUserToSort([out, retval] BOOL *pVal);
      [propput, helpstring("Sets AllowUserToSort value")] 
         HRESULT AllowUserToSort([in] BOOL newVal);

      [helpstring("Resorts the grid data, by this column content")]
         HRESULT Resort();
   };

IColumn interface can be used to read or change properties of each column. Like for rows, you can access cells from a column through Cell property if you specify index of the cell in column. A column has the following properties: Width in pixels, Name which is the label displayed on the top header, DataType is read-only property used to retrieve data type associated with the column. Index is the zero-based index of the column within the grid and ReadyOnly is a boolean property which can be used to make a column available only for view. Even the grid is not entirely ReadOnly.

Events

There are a few events that the grid raises when certain operations take place. These events can be seen in the following dispinterface:

   [
      uuid(855D88AF-C9BD-11D3-A34E-0080AD303A9A),
      helpstring("_ISmartGridEvents Interface")
   ]
   dispinterface _ISmartGridEvents
   {
      properties:
      
      methods:
      [id(1), helpstring("Raised when the active row has changed")] 
         HRESULT RowChanged(long nPrevious, long nNew);
      [id(2), helpstring("Raised when the active column has changed")] 
         HRESULT ColumnChanged(long nPrevious, long nNew);
      [id(3), helpstring("Raised when the active cell has changed")] 
         HRESULT CellChanged(long nPreviousRow, long nPreviousColumn, 
         long nNewRow, long nNewColumn);

      // Cell content changing events
      [id(4), helpstring("Raised before edit begins")] 
         VARIANT_BOOL BeginCellEdit(long nRow, long nColumn, ICell*);
      [id(5), helpstring("Raised after edit is ended")] 
         HRESULT EndCellEdit(long nRow, long nColumn, ICell*);
      [id(6), helpstring("Raised after cell content is updated")] 
         HRESULT CellUpdated(long nRow, long nColumn, ICell*);
   };

I have tested this DLL using Microsoft Visual Basic 6.0. The archive contains the VB project that I used to test this ActiveX control.

This control does not depends on MFC.

History

  • Date Posted: March 28, 2000

  • Updated: April 12, 2000

    • Added DataType_Option and DataType_StrictOption that are edited using combo boxes and drop down lists.
    • Added "Range Specification" for values in each column. This will provide better control on values entered in grid's cells.
    • ReadOnly attribute is available on column and on entire grid.
    • When adding a row or a column, we can optionally receive a reference to the added object ( row or column ) so that we can immediately change its properties.
    • Added some event raising.
    • Bug fixes.
  • Updated: April 28, 2000

    • Added sorting capabilities. Double clicking on a column's header sorts the content of the grid after that column ( if the sorting is allowed for the column ). F5 key can be used for resort.
    • Bug fixes.
  • Updated: May 16, 2000

    • Added three events: BeginCellEdit, EndCellEdit and CellUpdated.
    • Bug fixes ( including those reported in comments till May 16 2000 ).
  • Updated: May 18, 2000

    • Added event ValueNotInRange, which is raised when the user enters a value that it is not in specified range.
    • Bug fixes.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Alex Turc

United States United States
No Biography provided

Comments and Discussions

 
GeneralOne more small bug Pin
<marquee>Alberto Gattegno</marquee>6-Sep-01 0:11
memberAlberto Gattegno6-Sep-01 0:11 
GeneralRead Only Columns Pin
<marquee>Alberto Gattegno</marquee>5-Sep-01 7:44
memberAlberto Gattegno5-Sep-01 7:44 
GeneralRe: Read Only Columns - the Fix Pin
<marquee>Alberto Gattegno</marquee>5-Sep-01 8:02
memberAlberto Gattegno5-Sep-01 8:02 
GeneralRe: Read Only Columns - the Fix Pin
<marquee>Alberto Gattegno</marquee>5-Sep-01 8:09
memberAlberto Gattegno5-Sep-01 8:09 
GeneralCrash in CManageData::Draw_StrictOption(unsigned short * 0xcdcdcdcd... Pin
Anonymous21-Jul-01 13:02
memberAnonymous21-Jul-01 13:02 
GeneralRe: Crash in CManageData::Draw_StrictOption(unsigned short * 0xcdcdcdcd... Pin
Anonymous21-Jul-01 14:24
memberAnonymous21-Jul-01 14:24 
GeneralNewbie: How to add a row properly Pin
Anonymous17-Jul-01 13:53
memberAnonymous17-Jul-01 13:53 
GeneralBug: Error using #import for generated AlxGrd.tlb Pin
Michael Fitzgerald13-Jul-01 9:39
memberMichael Fitzgerald13-Jul-01 9:39 
GeneralRe: Bug: Error using #import for generated AlxGrd.tlb Pin
Michail23-Nov-01 1:10
memberMichail23-Nov-01 1:10 
GeneralAdding Smart Grid to MFC DLL Pin
Tasiogr26-Jun-01 5:58
memberTasiogr26-Jun-01 5:58 
General**** VISUAL BASIC WARNING **** Pin
Anonymous25-Jun-01 20:26
memberAnonymous25-Jun-01 20:26 
GeneralRe: **** VISUAL BASIC WARNING **** Pin
Dimitris Vassiliades21-Sep-02 10:07
memberDimitris Vassiliades21-Sep-02 10:07 
QuestionWhat is "warning MIDL2039" ?? Pin
Anonymous5-Jun-01 9:16
memberAnonymous5-Jun-01 9:16 
GeneralErrors in VB6 with updating recordset Pin
Dang Dinh Ngoc26-May-01 0:36
memberDang Dinh Ngoc26-May-01 0:36 
GeneralAn issue under Windows 2000 Pin
Anonymous8-May-01 7:42
memberAnonymous8-May-01 7:42 
GeneralRe: An issue under Windows 2000 Pin
michail23-Nov-01 4:43
membermichail23-Nov-01 4:43 
Generalplz let me know how to display this grid on my form. Pin
SangKeun22-Mar-01 19:18
memberSangKeun22-Mar-01 19:18 
GeneralRe: plz let me know how to display this grid on my form. Pin
Anonymous27-May-01 21:45
memberAnonymous27-May-01 21:45 
Generaldifference between VARIANT and VARIANT FAR in VC Pin
prashant_ranade26-Feb-01 20:38
memberprashant_ranade26-Feb-01 20:38 
Generaldifference between VARIANT and VARIANT FAR in VC Pin
prashant_ranade26-Feb-01 20:37
memberprashant_ranade26-Feb-01 20:37 
GeneralConverted to MFC Pin
Norm Almond9-Feb-01 11:06
memberNorm Almond9-Feb-01 11:06 
GeneralRe: Converted to MFC Pin
Norm Almond19-Jul-02 23:00
memberNorm Almond19-Jul-02 23:00 
QuestionWhat should I do to Display the Grid ? Pin
Julie5-Feb-01 4:31
memberJulie5-Feb-01 4:31 
GeneralWon't compile Pin
Mel15-Jan-01 9:49
memberMel15-Jan-01 9:49 
GeneralCell merging Pin
Jerry Champeau22-Sep-00 3:57
sussJerry Champeau22-Sep-00 3:57 
GeneralSorting bug Pin
David Liu14-Sep-00 16:31
sussDavid Liu14-Sep-00 16:31 
GeneralA little bug Pin
Cecilia Ayala14-Sep-00 5:44
sussCecilia Ayala14-Sep-00 5:44 
GeneralCompilation & AlxGrd.tlb Pin
Tarek Eslim5-Sep-00 7:20
sussTarek Eslim5-Sep-00 7:20 
GeneralA possible bug Pin
Mike Player30-Aug-00 3:42
sussMike Player30-Aug-00 3:42 
GeneralRe: A possible bug Pin
Alex Turc31-Aug-00 22:51
sussAlex Turc31-Aug-00 22:51 
GeneralYet another bugfix Pin
Jerry III19-Aug-00 9:01
sussJerry III19-Aug-00 9:01 
GeneralAnother bug fix Pin
Serge Weinstock19-Aug-00 4:20
sussSerge Weinstock19-Aug-00 4:20 
Generalerror in editable combo Pin
John Mayer18-Aug-00 3:07
sussJohn Mayer18-Aug-00 3:07 
GeneralRe: error in editable combo Pin
Serge Weinstock19-Aug-00 4:22
sussSerge Weinstock19-Aug-00 4:22 
GeneralProblems handling RMB in cell edit Pin
Ivan Campo17-Aug-00 23:04
sussIvan Campo17-Aug-00 23:04 
GeneralRe: Problems handling RMB in cell edit Pin
Bogo17-Aug-00 23:13
sussBogo17-Aug-00 23:13 
GeneralSmall Bug Fix Pin
Serge Weinstock15-Aug-00 6:25
sussSerge Weinstock15-Aug-00 6:25 
GeneralCombo Box Pin
denis29-Jul-00 23:41
sussdenis29-Jul-00 23:41 
GeneralIcon in grid Pin
tomer27-Jul-00 7:56
susstomer27-Jul-00 7:56 
GeneralSmart Grid - Error in VC++ client - #import Pin
Girish25-Jul-00 22:57
sussGirish25-Jul-00 22:57 
GeneralRe: Smart Grid - Error in VC++ client - #import Pin
Emil14-Sep-00 5:10
sussEmil14-Sep-00 5:10 
GeneralRe: Smart Grid - Error in VC++ client - #import Pin
Anonymous26-Feb-01 6:47
memberAnonymous26-Feb-01 6:47 
Generalemail for Alex Turc Pin
Jerry22-Jun-00 10:35
sussJerry22-Jun-00 10:35 
QuestionCell Joining, Font, and Color ? Pin
Jerry Champeau14-Jun-00 3:09
sussJerry Champeau14-Jun-00 3:09 
GeneralTypo in CColumn Pin
Kevin Cook9-Jun-00 10:51
sussKevin Cook9-Jun-00 10:51 
GeneralDataType_Option Pin
ann30-May-00 6:38
sussann30-May-00 6:38 
GeneralRe: DataType_Option Pin
Richard Cunday31-May-00 11:49
sussRichard Cunday31-May-00 11:49 
QuestionCan Help me to compile Pin
Jack Hui25-May-00 21:44
sussJack Hui25-May-00 21:44 
AnswerRe: Can Help me to compile Pin
Gerolf Kuehnel28-May-00 21:51
sussGerolf Kuehnel28-May-00 21:51 
AnswerRe: Can Help me to compile Pin
Jack Hui29-May-00 5:52
sussJack Hui29-May-00 5:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150506.1 | Last Updated 25 May 2000
Article Copyright 2000 by Alex Turc
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid