Click here to Skip to main content
Click here to Skip to main content

DataGrid Control

By , 5 Aug 2005
 

Example on using DataGrid control

Introduction

This article presents a DataGrid control which is built with no MFC. It can be used in SDK or MFC Win32 applications. This source code is also compiled with GNU compiler and has shown to be stable.

Background

You can find various grid controls all over the Internet, some free and some not. Also, there is an article by Chris Maunder about a grid control which can be used on different platforms (ATL and MFC version). Grid controls are very useful for representing two-dimensional tabular data. They are often used in accounting applications. Grid controls must be designed for quick data-referencing and modification. The grid control presented in this article supports up to 32000 rows and 1000 columns. Also, there can be up to 20 grid controls created at the same time. These values can be changed in the DataGrid header file but there is always a memory limit.

Using the code

To use the DataGrid control a header file must be included in the project.

#include "DataGrid.h"

Next, create an instance of the CDataGrid class and call the Create() method.

// hParentWnd is declared somewhere else
//
CDataGrid dataGrid;
int numCols = 5;
RECT rect = {0,0,500,300};
dataGrid.Create( rect, hParentWnd, numCols );

Use SetColumnInfo() method to describe the DataGrid control columns.

int colIndex = 0;
char colText[] = "Column1";
int colSize = 120;
UINT txtAlign = DGTA_LEFT;
dataGrid.SetColumnInfo( colIndex, colText, colSize, txtAlign );

To add items to the DataGrid control, call InsertItem() method.

char itemText[] = "Item1";
dataGrid.InsertItem( itemText, txtAlign );

To describe subitems, use SetItemInfo() method.

int rowIndex = 0;
int columnIndex = 0;
char subitemText[] = "Subitem1";
bool readOnly = false;
dataGrid.SetItemInfo( rowIndex, columnIndex, subitemText, txtAlign, readOnly );

The DataGrid control sends notification messages through the WM_COMMAND message. These notifications are:

  • Item changed
  • Item text changed
  • Item added
  • Item removed
  • Column resized
  • Column clicked
  • Sorting started
  • Sorting ended

This is the basic use of this control. See the demo project as an example. The DataGrid control supports the following:

  • Grid show (on/off)
  • Column resize (on/off)
  • Item text edit (on/off)
  • Items sorting (on/off)
  • Get/set row background color
  • Get/set row text color
  • Get/set row font
  • Get/set column text color
  • Get/set column font
  • Set application-defined sort function

Points of Interest

My goal was to try to develop a grid control that will support most of the things that the MFC CListCtrl control does and possibly some more and to be as efficient. Its GUI is designed to be very similar with the previously mentioned control.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

darkoman
Software Developer (Senior) Elektromehanika d.o.o. Nis
Serbia Serbia
Member
He has a master degree in Computer Science at Faculty of Electronics in Nis (Serbia), and works as a C++/C# application developer for Windows platforms since 2001. He likes traveling, reading and meeting new people and cultures.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMore memory leaks....memberdc_20001 Apr '11 - 12:39 
I posted one comment about memory leaks before but now as I studied the code a bit more I see that there's more to it. Don't get me wrong, the author of this code has a very good knowledge of low-level programming of GUI controls, what he lacks is the knowledge of the memory management, or freeing the memory that is not needed. It's hard to put any code here of how this project has to be changed, I'll just put method named for you to check for memory leaks:
 
1. RemoveItem(int row) must release memory reserved in the call to InsertItem(const TCHAR* itemText, int textAlign, bool bReadOnly)
 
2. RemoveAllItems() also must release memory reserved in the same method.
GeneralWow, this thing leaks memory like a seivememberdc_200024 Mar '11 - 9:36 
OK, that poster before me was able to find the memory leak too, he just didn't have enough brains to post it here in a readable form so that everyone could just copy it (without editting out his comments). So once again here you go, to fix the memory leak replace the DestroyDGGrid() method in the code with this:
 
