|
|
Any idea how to get this to work with vs2010 pro .net 4.0, I get a steady stream of unresolved extern(s) with the api function calls. I was trying to include this in an existing VS2010 project. I also included <winuser.h> but no help
|
|
|
|
|
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.
|
|
|
|
|
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 )
{
if ( dgList->dg_Columns )
{
delete [] dgList->dg_Columns;
dgList->dg_Columns = NULL;
}
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;
}
free(dgList->dg_Rows);
dgList->dg_Rows = NULL;
if ( dgList->dg_hColumnFont )
{
DeleteObject(dgList->dg_hColumnFont);
dgList->dg_hColumnFont = NULL;
}
if ( dgList->dg_hRowFont )
{
DeleteObject(dgList->dg_hRowFont);
dgList->dg_hRowFont = NULL;
}
if ( dgList->dg_hBgBrush )
{
DeleteObject(dgList->dg_hBgBrush);
dgList->dg_hBgBrush = NULL;
}
if ( dgList->dg_hCellPen )
{
DeleteObject(dgList->dg_hCellPen);
dgList->dg_hCellPen = NULL;
}
if ( dgList->dg_hMemDC )
{
SelectObject( dgList->dg_hMemDC, dgList->dg_hOldMemBitmap );
DeleteDC(dgList->dg_hMemDC);
dgList->dg_hMemDC = NULL;
}
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...
|
|
|
|
|
Hi! Very great grid but i found out that it's not free _DG_ROW structures can you fix this bug?
|
|
|
|
|
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
|
|
|
|
|
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!!
|
|
|
|
|
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 );
|
|
|
|
|
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
{
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
{
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.
|
|
|
|
|
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
|
|
|
|
|
Hi darkoman,
Do you plan to continue development ?
When an updated and enhanced version will be released ?
Thanks
spyto
|
|
|
|
|
Hellow, the DataGrid is very useful, but how can I resize it when I resize the dialog?
Find the Way!
|
|
|
|
|
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.
|
|
|
|
|
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!
|
|
|
|
|
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!
|
|
|
|
|
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?
|
|
|
|
|
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.
|
|
|
|
|
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!
|
|
|
|
|
I have been resolved this question.
|
|
|
|
|
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!
|
|
|
|
|
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
|
|
|
|
|
Hello, thanks for your advice, now it works well in unicode! I'm so happy!
Find the Way!
|
|
|
|
|
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.
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|