void DestroyDGGrid(HWND hWnd)
{ 
	DG_LIST* dgList = DetachDGGrid(hWnd); 
	if ( dgList != NULL ) 
	{ 
		// Delete columns 
		if ( dgList->dg_Columns ) 
		{ 
			delete [] dgList->dg_Columns; 
			dgList->dg_Columns = NULL; 
		} 
 
		// Delete Items - hochan Added 
		for(int i = 0; i< dgList->dg_RowNumber; i++) 
		{
			for ( int j=0; j< dgList->dg_ColumnNumber; j++ )
			{ 
				delete [] dgList->dg_Rows[i].rowText[j]; 
			} 
 
			delete [] dgList->dg_Rows[i].rowText; 
			delete [] dgList->dg_Rows[i].textAlign; 
			delete [] dgList->dg_Rows[i].readOnly; 
		}
 
		 // Delete rows 
		free(dgList->dg_Rows); 
		dgList->dg_Rows = NULL; 
 
		// Delete column font 
		if ( dgList->dg_hColumnFont ) 
		{ 
			DeleteObject(dgList->dg_hColumnFont); 
			dgList->dg_hColumnFont = NULL; 
		} 
 
		// Delete row font 
		if ( dgList->dg_hRowFont ) 
		{ 
			DeleteObject(dgList->dg_hRowFont); 
			dgList->dg_hRowFont = NULL; 
		}
 
		 // Delete background brush 
		if ( dgList->dg_hBgBrush ) 
		{ 
			DeleteObject(dgList->dg_hBgBrush); 
			dgList->dg_hBgBrush = NULL; 
		}
 
		// Delete cell pen 
		if ( dgList->dg_hCellPen ) 
		{ 
			DeleteObject(dgList->dg_hCellPen); 
			dgList->dg_hCellPen = NULL; 
		} 
 

		// Delete memory device context 
		if ( dgList->dg_hMemDC ) 
		{ 
			SelectObject( dgList->dg_hMemDC, dgList->dg_hOldMemBitmap ); 
			DeleteDC(dgList->dg_hMemDC); 
			dgList->dg_hMemDC = NULL; 
		} 
 
		// Delete memory bitmap 
		if ( dgList->dg_hMemBitmap ) 
		{ 
			DeleteObject(dgList->dg_hMemBitmap); 
			dgList->dg_hMemBitmap = NULL; 
		} 
 
		delete dgList; 
		
 
		g_DGGridNumber--; 
	} 
}
 
PS. And a note for the author, please include this in the source...
Questionmemory leaksmemberRonWilsonCPP11 Aug '10 - 21:15 
Hi! Very great grid but i found out that it's not free _DG_ROW structures Frown | :( can you fix this bug?
AnswerRe: memory leaks [modified]membermaplewang7 Dec '10 - 18:24 
one taken item was from http://www.codeguru.com/cpp/controls/controls/gridcontrol/article.php/c10319/CDataGrid-Control.htm[^]
in void DestroyDGGrid(HWND hWnd)
// Delete columns
if ( dgList->dg_Columns )
{
delete [] dgList->dg_Columns;
dgList->dg_Columns = NULL;
}
// Delete Items - hochan Added
for(int i = 0; i< dgList->dg_RowNumber; i++)
{
for ( int j=0; j< dgList->dg_ColumnNumber; j++ )
{
delete [] dgList->dg_Rows[i].rowText[j];
}
delete [] dgList->dg_Rows[i].rowText;
delete [] dgList->dg_Rows[i].textAlign;
delete [] dgList->dg_Rows[i].readOnly;
}
// Delete rows
free(dgList->dg_Rows);
dgList->dg_Rows = NULL;
// Delete column font
 
in void CDataGrid::RemoveAllItems() it should do this job too.
in BOOL CDataGrid::RemoveItem(int row)
comment out memcpy by using the code bellow
for ( i=row; i<dgList->dg_RowNumber; i++ )
{
// memcpy( &dgList->dg_Rows[i], &dgList->dg_Rows[i+1], sizeof(DG_ROW) );
iNext =i+1;
for ( j=0; j<dgList->dg_ColumnNumber; j++ )
{
//strcpy( dgList->dg_Rows[i].rowText[j], dgList->dg_Rows[iNext].rowText[j] );
if (( strlen(dgList->dg_Rows[i].rowText[j]) < strlen(dgList->dg_Rows[iNext].rowText[j]))
&& (DG_MINTEXTLEN<strlen(dgList->dg_Rows[iNext].rowText[j])))//#define DG_MINTEXTLEN 128 can be changed to suit your need
 
{
delete dgList->dg_Rows[i].rowText[j];
dgList->dg_Rows[i].rowText[j] = new char[strlen(dgList->dg_Rows[iNext].rowText[j])+1];
}
if ( strlen(dgList->dg_Rows[iNext].rowText[j]) == 0 )
strcpy( dgList->dg_Rows[i].rowText[j], "" );
else
strcpy( dgList->dg_Rows[i].rowText[j], dgList->dg_Rows[iNext].rowText[j] ); dgList->dg_Rows[i].textAlign[j] = dgList->dg_Rows[iNext].textAlign[j];
dgList->dg_Rows[i].readOnly[j] = dgList->dg_Rows[iNext].readOnly[j];
}
dgList->dg_Rows[i].selected = dgList->dg_Rows[iNext].selected;
dgList->dg_Rows[i].bgColor = dgList->dg_Rows[iNext].bgColor;
}
 
every time the control adding/remove item will realloc memory , it is not efficient, this can be avoid by introducing a virtual memory rownumber to manage memory problem.
 
the origin version text memory len is allocated on base of text length, it is not good when delete one row, then have to copy behind to the deleted row, I changed memory alloc method by allocate a fixed size memory, though it is not very feasible too.
in BOOL CDataGrid::InsertItem(char* itemText, int textAlign)
for ( int j=0; j<dgList->dg_ColumnNumber; j++ )
{
//dgList->dg_Rows[dgList->dg_RowNumber-1].rowText[j] = new char[strlen(itemText)+1];
dgList->dg_Rows[i].rowText[j] = new char[DG_MINTEXTLEN];//changed to this #define DG_MINTEXTLEN 128 can be changed to suit your need
strcpy( dgList->dg_Rows[i].rowText[j], " " );
dgList->dg_Rows[i].textAlign[j] = textAlign;
dgList->dg_Rows[i].readOnly[j] = false;
}
 
in BOOL CDataGrid::RemoveItem(int row) change:
for ( j=0; j<dgList->dg_ColumnNumber; j++ )
{
//strcpy( dgList->dg_Rows[i].rowText[j], dgList->dg_Rows[iNext].rowText[j] );
if (( strlen(dgList->dg_Rows[i].rowText[j]) < strlen(dgList->dg_Rows[iNext].rowText[j]))
&& (DG_MINTEXTLEN<strlen(dgList->dg_Rows[iNext].rowText[j])))
{
delete dgList->dg_Rows[i].rowText[j];
dgList->dg_Rows[i].rowText[j] = new char[strlen(dgList->dg_Rows[iNext].rowText[j])+1];
}
if ( strlen(dgList->dg_Rows[iNext].rowText[j]) == 0 )
strcpy( dgList->dg_Rows[i].rowText[j], "" );
else
strcpy( dgList->dg_Rows[i].rowText[j], dgList->dg_Rows[iNext].rowText[j] );
dgList->dg_Rows[i].textAlign[j] = dgList->dg_Rows[iNext].textAlign[j];
dgList->dg_Rows[i].readOnly[j] = dgList->dg_Rows[iNext].readOnly[j];
}
anyway it is one of best GRID for programming with VC Express.

modified on Monday, December 20, 2010 8:05 PM

GeneralLogical FlawmemberJosephHong31 Jul '09 - 22:00 
Upon CreateWindowEx(..."DATAGRID"...) at CDataGrid::Create() function, WM_CREATE is immediately called before CreateWindowEx returns. This results in improper handling of WM_CREATE where GetDGGrid fails and consequently fails to create Device Context(CreateCompatibleDC). This results in nothing showing up. For now, the grid is showing up only because it does something else(I have to look at thoroughly to find out the trigger). But other than that, nice work!!
GeneralRe: Logical Flawmemberdc_200025 Mar '11 - 14:48 
Yes, agreed. To fix that, move the following code block from the WM_CREATE handler into CDataGrid::Create() after these lines of code :
          DG_LIST* dgList = GetDGGrid(m_hWnd);
          if ( dgList != NULL )
          {
                  HDC hDC = GetDC(dgList->dg_hWnd);
                  RECT rectClient;
                  GetClientRect( dgList->dg_hWnd, &rectClient );
                  dgList->dg_hMemBitmap = CreateCompatibleBitmap( hDC, (rectClient.right-rectClient.left), (rectClient.bottom-rectClient.top) );
                  dgList->dg_hMemDC = CreateCompatibleDC(hDC);
                  dgList->dg_hOldMemBitmap = (HBITMAP)SelectObject( dgList->dg_hMemDC, dgList->dg_hMemBitmap );
                  SetFocus(dgList->dg_hWnd);
                  ReleaseDC( dgList->dg_hWnd, hDC );

AnswerControl Not Displaying Bug and FixmemberDrew_Benton7 Apr '08 - 23:54 
There seems to be a bug when you specify a grid to be larger than the length of it's columns. The grid control turns gray and nothing is drawn. I am using Windows XP, Service Pack 2.
 
The problem is caused by the scroll window being not shown, but the scroll information is never updated.
 
In the void RecalcWindow(HWND hWnd) function:
 
else
   ShowScrollBar( hWnd, SB_HORZ, FALSE );
 
at the top of the function should be:
 
else
{
   // Show horizontal scroll bar
   SCROLLINFO si;
   si.cbSize = sizeof(SCROLLINFO);
   si.fMask = SIF_ALL;
   si.nPos = GetScrollPos( hWnd, SB_HORZ );
   si.nMin = 0;
   si.nMax = sizeX - scrollDiff;
   si.nPage = si.nMax - si.nMin + 1 - abs(scrollDiff);
   si.nTrackPos = 0;
   SetScrollInfo( hWnd, SB_HORZ, &si, TRUE );
   ShowScrollBar( hWnd, SB_HORZ, FALSE );
}
 
And:
 
else
   ShowScrollBar( hWnd, SB_VERT, FALSE );
 
at the bottom of the function should be:
 
else
{
   // Show vertical scroll bar
   SCROLLINFO si;
   si.cbSize = sizeof(SCROLLINFO);
   si.fMask = SIF_ALL;
   si.nPos = GetScrollPos( hWnd, SB_VERT );
   si.nMin = 0;
   si.nMax = sizeY - scrollDiff;
   si.nPage = si.nMax - si.nMin + 1 - abs(scrollDiff);
   si.nTrackPos = 0;
   SetScrollInfo( hWnd, SB_VERT, &si, TRUE );
   ShowScrollBar( hWnd, SB_VERT, FALSE );
}
 
That's what I have right now which makes the control behave how it should. I've not used it much due to this bug, but if I find more I will post.
QuestionLicense?memberrecyclotron20 Feb '08 - 5:22 
Hey!
 
What kind of license are you using for this great control? Would you mind if I used it in a couple of projects?
 
-R
QuestionNice and usefulmemberspyto30 Nov '07 - 3:51 
Hi darkoman,
 
Do you plan to continue development ?
 
When an updated and enhanced version will be released ?
 
Thanks
 
spyto
QuestionHow to resize the Datagrid?memberlurvhua26 Nov '07 - 18:17 
Hellow, the DataGrid is very useful, but how can I resize it when I resize the dialog?
 
Find the Way!

AnswerRe: How to resize the Datagrid?memberAjm11330 Dec '09 - 7:48 
Just re-size it like any other window using the MoveWindow function and use the GetWindowHandle in DataGrid class for the first argument for MoveWindow.
 
Then use GetClientRect for the dialog's 'HWND' to get the size.
Generala bugmemberclxye8 Oct '07 - 17:24 
In a mfc program, this class works not very well.
void CTest11Dlg::OnButton1()
{
// TODO: Add your control notification handler code here

RECT rect = {50,50,670,300};
CDataGrid dataGrid;
dataGrid.Create( rect, this->m_hWnd, 5 );
 
// Set DataGrid column info
dataGrid.SetColumnInfo( 0, "Column0", 120, DGTA_CENTER );
dataGrid.SetColumnInfo( 1, "Column1", 120, DGTA_CENTER );
dataGrid.SetColumnInfo( 2, "Column2", 120, DGTA_CENTER );
dataGrid.SetColumnInfo( 3, "Column3", 120, DGTA_CENTER );
dataGrid.SetColumnInfo( 4, "Column4", 120, DGTA_CENTER );
dataGrid.Update();
}
 
The grid is invisible in this procedure.
 
When the total columns width less than the grid width, the grid will be invisible in MFC procedures. in other words, if no vertical or horizontal scrolling of the scroll appears, the grid will be invisible. However, in Win32 procedure does not exist in this issue.
 
Thank you!

QuestionHow to delete a column?memberclxye27 Sep '07 - 22:16 
First of all, thank you for your work! This class is practical, and very brief.
 
I would like to ask you how to delete n column or delete all columns?
 
Thank you!Rose | [Rose]
AnswerRe: How to delete a column?memberoldmoon27 Sep '07 - 22:37 
Laugh | :laugh:
Which step that you want delete DataGrid's column?
Before DataGrid DataBind:
You can control DataSet or DataTable or ArrayList!
After DataGrid DataBind:
First, You can give DataGrid's column a id when DataBind by event OnItemDataBound.
Second,You can contol hidden or show by javascript(document.getElementById(id).style.display).
 
My English not very well,Are you understand?
GeneralRe: How to delete a column?memberclxye28 Sep '07 - 15:01 
First of all, thank you for your attention!
 
I need the works based on the user's choice of different values, and in tabular form displayed.
 
First time user may measure sample1 value and sample2 value, so column1 = sample and column2 = Sample2.
 
After read all the data and display the future, user may have to sample3 and sample4 or other values, so I want to clear all the Items and Columns, and re-create Columns. Then read data and show it again.
GeneralRe: How to delete a column?memberoldmoon29 Sep '07 - 15:35 
If you want to read data and show it again,you should re-creat page and re-DataBind or use ajax.
Sorry,I used ajax hardly! You can read some books about ajax!But,If you want to How to re-DataBind,please tell me!
AnswerRe: How to delete a column?memberclxye28 Sep '07 - 20:47 
I have been resolved this question.
GeneralProblem In Unicodememberlurvhua30 Aug '07 - 22:08 
Hi, darkoman, I like your control style very much. But when I test it in unicode, many error occurs. I've changed the code as you suggested before.
 
eg: _tcscpy( dgList->dg_Columns[i].columnText, " ");
error C2664: 'wcscpy' : cannot convert parameter 1 from 'char [1024]' to 'wchar_t *'
 
Can you give me some more advice? Or can you kindly test the code in unicode?
 
sorry for my poor English! : )

 
Find the Way!

GeneralRe: Problem In Unicodememberdarkoman31 Aug '07 - 12:12 
Hello, thanks for your interest...
 
I think that you'll need just to convert dgList->dg_Columns[i].columnText variable to _TCHAR* and it should work. I mean both params in _tcscpy() method have to be of the _TCHAR* type.
Hope it will work for you...
 

Best regards,
Darkoman

GeneralRe: Problem In Unicodememberlurvhua2 Sep '07 - 0:18 
Hello, thanks for your advice, now it works well in unicode! I'm so happy!
 
Find the Way!

Generalmultiple row selectionmemberadii289 Jul '07 - 6:43 
I am thinking of using this datagrid for my project. There are two features missing which I need i.e. multiple row selection and intelligent paging.
I was wondering if any work has been done on them. If not I am willing to spend some time to add these features, but want to make sure if the design of the grid will support multiple row selections? I have not looked at the source yet.

GeneralRe: multiple row selectionmemberdarkoman9 Jul '07 - 19:14 
Hello and thanks for your interest in this project,
 
Sorry, but no work has been done (no time to work further) on the multiple row selection or paging.
Yes, you are free to add these features to the project. The grid design would allow support of multiple row selection (with no major changes).
Best luck...
 

Regards,
Darkoman

QuestionHow to get the number of specific rowmembereryreyeryeryeryeyryye17 May '07 - 6:46 
I have seen you data grid project and willing to ask you that if I click on any row i want the number(count) of the row where it exist as i need some sort of looping for my application
 
for(int i= clickedRow ; i < totalrows; i++ ) for enhancing my UI
 

I am able to get the total number of rows via
long totalRows = m_dataGrid.get_ApproxCount();
 
Would you please help me
Thnaks in advance
Kaz
 
It is Kaz

Questionmultiple instancesmemberhopsoid19 Nov '06 - 15:37 
I'm trying to create a second instance of the grid in another dialog but i'm having redefinition error for the structs(DG_COLUMN..) I tried to move their definition to another file but that didn't help. Any help?
Thanks,
 
hope.
GeneralQuestion about simple applikationmemberwoj11727 Jul '06 - 8:40 
Hi Darkoman,
That's me again. Now I have probably simple problem, but I can't solve it. I have created simple application with main window and status bar. In a workspace between menu and statusbar Grid is located. Now, when window is resized then Grid is also resized, but it overlaps with status bar or there is a space between them. Any suggestion to solve this problem??
 
Regards
WojciechW
NewsA bugmemberkingren3 Jul '06 - 15:25 
if debug,it has no error.But I built it in release."remove all",then duobled click on datagrid control,then it pop out a error"unknow software exception(0c0000094)".

QuestionHidden RowsmemberRickomurphy27 Jun '06 - 4:13 
Hi I'm using your grid in my application, and as others have said, thanks for all your hard work. I'm making some modifications (as my application is slightly odd) and am trying to implement Hidden Rows, i.e. I've added an attribute to each row which when set the row is not redrawn, instead the next one is (unless that is hidden, and so on). Frankly, as I'm not an expert Windows programmer, I'm having trouble! Perhaps this is something you would consider adding yourself?
 
Also I noticed a problem where the vertical scroll bar "bounces" when dragged to the bottom. This seems to fix it:
 
case SB_THUMBTRACK:
{
RECT rowRect, clientRect, columnRect;
GetRowRect( hwnd, 0, &rowRect );
GetColumnRect( hwnd, 0, &columnRect );
GetClientRect( hwnd, &clientRect );
clientRect.top = columnRect.bottom;
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo( hwnd, SB_VERT, &si );
int OldPos = si.nPos;
int NewPos = si.nTrackPos;
// Rick these two lines cause the vertical scrollbar bounce
// which occurs when the scroll bar is dragged to the bottom
//int diff = NewPos % (rowRect.bottom-rowRect.top-1);
//NewPos -= diff;
si.nPos = NewPos;
si.nTrackPos = NewPos;
SetScrollPos( hwnd, SB_VERT, NewPos, TRUE );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
 
Any comments?

 
--Ricko
AnswerRe: Hidden Rowsmemberdarkoman27 Jun '06 - 5:14 
Hello, thanks if you find it usefull. Yes, I can do this small fix in the next two or three days so I will post an update.
 
Best regards...
GeneralRe: Hidden RowsmemberRickomurphy27 Jun '06 - 5:53 
Wow - that'd be great!
FYI the issues I've identified are:
 
(1) when the user clicks on a row to select it, converting the click position to the correct row given that there may be hidden rows. For example,
Row 1,2,3,8,9,10 are displayed (rows 4,5,6,7 are hidden)
Click on the 4th visible row, that means that row 8 has been selected.
 
(2) The vertical scrollbar must be resized depending on the number of visible rows
 
(3) Select Next/Prev must select the Next / Prev visible row
 
(4) When the currently selected row is hidden, it needs to be "un-selected"
 
(5) EnsureRowVisible needs to take account of hidden rows
 
Items (1) and (5) have got me stumped.
Item (2) required that a count is kept of the number of visible rows as well as the total number of rows. Keeping this in sync is a bit nasty when rows are added, removed, hidden and unhidden.
 
I look forward to the update! Thanks.
 
--Ricko
GeneralNicememberSharpmike17 Jun '06 - 19:31 
Nice work, you got my 4. Not many are willing to do this kind of thing in Win32; even fewer are willing to share their code for free. Love the grid, but I have a few suggestions for you. Ignore these if you've heard them before.
 
- Try drawing only those cells that are visible. You can greatly speed up the responsiveness of the grid when there are 500+ cells.
- Try to implement more functions as windows messages. This would make wrapping your control in an MFC, WTL, or other object windows environment much easier.
- Provide a UNICODE implementation. I see an earlier post suggesting this; you're right, it is simple to do.
- Consider XP theming. It's very easy to implement and adds a lot of visual bang for the buck.
- Build yourself a way of subclassing the edit box and any other controls you wish to use for editing the grid. This way you can catch things like the Enter, Escape, and Tab keys and perform appropriate actions in the grid.
- Implement a handler for WM_GETDLGCODE. This way users putting your grid in a dialog can still get the standard behavior for any keyboard input on the grid.
 
Thanks again for your hard work, I appreciate it.
 
Sharpmike
GeneralRe: Nicememberdarkoman17 Jun '06 - 20:25 
Hello, thanks for these very good sugestions. I am going to implement most of these things in the next release of the DataGrid. Now, I am on the secret SWF-PROJECT (not present here on CodeProject), so it will take some time.
 
Considering cell drawing, well, only visible cells are drawn on the screen, otherwise if there are more then 500 cells it would be a problem. I am performing that kind of calculation before I do any drawing.
 

Best regards...
GeneralSome more wishes...memberwoj11713 Mar '06 - 4:31 
Hi Darkoman,
Your control is really cool, and up to now it work without any problems. But I need some additional functionalities:
1. would it be possible to change a colour of only one cell?
And now more complicated things:
2. would it be possible to select a block of cells?
3. and maybe also to set a border for cell/block of cells?
 
I know, it looks like a wish list...;)
 
Regards
WojciechW
GeneralRe: Some more wishes...memberdarkoman13 Mar '06 - 20:33 
Hello...
 
thanks for you comment. Now, it wont be difficult to change the color of the single cell, but your next two requests ask for some additional time I must find to make it work in the way you like it. Hope to do it soon...
 
Regards...
GeneralRe: Some more wishes...memberwoj11713 Mar '06 - 22:28 
Hi darkoman,
thanks for fast reply. I wait for improvements I have ordered...;)
 
Regards
WojciechW
GeneralCDataGrid difficulties in SDImemberlukeevans8 Mar '06 - 23:49 
Hi Darkoman - nice piece of work. I have your grid working quite will in a test harness.
 
When I put the class into my MFC Doc/View, the SDI client window does not draw the grid. I know everyhting is working, because if I Create() the datagrid using the MainFrm (toolbar/status bar etc) as parent, I can see it drawing in the menu bar and status bars, well some of it anyway.
 
But when I set the CMyView.m_hWnd as parent on call to CDataGrid::Create() - nada drawing in the SDI client.
 
Can you kindly suggest what I might be missing?
 
int CTestGridView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
RECT rect = {50,50,700,300};
m_DG.Create( rect, m_hWnd, 5 );
};
 
void CTestGridView::OnInitialUpdate()
{
// Set dummy DataGrid column info, then
CView::OnInitialUpdate();
}
 
void CTestGridView::OnDraw(CDC* pDC)
{
CTestGridDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//nothing here since grid get WM_DRAW messages first as child. yes???
}
 

Many thanks

 
Luke
(may the source be with you)
GeneralRe: CDataGrid difficulties in SDImemberdarkoman12 Mar '06 - 19:31 
Hello...
 
you can put your creation code in OnInitialUpdate member function of the CView derived class and process WM_SIZE message of the main window (can be done also in CView derived class) calling Resize() member of the CDataGrid control.
You should see the grid drawing in the client area of the window.
 
Regards...
GeneralRe: CDataGrid difficulties in SDImemberlukeevans13 Mar '06 - 19:24 
Thanks, darkoman.
 
Yes that's right, I have it working now. Also, I wrote some extra code to callback the CMyView each time a Row is drawn, so the view can terminate the redraw.
 
This assists my application where I am using the CDataGrid to display time-stamped incoming messages from the serial port. The redraw operation should not slow down my application, so that is why I did this. After some quiet time I call back and complete the draw.
 
Regards
Luke
(may the source be with you)
GeneralSome improvesmemberWiseWarrior4 Jan '06 - 23:06 
Hi,
I wanna develope a program and i use VC++ + win32 and i really need a cool data grid. so after many search i found yours. but it seems that it has many bugs and doesn't support unicode! (i tested it). can you help me. is there any component like that (free one ) to help me or can we have a cooperation to edit it?
 
Best Wishes - Mohammad
mghalambor at gmail.com
GeneralRe: Some improvesmemberdarkoman5 Jan '06 - 1:03 
Thank you for your interest.
Yes, this control did have some bugs but they were fixed...
 

Now, I am sure that a similar thing can be found on the Internet (CodeProject or CodeGuru, maybe?), but if you are really interested in I am willing to help you develop a better-looking data grid control.
 

PS.
To get UNICODE work should not be so hard:
1) Hard-coded strings should be changed from "some_text" to _T("some_text")
2) All functions like e.g. strlen() should be written like e.g. _tcslen()
3) Also, fonts should be used that have different character-set mappings (e.g. don't use font like System, but like TimesNewRoman or Arial)
4) For UNICODE project compiling UNICODE pre-processor directive should be defined and not MBCS (Check on CodeProject or MSDN for details)
 

Best regards,
Darkoman
GeneralRe: Some improvesmemberWiseWarrior6 Jan '06 - 20:45 
Hi darkoman,
Thank u for your fast reply.
yes, i am so interested in your component and i hope to have no problem with that.
is the last version of it (already in code project) without bug?
why can't i have a grid with less than 6 rows!!!?
 
Best Wishes - Mohammad
GeneralRe: Some improvesmemberdarkoman6 Jan '06 - 21:39 
Hello...
 
well, I hope it is. If you find one, please tell me.
 
I didn't understand exactly the last thing you have written. I have downloaded the code and
chanded the number of created rows in WM_CREATE event of WndProc function of the main window
(I have put just 1 row) and everything went well.
 
So, please explain more...
 

 
Best regards,
Darkoman
GeneralAnother Bug too!memberLove In Snowing11 Jul '05 - 2:02 
When you select one cell to edit ,and then you click the "remove all" button, then the selected cell still appear the contents you inputed.
GeneralRe: Another Bug too!memberdarkoman21 Jul '05 - 1:20 
Was away for a while...
It will be soon repaired and working...
Thanks!
GeneralThis code does not work!memberPJ Arends10 Jul '05 - 11:45 
The code as presented here does not work. Just because it seems to compile does not mean it is stable. You use variables without initializing them, you use short variables to store long values, column resizing is prone to errors, cell editing does not work, etc.
 
While most code has some bugs that may only show up in certain unusual circumstances, this code has so many bugs that pop up with just a cursory test. The fact that it generates 28 warnings when compiled at warning level 4 should be enough of a clue that there is something wrong.
 
Your idea seems nice, and the grid looks good, but the code needs a lot of work.
 
1 Frown | :(
 


"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
 
"Obviously ???  You're definitely a superstar!!!" - mYkel - 21 Jun '04
 
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
 
Within you lies the power for good - Use it!
GeneralRe: This code does not work!memberdarkoman21 Jul '05 - 1:21 
Yes, it probably doesn't but...
Try again these days...
Thanks for comment!
GeneralAnother bugmemberDavid O'Neil9 Jul '05 - 8:49 
Another bug: Select collumn 0 to sort, then select collumn 1 to sort, then select collumn 0 to sort again: Access violation error - read of address 00000818. Great beginning to a useful item, though.
 
As far as the first bug that Kochise illuminated: you don't even have to select between collumn 0 and 1: simply resize collumn 1 to a negative width and collumn 0 becomes __*very*__ wide. Placing a 'minWidth' variable in would fix this behavior.
 
David
GeneralRe: Another bugmemberdarkoman21 Jul '05 - 1:23 
It will be repaired and will work...
Thanks!
Generalgood jobmemberbadpeos8 Jul '05 - 15:06 
it seems good in look.
but when i test it, the screen refresh a lot.
GeneralNice, but...memberKochise8 Jul '05 - 3:49 
7 warnings, from 'unreferenced local variables' to... err... 'not all control paths return a value' !
 
Select between Column0 and Column1, then drag the limit completely on the left, before Column0 (width == 0).
 
Select between Column1 and Column2, then drag the limit completely on the left, before Column0 (width == -width Column0).
 
Sort the lines with clicking the following clomuns header in the following order :
 
Column0 6 times
Column1
Column2
Column1
Column0
 
The message grid don't automatically scroll down when too much messages comes.
 
Would like to see a tree on Column0 if I want...
 
Beside all of this, you get my 4. Right now I suspend my vote, I'd like to give you a 5 Smile | :) Thanks for updating things... And debug more carefully, please :/
 
Kochise
 
In Code we trust !
GeneralRe: Nice, but...memberdarkoman21 Jul '05 - 1:24 
Good testing is as much important as good coding...
Thank you for the comment...
I'll try to fix as soon as possible...

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 5 Aug 2005
Article Copyright 2005 by darkoman
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid