#include "stdafx.h"
#include "DataGrid.h"
/* DataGrid global variables */
DG_LIST *g_DGList = NULL;
int g_DGGridNumber = 0;
CDataGrid::CDataGrid()
{
// Init DataGrid variables
m_hWnd = NULL;
m_hParentWnd = NULL;
}
CDataGrid::~CDataGrid()
{
}
void CDataGrid::Resize()
{
// Recalculate DataGrid relative size
RECT rectParent;
GetWindowRect( m_hParentWnd, &rectParent );
SetWindowPos( m_hWnd, HWND_NOTOPMOST, int((double(m_DGRect.left)/100.0)*(rectParent.right-rectParent.left)), int((double(m_DGRect.top)/100.0)*(rectParent.bottom-rectParent.top)),
int((double(m_DGRect.right)/100.0)*(rectParent.right-rectParent.left)), int((double(m_DGRect.bottom)/100.0)*(rectParent.bottom-rectParent.top)), SWP_NOZORDER | SWP_SHOWWINDOW );
RECT clientRect;
GetClientRect( m_hWnd, &clientRect );
RecalcWindow(m_hWnd);
InvalidateRect( m_hWnd, NULL, TRUE );
UpdateWindow(m_hWnd);
}
BOOL CDataGrid::Create(RECT wndRect, HWND hParent, int numCols)
{
BOOL result = FALSE;
// Set DatGrid parent window handle
m_hParentWnd = hParent;
// Calculate DataGrid relative offset and size
RECT rectParent;
GetWindowRect( hParent, &rectParent );
m_DGRect.left = int(100*double(wndRect.left)/double(rectParent.right-rectParent.left));
m_DGRect.top = int(100*double(wndRect.top)/double(rectParent.right-rectParent.left));
m_DGRect.right = int(100*double(wndRect.right-wndRect.left)/double(rectParent.right-rectParent.left));
m_DGRect.bottom = int(100*double(wndRect.bottom-wndRect.top)/double(rectParent.bottom-rectParent.top));
WNDCLASSEX wincl;
wincl.hInstance = GetModuleHandle(NULL);
wincl.lpszClassName = "DATAGRID";
wincl.lpfnWndProc = DataGridProc;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wincl.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
wincl.hCursor = LoadCursor( NULL, IDC_ARROW );
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
ATOM reg = RegisterClassEx(&wincl);
DWORD error = GetLastError();
// Register DataGrid window class
if ( ( reg ) || ( error == ERROR_CLASS_ALREADY_EXISTS ) )
{
// Create DataGrid window
m_hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, "DATAGRID", "", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL,
wndRect.left, wndRect.top, wndRect.right-wndRect.left, wndRect.bottom-wndRect.top, hParent, NULL, GetModuleHandle(NULL), NULL );
// Hide DataGrid window scroll bars
ShowScrollBar( m_hWnd, SB_BOTH, FALSE );
if ( m_hWnd )
{
AddDGGrid( m_hWnd, m_hParentWnd );
result = TRUE;
}
// Init DataGrid GDI objects
InitDGGlobals( hParent, m_hWnd );
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Init DataGrid columns info
if ( numCols < DG_MAXCOLUMN )
dgList->dg_ColumnNumber = numCols;
else
dgList->dg_ColumnNumber = DG_MAXCOLUMN;
dgList->dg_Columns = new DG_COLUMN[dgList->dg_ColumnNumber];
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
{
dgList->dg_Columns[i].columnWidth = 50;
dgList->dg_Columns[i].textAlign = DGTA_LEFT;
strcpy( dgList->dg_Columns[i].columnText, " " );
}
// Create EDIT control
dgList->dg_hEditWnd = CreateWindow( "EDIT", "", WS_CHILD | WS_CLIPSIBLINGS | ES_AUTOHSCROLL, 0, 0, 100, 20, m_hWnd, NULL, GetModuleHandle(NULL), NULL );
SendMessage( dgList->dg_hEditWnd, WM_SETFONT, (WPARAM)dgList->dg_hRowFont, MAKELPARAM(TRUE,0) );
}
}
return result;
}
HWND CDataGrid::GetWindowHandle()
{
// Return DataGrid window handle
return m_hWnd;
}
void InitDGGlobals(HWND hParent, HWND hWnd)
{
DG_LIST* dgList = GetDGGrid(hWnd);
if ( dgList != NULL )
{
// Create fonts
HDC hParentDC = GetDC(hParent);
LOGFONT lf;
lf.lfHeight = -MulDiv( 10, GetDeviceCaps(hParentDC,LOGPIXELSY), 72 );
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = FW_NORMAL;
lf.lfItalic = FALSE;
lf.lfUnderline = FALSE;
lf.lfStrikeOut = FALSE;
lf.lfCharSet = ANSI_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
strcpy( lf.lfFaceName, "Arial" );
dgList->dg_hColumnFont = CreateFontIndirect(&lf);
memcpy( &dgList->dg_LFColumnFont, &lf, sizeof(LOGFONT) );
lf.lfHeight = -MulDiv( 9, GetDeviceCaps(hParentDC,LOGPIXELSY), 72 );
dgList->dg_hRowFont = CreateFontIndirect(&lf);
memcpy( &dgList->dg_LFRowFont, &lf, sizeof(LOGFONT) );
ReleaseDC( hParent, hParentDC );
// Create background brush
LOGBRUSH lb;
lb.lbColor = DGBGR_COLOR;
lb.lbStyle = BS_SOLID;
dgList->dg_hBgBrush = CreateBrushIndirect(&lb);
// Create cell pen
LOGPEN lp;
lp.lopnColor = RGB(210,210,210);
lp.lopnStyle = PS_SOLID;
lp.lopnWidth.x = 1;
dgList->dg_hCellPen = CreatePenIndirect(&lp);
}
}
BOOL CDataGrid::SetColumnInfo(int columnIndex, char* columnText, int columnWidth, int textAlign)
{
BOOL result = FALSE;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Check column index
if ( columnIndex < dgList->dg_ColumnNumber )
{
// Set new DataGrid column info
strncpy( dgList->dg_Columns[columnIndex].columnText, columnText, 1024 );
dgList->dg_Columns[columnIndex].columnWidth = columnWidth;
dgList->dg_Columns[columnIndex].textAlign = textAlign;
dgList->dg_Columns[columnIndex].pressed = false;
result = TRUE;
}
}
return result;
}
BOOL CDataGrid::SetItemInfo(int rowIndex, int columnIndex, char* itemText, int textAlign, bool readOnly)
{
BOOL result = FALSE;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
if ( SetDGItemText( m_hWnd, rowIndex, columnIndex, itemText ) )
{
dgList->dg_Rows[rowIndex].textAlign[columnIndex] = textAlign;
if ( dgList->dg_EnableEdit )
dgList->dg_Rows[rowIndex].readOnly[columnIndex] = readOnly;
result = TRUE;
}
}
return result;
}
BOOL SetDGItemText(HWND hWnd, int rowIndex, int columnIndex, char* buffer)
{
BOOL result = FALSE;
DG_LIST* dgList = GetDGGrid(hWnd);
if ( dgList != NULL )
{
// Check column and row index
if ( ( columnIndex < dgList->dg_ColumnNumber ) && ( rowIndex < dgList->dg_RowNumber ) && ( buffer != NULL ) )
{
// Set DataGrid row info
if ( strlen(dgList->dg_Rows[rowIndex].rowText[columnIndex]) < strlen(buffer) )
{
delete dgList->dg_Rows[rowIndex].rowText[columnIndex];
dgList->dg_Rows[rowIndex].rowText[columnIndex] = new char[strlen(buffer)+1];
}
if ( strlen(buffer) == 0 )
strcpy( dgList->dg_Rows[rowIndex].rowText[columnIndex], " " );
else
strcpy( dgList->dg_Rows[rowIndex].rowText[columnIndex], buffer );
result = TRUE;
}
}
return result;
}
BOOL CDataGrid::SetItemInfo(DG_ITEMINFO* itemInfo)
{
BOOL result = FALSE;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
if ( ( itemInfo != NULL ) && ( itemInfo->dgItem < dgList->dg_RowNumber ) && ( itemInfo->dgSubitem < dgList->dg_ColumnNumber ) )
{
switch ( itemInfo->dgMask )
{
case DG_TEXTEDIT:
{
// Set DataGrid item text
SetDGItemText( m_hWnd, itemInfo->dgItem, itemInfo->dgSubitem, itemInfo->dgText );
}
break;
case DG_TEXTALIGN:
{
// Set DataGrid item text align
dgList->dg_Rows[itemInfo->dgItem].textAlign[itemInfo->dgSubitem] = itemInfo->dgTextAlign;
}
break;
case DG_TEXTHIGHLIGHT:
{
// Select DataGrid item
SelectItem( itemInfo->dgItem, itemInfo->dgSubitem );
}
break;
case DG_TEXTRONLY:
{
// Set DataGrid item edit mode
dgList->dg_Rows[itemInfo->dgItem].readOnly[itemInfo->dgSubitem] = itemInfo->dgReadOnly;
}
break;
case DG_TEXTBGCOLOR:
{
// Set DataGrid row background color
dgList->dg_Rows[itemInfo->dgItem].bgColor = itemInfo->dgBgColor;
}
break;
}
}
}
return result;
}
BOOL CDataGrid::GetItemText(int rowIndex, int columnIndex, char* buffer, int buffer_size)
{
BOOL result = GetDGItemText( m_hWnd, rowIndex, columnIndex, buffer, buffer_size );
return result;
}
BOOL GetDGItemText(HWND hWnd, int rowIndex, int columnIndex, char* buffer, int buffer_size)
{
BOOL result = FALSE;
// Clear return buffer
strcpy( buffer, "" );
DG_LIST* dgList = GetDGGrid(hWnd);
// Check column and row index
if ( ( columnIndex < dgList->dg_ColumnNumber ) && ( rowIndex < dgList->dg_RowNumber ) )
{
// Get DataGrid item text
strncpy( buffer, dgList->dg_Rows[rowIndex].rowText[columnIndex], buffer_size );
result = TRUE;
}
return result;
}
LRESULT CALLBACK DataGridProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
DG_LIST* dgList = GetDGGrid(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 );
}
}
break;
case WM_DESTROY:
{
// Delete DataGrid grid
DestroyDGGrid(hwnd);
}
break;
case WM_SIZE:
{
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != 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;
}
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 );
ReleaseDC( dgList->dg_hWnd, hDC );
}
}
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint( hwnd, &ps );
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != NULL )
{
// Draw DataGrid rows
DrawRows(dgList->dg_hWnd);
// Draw DataGrid columns
DrawColumns(dgList->dg_hWnd);
RECT clientRect;
GetClientRect( dgList->dg_hWnd, &clientRect );
BitBlt( ps.hdc, 0, 0, (clientRect.right-clientRect.left), (clientRect.bottom-clientRect.top), dgList->dg_hMemDC, 0, 0, SRCCOPY );
}
EndPaint( hwnd, &ps );
}
break;
case WM_ERASEBKGND:
{
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != NULL )
{
RECT clientRect;
GetClientRect( dgList->dg_hWnd, &clientRect );
FillRect( dgList->dg_hMemDC, &clientRect, dgList->dg_hBgBrush );
}
}
break;
case WM_HSCROLL:
{
switch ( LOWORD(wParam) )
{
case SB_LINERIGHT:
case SB_PAGERIGHT:
{
int OldPos = GetScrollPos( hwnd, SB_HORZ );
SetScrollPos( hwnd, SB_HORZ, OldPos+10, TRUE );
int NewPos = GetScrollPos( hwnd, SB_HORZ );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
}
break;
case SB_LINELEFT:
case SB_PAGELEFT:
{
int OldPos = GetScrollPos( hwnd, SB_HORZ );
SetScrollPos( hwnd, SB_HORZ, OldPos-10, TRUE );
int NewPos = GetScrollPos( hwnd, SB_HORZ );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
}
break;
case SB_THUMBTRACK:
{
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo( hwnd, SB_HORZ, &si );
int OldPos = si.nPos;
si.nPos = si.nTrackPos;
int NewPos = si.nPos;
SetScrollPos( hwnd, SB_HORZ, si.nPos, TRUE );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
}
break;
}
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList->dg_Edit )
{
int scrollX = GetScrollPos( hwnd, SB_HORZ );
int scrollY = GetScrollPos( hwnd, SB_VERT );
RECT columnRect, clientRect;
GetClientRect( hwnd, &clientRect );
GetColumnRect( hwnd, 0, &columnRect );
int offsetLeft = scrollX + clientRect.left;
int offsetRight = scrollX + (clientRect.right-clientRect.left);
int offsetTop = scrollY + clientRect.top + (columnRect.bottom-columnRect.top);
int offsetBottom = scrollY + (clientRect.bottom - clientRect.top);
if ( ( dgList->dg_EditRect.top >= offsetTop ) && ( dgList->dg_EditRect.bottom <= offsetBottom ) &&
( dgList->dg_EditRect.right >= offsetLeft ) && ( dgList->dg_EditRect.left <= offsetRight ) )
{
SetWindowPos( dgList->dg_hEditWnd, HWND_NOTOPMOST, dgList->dg_EditRect.left-scrollX, dgList->dg_EditRect.top-scrollY, dgList->dg_EditRect.right-dgList->dg_EditRect.left, dgList->dg_EditRect.bottom-dgList->dg_EditRect.top, SWP_NOZORDER | SWP_SHOWWINDOW );
SetFocus(dgList->dg_hEditWnd);
}
else
ShowWindow( dgList->dg_hEditWnd, SW_HIDE );
}
}
break;
case WM_VSCROLL:
{
switch ( LOWORD(wParam) )
{
case SB_LINEUP:
{
RECT rowRect;
GetRowRect( hwnd, 0, &rowRect );
int OldPos = GetScrollPos( hwnd, SB_VERT );
int diff = (rowRect.bottom-rowRect.top) - 1;
SetScrollPos( hwnd, SB_VERT, OldPos-diff, TRUE );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
}
break;
case SB_PAGEUP:
{
RECT rowRect, clientRect;
GetRowRect( hwnd, 0, &rowRect );
GetClientRect( hwnd, &clientRect );
int OldPos = GetScrollPos( hwnd, SB_VERT );
int diff = (clientRect.bottom-clientRect.top) / (rowRect.bottom-rowRect.top-1) - 2;
diff *= (rowRect.bottom-rowRect.top-1);
SetScrollPos( hwnd, SB_VERT, OldPos-diff, TRUE );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
}
break;
case SB_LINEDOWN:
{
RECT rowRect;
GetRowRect( hwnd, 0, &rowRect );
int OldPos = GetScrollPos( hwnd, SB_VERT );
int diff = (rowRect.bottom-rowRect.top) - 1;
SetScrollPos( hwnd, SB_VERT, OldPos+diff, TRUE );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
}
break;
case SB_PAGEDOWN:
{
RECT rowRect, clientRect;
GetRowRect( hwnd, 0, &rowRect );
GetClientRect( hwnd, &clientRect );
int OldPos = GetScrollPos( hwnd, SB_VERT );
int diff = (clientRect.bottom-clientRect.top) / (rowRect.bottom-rowRect.top-1) - 2;
diff *= (rowRect.bottom-rowRect.top-1);
SetScrollPos( hwnd, SB_VERT, OldPos+diff, TRUE );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
}
break;
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;
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);
}
break;
}
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList->dg_Edit )
{
int scrollX = GetScrollPos( hwnd, SB_HORZ );
int scrollY = GetScrollPos( hwnd, SB_VERT );
RECT columnRect, clientRect;
GetClientRect( hwnd, &clientRect );
GetColumnRect( hwnd, 0, &columnRect );
int offsetLeft = scrollX + clientRect.left;
int offsetRight = scrollX + (clientRect.right-clientRect.left);
int offsetTop = scrollY + clientRect.top + (columnRect.bottom-columnRect.top);
int offsetBottom = scrollY + (clientRect.bottom - clientRect.top);
if ( ( dgList->dg_EditRect.top >= offsetTop ) && ( dgList->dg_EditRect.bottom <= offsetBottom ) &&
( dgList->dg_EditRect.right >= offsetLeft ) && ( dgList->dg_EditRect.left <= offsetRight ) )
{
SetWindowPos( dgList->dg_hEditWnd, HWND_NOTOPMOST, dgList->dg_EditRect.left-scrollX, dgList->dg_EditRect.top-scrollY, dgList->dg_EditRect.right-dgList->dg_EditRect.left, dgList->dg_EditRect.bottom-dgList->dg_EditRect.top, SWP_NOZORDER | SWP_SHOWWINDOW );
SetFocus(dgList->dg_hEditWnd);
}
else
ShowWindow( dgList->dg_hEditWnd, SW_HIDE );
}
}
break;
case WM_MOUSEWHEEL:
{
short int zDelta = (short)HIWORD(wParam);
if ( zDelta > 0 )
{
// Scroll page up
int scrollCode = SB_PAGEUP;
short int pos = GetScrollPos( hwnd, SB_VERT );
SendMessage( hwnd, WM_VSCROLL, MAKEWPARAM(scrollCode,pos), (LPARAM)NULL );
}
else
{
// Scroll page down
int scrollCode = SB_PAGEDOWN;
short int pos = GetScrollPos( hwnd, SB_VERT );
SendMessage( hwnd, WM_VSCROLL, MAKEWPARAM(scrollCode,pos), (LPARAM)NULL );
}
}
break;
case WM_LBUTTONDOWN:
{
int scrollX = GetScrollPos( hwnd, SB_HORZ );
int scrollY = GetScrollPos( hwnd, SB_VERT );
int xPos = LOWORD(lParam) + scrollX;
int yPos = HIWORD(lParam) + scrollY;
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != NULL )
{
if ( dgList->dg_Edit )
{
char text[1024];
SendMessage( dgList->dg_hEditWnd, WM_GETTEXT, (WPARAM)1024, (LPARAM)text );
ShowWindow( dgList->dg_hEditWnd, SW_HIDE );
dgList->dg_Edit = FALSE;
SetDGItemText( hwnd, dgList->dg_SelectedRow, dgList->dg_SelectedColumn, text );
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_ITEMTEXTCHANGED), (LPARAM)hwnd );
}
// Check for resized columns
RECT rect;
if ( dgList->dg_Resize == FALSE )
dgList->dg_Resize = CheckColumnResize( hwnd, xPos, yPos, &dgList->dg_Column, &rect );
// Check for clicked columns
if ( !dgList->dg_Resize )
dgList->dg_Click = CheckColumnClick( hwnd, xPos, yPos, &dgList->dg_Column );
if ( dgList->dg_Click )
dgList->dg_Columns[dgList->dg_Column].pressed = true;
// Check for selected rows
if ( !dgList->dg_Click )
{
if ( CheckRows( hwnd, xPos, yPos, &dgList->dg_Row ) )
{
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_ITEMCHANGED), (LPARAM)hwnd );
}
}
InvalidateRect( hwnd, NULL, FALSE );
UpdateWindow(hwnd);
SetFocus(hwnd);
// Capture mouse
SetCapture(hwnd);
}
}
break;
case WM_LBUTTONUP:
{
int scrollX = GetScrollPos( hwnd, SB_HORZ );
int scrollY = GetScrollPos( hwnd, SB_VERT );
int xPos = LOWORD(lParam) + scrollX;
int yPos = HIWORD(lParam) + scrollY;
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != NULL )
{
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
dgList->dg_Columns[i].pressed = false;
if ( dgList->dg_Resize )
{
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_COLUMNRESIZED), (LPARAM)hwnd );
}
RECT rect;
dgList->dg_Resize = FALSE;
if ( ( dgList->dg_Click ) && ( dgList->dg_EnableSort ) )
{
SortDGItems( hwnd, dgList->dg_Column );
dgList->dg_Click = FALSE;
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_COLUMNCLICKED), (LPARAM)hwnd );
}
dgList->dg_Cursor = CheckColumnResize( hwnd, xPos, yPos, &dgList->dg_Column, &rect );
InvalidateRect( hwnd, NULL, FALSE );
UpdateWindow(hwnd);
// Release mouse
ReleaseCapture();
}
}
break;
case WM_NCLBUTTONUP:
{
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != NULL )
{
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
dgList->dg_Columns[i].pressed = false;
if ( dgList->dg_Resize )
{
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_COLUMNRESIZED), (LPARAM)hwnd );
}
dgList->dg_Resize = FALSE;
if ( ( dgList->dg_Click ) && ( dgList->dg_EnableSort ) )
{
SortDGItems( hwnd, dgList->dg_Column );
dgList->dg_Click = FALSE;
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_COLUMNCLICKED), (LPARAM)hwnd );
}
InvalidateRect( hwnd, NULL, FALSE );
UpdateWindow(hwnd);
}
}
break;
case WM_LBUTTONDBLCLK:
{
DG_LIST* dgList = GetDGGrid(hwnd);
if ( ( dgList != NULL ) && ( dgList->dg_EnableEdit ) )
{
int scrollX = GetScrollPos( hwnd, SB_HORZ );
int scrollY = GetScrollPos( hwnd, SB_VERT );
RECT columnRect, clientRect;
GetClientRect( hwnd, &clientRect );
GetColumnRect( hwnd, 0, &columnRect );
int offsetLeft = scrollX + clientRect.left;
int offsetRight = scrollX + (clientRect.right-clientRect.left);
int offsetTop = scrollY + clientRect.top + (columnRect.bottom-columnRect.top);
int offsetBottom = scrollY + (clientRect.bottom - clientRect.top);
GetCellRect( hwnd, &dgList->dg_EditRect );
if ( ( dgList->dg_EditRect.top >= offsetTop ) && ( dgList->dg_EditRect.bottom <= offsetBottom ) &&
( dgList->dg_EditRect.right >= offsetLeft ) && ( dgList->dg_EditRect.left <= offsetRight ) )
{
if ( !dgList->dg_Rows[dgList->dg_SelectedRow].readOnly[dgList->dg_SelectedColumn] )
{
if ( CheckRows( hwnd, LOWORD(lParam) + scrollX, HIWORD(lParam) + scrollY, &dgList->dg_Row ) )
{
char text[1024];
GetDGItemText( hwnd, dgList->dg_SelectedRow, dgList->dg_SelectedColumn, text, 1024 );
SetWindowPos( dgList->dg_hEditWnd, HWND_NOTOPMOST, dgList->dg_EditRect.left-scrollX, dgList->dg_EditRect.top-scrollY, dgList->dg_EditRect.right-dgList->dg_EditRect.left, dgList->dg_EditRect.bottom-dgList->dg_EditRect.top, SWP_NOZORDER | SWP_SHOWWINDOW );
SendMessage( dgList->dg_hEditWnd, WM_SETTEXT, (WPARAM)0, (LPARAM)(LPCTSTR)text );
SetFocus(dgList->dg_hEditWnd);
dgList->dg_Edit = TRUE;
}
}
}
}
}
break;
case WM_MOUSEMOVE:
{
int scrollX = GetScrollPos( hwnd, SB_HORZ );
int scrollY = GetScrollPos( hwnd, SB_VERT );
int xPos = LOWORD(lParam) + scrollX;
int yPos = HIWORD(lParam) + scrollY;
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != NULL )
{
int oldSize, newSize;
RECT rect;
if ( wParam == MK_LBUTTON )
{
if ( ( dgList->dg_Resize ) && ( dgList->dg_EnableResize ) )
{
// Get column rectangle
GetColumnRect( hwnd, dgList->dg_Column, &rect );
RECT wndRect;
GetWindowRect( hwnd, &wndRect );
POINT pt = {LOWORD(lParam), HIWORD(lParam)};
if ( ( pt.x >= 0 ) && ( pt.x <= 2000 ) )
{
// Calculate new column size
oldSize = rect.right - rect.left;
newSize = xPos - rect.left;
if ( newSize < 0 )
newSize = 2;
// Resize DataGrid column
dgList->dg_Columns[dgList->dg_Column].columnWidth = newSize;
RecalcWindow(hwnd);
RECT clientRect, columnRect;
GetColumnRect( hwnd, 0, &columnRect );
GetClientRect( hwnd, &clientRect );
clientRect.top += (columnRect.bottom-columnRect.top);
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
dgList->dg_Cursor = TRUE;
}
}
else
dgList->dg_Cursor = FALSE;
}
else if ( dgList->dg_EnableResize )
dgList->dg_Cursor = CheckColumnResize( hwnd, xPos, yPos, &dgList->dg_Column, &rect );
}
}
break;
case WM_SETCURSOR:
{
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != NULL )
{
// Check cursor flag
if ( ( dgList->dg_Cursor ) && ( LOWORD(lParam) == HTCLIENT ) )
SetCursor(LoadCursor(NULL, IDC_SIZEWE));
else
SetCursor(LoadCursor(NULL, IDC_ARROW));
}
}
break;
case WM_KEYDOWN:
{
DG_LIST* dgList = GetDGGrid(hwnd);
if ( dgList != NULL )
{
if ( dgList->dg_Selected != NULL )
{
/* KEY_DOWN pressed */
if ( int(wParam) == 40 )
{
// Select next item
SelectNextItem( hwnd, dgList->dg_Selected );
EnsureVisible( hwnd, dgList->dg_SelectedRow, dgList->dg_SelectedColumn );
}
/* KEY_UP pressed */
else if ( int(wParam) == 38 )
{
// Select previous item
SelectPreviousItem( hwnd, dgList->dg_Selected );
EnsureVisible( hwnd, dgList->dg_SelectedRow, dgList->dg_SelectedColumn );
}
/* KEY_LEFT pressed */
else if ( int(wParam) == 37 )
{
// Select previous subitem
SelectPreviousSubitem(hwnd);
EnsureVisible( hwnd, dgList->dg_SelectedRow, dgList->dg_SelectedColumn );
}
/* KEY_RIGHT pressed */
else if ( int(wParam) == 39 )
{
// Select next subitem
SelectNextSubitem(hwnd);
EnsureVisible( hwnd, dgList->dg_SelectedRow, dgList->dg_SelectedColumn );
}
/* KEY_PAGEUP pressed */
else if ( int(wParam) == 33 )
{
// Scroll page up
int scrollCode = SB_PAGEUP;
short int pos = GetScrollPos( hwnd, SB_VERT );
SendMessage( hwnd, WM_VSCROLL, MAKEWPARAM(scrollCode,pos), (LPARAM)NULL );
}
/* KEY_PAGEDOWN pressed */
else if ( int(wParam) == 34 )
{
// Scroll page up
int scrollCode = SB_PAGEDOWN;
short int pos = GetScrollPos( hwnd, SB_VERT );
SendMessage( hwnd, WM_VSCROLL, MAKEWPARAM(scrollCode,pos), (LPARAM)NULL );
}
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_ITEMCHANGED), (LPARAM)hwnd );
InvalidateRect( hwnd, NULL, TRUE );
UpdateWindow(hwnd);
}
}
}
break;
default:
return DefWindowProc( hwnd, message, wParam, lParam );
}
return 0;
}
void DrawColumns(HWND hWnd)
{
int offsetX=0, offsetY=0;
RECT rect;
SIZE size;
TEXTMETRIC tm;
DRAWTEXTPARAMS dtp;
dtp.cbSize = sizeof(DRAWTEXTPARAMS);
dtp.iLeftMargin = 5;
dtp.iRightMargin = 5;
dtp.iTabLength = 0;
// Find DataGrid
DG_LIST* dgList = GetDGGrid(hWnd);
HDC hDC = dgList->dg_hMemDC;
int scrollX = GetScrollPos( hWnd, SB_HORZ );
offsetX -= scrollX;
HFONT hOldFont = (HFONT)SelectObject( hDC, dgList->dg_hColumnFont );
COLORREF oldTxtColor = SetTextColor( hDC, dgList->dg_ColumnTextColor );
SetBkMode( hDC, TRANSPARENT );
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
{
// Get column text dimensions
GetTextExtentPoint( hDC, dgList->dg_Columns[i].columnText, strlen(dgList->dg_Columns[i].columnText), &size );
GetTextMetrics( hDC, &tm );
// Set column rectangle
rect.left = offsetX;
rect.top = offsetY;
rect.right = rect.left + dgList->dg_Columns[i].columnWidth;
rect.bottom = rect.top + size.cy + tm.tmInternalLeading;
offsetX = rect.right;
if ( dgList->dg_EnableSort )
{
// Draw sorting column
if ( !dgList->dg_Columns[i].pressed )
DrawFrameControl( hDC, &rect, DFC_BUTTON, DFCS_BUTTONPUSH );
else
DrawFrameControl( hDC, &rect, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_FLAT );
}
else
{
// Draw non-sorting column
rect.bottom += 2;
DrawEdge( hDC, &rect, EDGE_ETCHED, BF_RECT | BF_MIDDLE | BF_ADJUST );
}
// Draw column text
DrawTextEx( hDC, dgList->dg_Columns[i].columnText, strlen(dgList->dg_Columns[i].columnText), &rect, dgList->dg_Columns[i].textAlign | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS, &dtp );
}
SetTextColor( hDC, oldTxtColor );
SetBkMode( hDC, OPAQUE );
SelectObject( hDC, hOldFont );
}
void DrawRows(HWND hWnd)
{
int offsetX=0, offsetY=0, offY=0;
RECT rect, colRect, clientRect;
SIZE size;
TEXTMETRIC tm;
DRAWTEXTPARAMS dtp;
dtp.cbSize = sizeof(DRAWTEXTPARAMS);
dtp.iLeftMargin = 5;
dtp.iRightMargin = 5;
dtp.iTabLength = 0;
// Find DataGrid
DG_LIST* dgList = GetDGGrid(hWnd);
HDC hDC = dgList->dg_hMemDC;
GetClientRect( hWnd, &clientRect );
int scrollX = GetScrollPos( hWnd, SB_HORZ );
offsetX -= scrollX+1;
int scrollY = GetScrollPos( hWnd, SB_VERT );
offY -= scrollY;
// Get column rectangle
GetColumnRect( hWnd, 0, &colRect );
offsetY += (colRect.bottom - colRect.top) - 1;
HFONT hOldFont = (HFONT)SelectObject( hDC, dgList->dg_hRowFont );
HPEN hOldPen;
HPEN hBgPen = CreatePen( PS_SOLID, 1, DGBGR_COLOR );
if ( dgList->dg_EnableGrid )
hOldPen = (HPEN)SelectObject( hDC, dgList->dg_hCellPen );
else
hOldPen = (HPEN)SelectObject( hDC, hBgPen );
COLORREF oldTxtColor = SetTextColor( hDC, dgList->dg_RowTextColor );
SetBkMode( hDC, TRANSPARENT );
// Get row clipping boundaries
RECT rRect, cRect;
GetRowRect( hWnd, 0, &rRect );
GetClientRect( hWnd, &cRect );
int rowOffsetT = scrollY / (rRect.bottom-rRect.top-1);
if ( ( scrollY % (rRect.bottom-rRect.top-1) != 0 ) && ( rowOffsetT > 0 ) )
rowOffsetT--;
offY += rowOffsetT*(rRect.bottom-rRect.top-1);
int rowOffsetB = (scrollY + cRect.bottom-cRect.top) / (rRect.bottom-rRect.top-1);
if ( rowOffsetB > dgList->dg_RowNumber )
rowOffsetB = dgList->dg_RowNumber;
for ( int i=rowOffsetT; i<rowOffsetB; i++ )
{
for ( int j=0; j<dgList->dg_ColumnNumber; j++ )
{
// Get column rectangle
GetColumnRect( hWnd, j, &colRect );
// Get row text dimensions
GetTextExtentPoint( hDC, dgList->dg_Rows[i].rowText[j], strlen(dgList->dg_Rows[i].rowText[j]), &size );
GetTextMetrics( hDC, &tm );
// Set row rectangle
rect.left = offsetX;
rect.top = offsetY + offY;
rect.right = rect.left + (colRect.right-colRect.left+1);
rect.bottom = rect.top + size.cy + tm.tmInternalLeading;
offsetX = rect.right - 1;
// If item is full or partially visible
if ( ( ( rect.top >= offsetY ) && ( rect.bottom <= clientRect.bottom ) ) ||
( ( rect.top < clientRect.bottom ) && ( rect.bottom > clientRect.bottom ) ) ||
( ( rect.top < offsetY ) && ( rect.bottom > offsetY ) ) )
{
// Check if row is selected
if ( dgList->dg_Rows[i].selected == false )
{
// Draw row
HBRUSH hBgBrush;
if ( !dgList->dg_Rows[i].readOnly[j] )
hBgBrush = CreateSolidBrush(dgList->dg_Rows[i].bgColor);
else
hBgBrush = CreateSolidBrush(DGRONLY_COLOR);
HBRUSH hOldBrush = (HBRUSH)SelectObject( hDC, hBgBrush );
Rectangle( hDC, rect.left, rect.top, rect.right, rect.bottom );
SelectObject( hDC, hOldBrush );
DeleteObject(hBgBrush);
// Draw row text
DrawTextEx( hDC, dgList->dg_Rows[i].rowText[j], strlen(dgList->dg_Rows[i].rowText[j]), &rect, dgList->dg_Rows[i].textAlign[j] | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS, &dtp );
}
else
{
// Draw row
HBRUSH hSelectionBrush = CreateSolidBrush(RGB(220,230,250));
HBRUSH hOldBrush = (HBRUSH)SelectObject( hDC, hSelectionBrush );
Rectangle( hDC, rect.left, rect.top, rect.right, rect.bottom );
SelectObject( hDC, hOldBrush );
DeleteObject(hSelectionBrush);
// Draw row text
COLORREF oldTextColor = SetTextColor( hDC, RGB(130,130,130) );
DrawTextEx( hDC, dgList->dg_Rows[i].rowText[j], strlen(dgList->dg_Rows[i].rowText[j]), &rect, dgList->dg_Rows[i].textAlign[j] | DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS, &dtp );
SetTextColor( hDC, oldTextColor );
}
if ( ( j == dgList->dg_SelectedColumn ) && ( i == dgList->dg_SelectedRow ) )
{
// Draw focus
RECT focusRect = rect;
focusRect.left += 1;
focusRect.right -= 1;
focusRect.top += 1;
focusRect.bottom -= 1;
DrawFocusRect( hDC, &focusRect );
}
}
}
offsetX = -scrollX-1;
offY += (rect.bottom - rect.top) - 1;
}
DeleteObject(hBgPen);
SetTextColor( hDC, oldTxtColor );
SetBkMode( hDC, OPAQUE );
SelectObject( hDC, hOldPen );
SelectObject( hDC, hOldFont );
}
BOOL CheckColumnResize(HWND hWnd, int x, int y, int* col, RECT* colRect)
{
BOOL result = FALSE;
RECT rect;
SIZE size;
int offsetX=0, offsetY=0;
TEXTMETRIC tm;
DG_LIST* dgList = GetDGGrid(hWnd);
HDC hDC = GetDC(hWnd);
int scrollY = GetScrollPos( hWnd, SB_VERT );
offsetY += scrollY;
HFONT hOldFont = (HFONT)SelectObject( hDC, dgList->dg_hColumnFont );
dgList->dg_Cursor = FALSE;
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
{
GetTextExtentPoint( hDC, dgList->dg_Columns[i].columnText, strlen(dgList->dg_Columns[i].columnText), &size );
GetTextMetrics( hDC, &tm );
rect.left = offsetX;
rect.top = offsetY;
rect.right = rect.left + dgList->dg_Columns[i].columnWidth;
rect.bottom = rect.top + size.cy + tm.tmInternalLeading;
offsetX = rect.right;
// Check mouse position
if ( ( abs(rect.right-x) < 3 ) && ( rect.top <= y ) && ( rect.bottom >= y ) )
{
*col = i;
*colRect = rect;
result = TRUE;
break;
}
}
SelectObject( hDC, hOldFont );
ReleaseDC( hWnd, hDC );
return result;
}
BOOL CheckColumnClick(HWND hWnd, int x, int y, int* col)
{
BOOL result = FALSE;
POINT pt = {x, y};
RECT rect;
SIZE size;
int offsetX=0, offsetY=0;
TEXTMETRIC tm;
DG_LIST* dgList = GetDGGrid(hWnd);
HDC hDC = GetDC(hWnd);
*col = -1;
int scrollY = GetScrollPos( hWnd, SB_VERT );
offsetY += scrollY;
HFONT hOldFont = (HFONT)SelectObject( hDC, dgList->dg_hColumnFont );
dgList->dg_Cursor = FALSE;
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
{
GetTextExtentPoint( hDC, dgList->dg_Columns[i].columnText, strlen(dgList->dg_Columns[i].columnText), &size );
GetTextMetrics( hDC, &tm );
rect.left = offsetX;
rect.top = offsetY;
rect.right = rect.left + dgList->dg_Columns[i].columnWidth;
rect.bottom = rect.top + size.cy + tm.tmInternalLeading;
offsetX = rect.right;
// Check mouse position
if ( PtInRect( &rect, pt ) )
{
*col = i;
result = TRUE;
break;
}
}
SelectObject( hDC, hOldFont );
ReleaseDC( hWnd, hDC );
return result;
}
void GetColumnRect(HWND hWnd, int col, RECT* colRect)
{
SIZE size;
int offsetX=0, offsetY=0;
TEXTMETRIC tm;
// Find DataGrid
DG_LIST* dgList = GetDGGrid(hWnd);
HDC hDC = GetDC(hWnd);
HFONT hOldFont = (HFONT)SelectObject( hDC, dgList->dg_hColumnFont );
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
{
GetTextExtentPoint( hDC, dgList->dg_Columns[i].columnText, strlen(dgList->dg_Columns[i].columnText), &size );
GetTextMetrics( hDC, &tm );
if ( i == col )
{
colRect->left = offsetX;
colRect->top = offsetY;
colRect->right = colRect->left + dgList->dg_Columns[i].columnWidth;
colRect->bottom = colRect->top + size.cy + tm.tmInternalLeading;
if ( !dgList->dg_EnableSort )
colRect->bottom += 2;
break;
}
offsetX += dgList->dg_Columns[i].columnWidth;
}
SelectObject( hDC, hOldFont );
ReleaseDC( hWnd, hDC );
}
int CDataGrid::GetResizedColumn()
{
int result;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
result = dgList->dg_Column;
// Return resized column
return result;
}
void GetRowRect(HWND hWnd, int row, RECT* rowRect)
{
int offsetX=0, offsetY=0;
RECT colRect;
SIZE size;
TEXTMETRIC tm;
DRAWTEXTPARAMS dtp;
dtp.cbSize = sizeof(DRAWTEXTPARAMS);
dtp.iLeftMargin = 5;
dtp.iRightMargin = 5;
dtp.iTabLength = 0;
DG_LIST* dgList = GetDGGrid(hWnd);
HDC hDC = GetDC(hWnd);
int scrollX = GetScrollPos( hWnd, SB_HORZ );
offsetX -= scrollX;
// Get column rectangle
GetColumnRect( hWnd, 0, &colRect );
offsetY += (colRect.bottom - colRect.top) - 1;
HFONT hOldFont = (HFONT)SelectObject( hDC, dgList->dg_hRowFont );
HPEN hOldPen = (HPEN)SelectObject( hDC, dgList->dg_hCellPen );
SetBkMode( hDC, TRANSPARENT );
for ( int i=0; i<dgList->dg_RowNumber; i++ )
{
// Get row text dimensions
GetTextExtentPoint( hDC, dgList->dg_Rows[i].rowText[0], strlen(dgList->dg_Rows[i].rowText[0]), &size );
GetTextMetrics( hDC, &tm );
if ( i == row )
{
// Get row rectangle
rowRect->left = offsetX;
rowRect->top = offsetY;
rowRect->right = rowRect->left + dgList->dg_Columns[0].columnWidth;
rowRect->bottom = rowRect->top + size.cy + tm.tmInternalLeading;
break;
}
offsetY += (rowRect->bottom - rowRect->top) - 1;
}
SetBkMode( hDC, OPAQUE );
SelectObject( hDC, hOldPen );
SelectObject( hDC, hOldFont );
ReleaseDC( hWnd, hDC );
}
BOOL CheckRows(HWND hWnd, int x, int y, int* row)
{
BOOL result = FALSE;
DG_LIST* dgList = GetDGGrid(hWnd);
HDC hDC = GetDC(hWnd);
*row = -1;
if ( dgList->dg_Resize )
return result;
// Clear selection
dgList->dg_Selected = NULL;
dgList->dg_SelectedRow = -1;
dgList->dg_SelectedColumn = -1;
int offsetX=0, offsetY=0, offY=0;
RECT rect, colRect;
SIZE size;
TEXTMETRIC tm;
DRAWTEXTPARAMS dtp;
dtp.cbSize = sizeof(DRAWTEXTPARAMS);
dtp.iLeftMargin = 5;
dtp.iRightMargin = 5;
dtp.iTabLength = 0;
int scrollX = GetScrollPos( hWnd, SB_HORZ );
offsetX -= scrollX;
int scrollY = GetScrollPos( hWnd, SB_VERT );
offY -= scrollY;
POINT pt = {x-scrollX, y};
// Get column rectangle
GetColumnRect( hWnd, 0, &colRect );
offsetY += (colRect.bottom - colRect.top) - 1;
HFONT hOldFont = (HFONT)SelectObject( hDC, dgList->dg_hRowFont );
HPEN hOldPen = (HPEN)SelectObject( hDC, dgList->dg_hCellPen );
SetBkMode( hDC, TRANSPARENT );
bool found = false;
DG_ROW *curr = dgList->dg_Rows;
int rowInd = 0;
for ( int j=0; j<dgList->dg_RowNumber; j++ )
{
// Reset row selection flag
dgList->dg_Rows[j].selected = false;
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
{
// Get row text dimensions
GetTextExtentPoint( hDC, dgList->dg_Rows[j].rowText[i], strlen(dgList->dg_Rows[j].rowText[i]), &size );
GetTextMetrics( hDC, &tm );
// Set row rectangle
rect.left = offsetX;
rect.top = offsetY;
rect.right = rect.left + dgList->dg_Columns[i].columnWidth;
rect.bottom = rect.top + size.cy + tm.tmInternalLeading;
offsetX = rect.right - 1;
// Check if row is selected
if ( ( PtInRect( &rect, pt ) ) && ( found == false ) )
{
*row = rowInd;
dgList->dg_Rows[j].selected = true;
found = true;
// Mark selection
dgList->dg_Selected = &dgList->dg_Rows[j];
dgList->dg_SelectedRow = j;
dgList->dg_SelectedColumn = i;
result = TRUE;
}
}
offsetX = -scrollX;
offsetY += (rect.bottom - rect.top) - 1;
rowInd++;
}
SetBkMode( hDC, OPAQUE );
SelectObject( hDC, hOldPen );
SelectObject( hDC, hOldFont );
ReleaseDC( hWnd, hDC );
return result;
}
void RecalcWindow(HWND hWnd)
{
int sizeX = 0;
int sizeY = 0;
DG_LIST* dgList = GetDGGrid(hWnd);
if ( dgList != NULL )
{
// Get DataGrid window rectangle
RECT rect;
GetClientRect( hWnd, &rect );
for ( int i=0; i<dgList->dg_ColumnNumber; i++ )
{
// Calculate total columns width
sizeX += dgList->dg_Columns[i].columnWidth;
}
// Check horizontal scroll bar visibility
int scrollDiff = (rect.right - rect.left) - sizeX;
if ( scrollDiff < 0 )
{
// 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;
si.nPage = si.nMax - si.nMin + 1 - abs(scrollDiff);
si.nTrackPos = 0;
SetScrollInfo( hWnd, SB_HORZ, &si, TRUE );
ShowScrollBar( hWnd, SB_HORZ, TRUE );
}
else
ShowScrollBar( hWnd, SB_HORZ, FALSE );
if ( dgList->dg_RowNumber > 0 )
{
RECT colRect, rowRect;
DRAWTEXTPARAMS dtp;
dtp.cbSize = sizeof(DRAWTEXTPARAMS);
dtp.iLeftMargin = 5;
dtp.iRightMargin = 5;
dtp.iTabLength = 0;
// Get column rectangle
GetColumnRect( hWnd, 0, &colRect );
sizeY += (colRect.bottom - colRect.top) - 1;
// Get row rectangle
GetRowRect( hWnd, 0, &rowRect );
sizeY += dgList->dg_RowNumber * (rowRect.bottom-rowRect.top-1) + 1;
// Check vertical scroll bar visibility
scrollDiff = (rect.bottom - rect.top) - sizeY;
if ( scrollDiff < 0 )
{
// 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;
si.nPage = si.nMax - si.nMin + 1 - abs(scrollDiff);
si.nTrackPos = 0;
SetScrollInfo( hWnd, SB_VERT, &si, TRUE );
ShowScrollBar( hWnd, SB_VERT, TRUE );
}
else
ShowScrollBar( hWnd, SB_VERT, FALSE );
}
else
ShowScrollBar( hWnd, SB_VERT, FALSE );
}
}
BOOL CDataGrid::InsertItem(char* itemText, int textAlign)
{
BOOL result = FALSE;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
if ( dgList->dg_RowNumber < DG_MAXROW )
{
dgList->dg_RowNumber++;
if ( dgList->dg_Rows == NULL )
dgList->dg_Rows = (DG_ROW*)malloc(dgList->dg_RowNumber*sizeof(DG_ROW));
else
dgList->dg_Rows = (DG_ROW*)realloc(dgList->dg_Rows, dgList->dg_RowNumber*sizeof(DG_ROW));
dgList->dg_Rows[dgList->dg_RowNumber-1].rowText = new char*[dgList->dg_ColumnNumber];
dgList->dg_Rows[dgList->dg_RowNumber-1].textAlign = new int[dgList->dg_ColumnNumber];
dgList->dg_Rows[dgList->dg_RowNumber-1].readOnly = new bool[dgList->dg_ColumnNumber];
for ( int j=0; j<dgList->dg_ColumnNumber; j++ )
{
dgList->dg_Rows[dgList->dg_RowNumber-1].rowText[j] = new char[strlen(itemText)+1];
strcpy( dgList->dg_Rows[dgList->dg_RowNumber-1].rowText[j], " " );
dgList->dg_Rows[dgList->dg_RowNumber-1].textAlign[j] = textAlign;
dgList->dg_Rows[dgList->dg_RowNumber-1].readOnly[j] = false;
}
strcpy( dgList->dg_Rows[dgList->dg_RowNumber-1].rowText[0], itemText );
dgList->dg_Rows[dgList->dg_RowNumber-1].selected = false;
dgList->dg_Rows[dgList->dg_RowNumber-1].bgColor = DGBGR_COLOR;
result = TRUE;
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_ITEMADDED), (LPARAM)m_hWnd );
}
}
return result;
}
BOOL CDataGrid::RemoveItem(int row)
{
BOOL result = FALSE;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( ( row >= 0 ) && ( row < dgList->dg_RowNumber ) )
{
dgList->dg_RowNumber--;
if ( row <= dgList->dg_RowNumber-1 )
{
for ( int i=row; i<dgList->dg_RowNumber; i++ )
memcpy( &dgList->dg_Rows[i], &dgList->dg_Rows[i+1], sizeof(DG_ROW) );
dgList->dg_Rows = (DG_ROW*)realloc(dgList->dg_Rows, dgList->dg_RowNumber*sizeof(DG_ROW));
}
else
dgList->dg_Rows = (DG_ROW*)realloc(dgList->dg_Rows, dgList->dg_RowNumber*sizeof(DG_ROW));
// Mark selection
dgList->dg_Selected = NULL;
dgList->dg_SelectedRow = -1;
dgList->dg_SelectedColumn = -1;
result = TRUE;
}
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_ITEMREMOVED), (LPARAM)m_hWnd );
return result;
}
void CDataGrid::RemoveAllItems()
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
// Delete all items
if ( dgList->dg_Rows != NULL )
{
dgList->dg_Edit = FALSE;
ShowWindow( dgList->dg_hEditWnd, SW_HIDE );
free(dgList->dg_Rows);
dgList->dg_Rows = NULL;
dgList->dg_RowNumber = 0;
dgList->dg_Row = -1;
SetScrollPos( m_hWnd, SB_HORZ, 0, TRUE );
SetScrollPos( m_hWnd, SB_VERT, 0, TRUE );
RecalcWindow(m_hWnd);
}
InvalidateRect( m_hWnd, NULL, TRUE );
UpdateWindow(m_hWnd);
}
int CDataGrid::GetSelectedRow()
{
int result = -1;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Return selected row
result = dgList->dg_SelectedRow;
}
return result;
}
int CDataGrid::GetSelectedColumn()
{
int result = -1;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Return selected column
result = dgList->dg_SelectedColumn;
}
return result;
}
void CDataGrid::Update()
{
// Update DataGrid window
RecalcWindow(m_hWnd);
InvalidateRect( m_hWnd, NULL, TRUE );
UpdateWindow(m_hWnd);
}
void CDataGrid::SetCompareFunction(DGCOMPARE CompareFunction)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set custom comparison function
dgList->dg_CompareFunc = (DGCOMPARE)CompareFunction;
}
}
void SortDGItems(HWND hWnd, int column)
{
DG_LIST* dgList = GetDGGrid(hWnd);
if ( ( dgList != NULL ) && ( dgList->dg_CompareFunc != NULL ) )
{
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_STARTSORTING), (LPARAM)hWnd );
// Sort DataGrid items
Sort( hWnd, column, dgList->dg_RowNumber );
// Send notification to the parent window
SendMessage( dgList->dg_hParent, WM_COMMAND, MAKEWPARAM(0,DGM_ENDSORTING), (LPARAM)hWnd );
// Set selection focus
SetDGSelection( hWnd, dgList->dg_SelectedRow, dgList->dg_SelectedColumn );
InvalidateRect( hWnd, NULL, TRUE );
UpdateWindow(hWnd);
}
}
void Sort(HWND hWnd, int col, int size)
{
int i;
DG_ROW temp;
DG_LIST* dgList = GetDGGrid(hWnd);
for ( i=(size+1/2); i>=0; i-- )
SiftDown( hWnd, i, size-1, col );
for ( i=size-1; i>=1; i-- )
{
memcpy( &temp, &dgList->dg_Rows[0], sizeof(DG_ROW) );
memcpy( &dgList->dg_Rows[0], &dgList->dg_Rows[i], sizeof(DG_ROW) );
memcpy( &dgList->dg_Rows[i], &temp, sizeof(DG_ROW) );
SiftDown( hWnd, 0, i-1, col );
}
}
void SiftDown( HWND hWnd, int root, int bottom, int col )
{
int done, maxChild;
DG_ROW temp;
DG_LIST* dgList = GetDGGrid(hWnd);
done = 0;
while ( (root*2 < bottom) && (!done) )
{
if ( root*2 == bottom )
maxChild = root * 2;
else if ( root*2 < bottom )
{
if ( dgList->dg_CompareFunc(dgList->dg_Rows[root*2].rowText[col], dgList->dg_Rows[root*2+1].rowText[col], col) > 0 )
maxChild = root * 2;
else
maxChild = root * 2 + 1;
if ( dgList->dg_CompareFunc(dgList->dg_Rows[root].rowText[col], dgList->dg_Rows[maxChild].rowText[col], col) < 0 )
{
memcpy( &temp, &dgList->dg_Rows[root], sizeof(DG_ROW) );
memcpy( &dgList->dg_Rows[root], &dgList->dg_Rows[maxChild], sizeof(DG_ROW) );
memcpy( &dgList->dg_Rows[maxChild], &temp, sizeof(DG_ROW) );
root = maxChild;
}
else
done = 1;
}
else
done = 1;
}
}
void SetDGSelection(HWND hWnd, int rowIndex, int columnIndex)
{
DG_LIST* dgList = GetDGGrid(hWnd);
bool found = false;
for ( int j=0; j<dgList->dg_RowNumber; j++ )
{
if ( ( dgList->dg_Rows[j].selected ) && ( !found ) )
{
// Mark selection
dgList->dg_Selected = &dgList->dg_Rows[j];
dgList->dg_SelectedRow = j;
dgList->dg_SelectedColumn = columnIndex;
found = true;
break;
}
if ( found )
break;
}
}
void SelectNextItem(HWND hWnd, DG_ROW* item)
{
DG_LIST* dgList = GetDGGrid(hWnd);
for ( int i=0; i<dgList->dg_RowNumber; i++ )
{
if ( ( (&dgList->dg_Rows[i]) == dgList->dg_Selected ) && ( i < dgList->dg_RowNumber-1 ) )
{
// Set selected item
dgList->dg_Rows[i].selected = false;
dgList->dg_Rows[i+1].selected = true;
dgList->dg_Selected = &dgList->dg_Rows[i+1];
dgList->dg_SelectedRow = i+1;
break;
}
}
}
void SelectPreviousItem(HWND hWnd, DG_ROW* item)
{
DG_LIST* dgList = GetDGGrid(hWnd);
for ( int i=0; i<dgList->dg_RowNumber; i++ )
{
if ( ( (&dgList->dg_Rows[i]) == dgList->dg_Selected ) && ( i > 0 ) )
{
// Set selected item
dgList->dg_Rows[i].selected = false;
dgList->dg_Rows[i-1].selected = true;
dgList->dg_Selected = &dgList->dg_Rows[i-1];
dgList->dg_SelectedRow = i-1;
break;
}
}
}
void SelectNextSubitem(HWND hWnd)
{
DG_LIST* dgList = GetDGGrid(hWnd);
// Set selected subitem
if ( dgList->dg_SelectedColumn < dgList->dg_ColumnNumber-1 )
dgList->dg_SelectedColumn++;
else
dgList->dg_SelectedColumn = dgList->dg_ColumnNumber-1;
}
void SelectPreviousSubitem(HWND hWnd)
{
DG_LIST* dgList = GetDGGrid(hWnd);
// Set selected subitem
if ( dgList->dg_SelectedColumn > 0 )
dgList->dg_SelectedColumn--;
else
dgList->dg_SelectedColumn = 0;
}
void EnsureVisible(HWND hWnd, int rowIndex, int colIndex)
{
// Ensure DataGrid item is visible
EnsureRowVisible( hWnd, rowIndex );
EnsureColumnVisible( hWnd, colIndex );
}
void EnsureRowVisible(HWND hWnd, int rowIndex)
{
// Check DataGrid row visibility
DG_LIST* dgList = GetDGGrid(hWnd);
RECT rowRect, clientRect, columnRect;
GetClientRect( hWnd, &clientRect );
GetColumnRect( hWnd, 0, &columnRect );
int clientHeight = clientRect.bottom - clientRect.top;
GetRowRect( hWnd, 0, &rowRect );
int rowOffsetT = dgList->dg_SelectedRow*(rowRect.bottom-rowRect.top-1);
int rowOffsetB = dgList->dg_SelectedRow*(rowRect.bottom-rowRect.top-1) + (columnRect.bottom-columnRect.top-1);
int scrollY = GetScrollPos( hWnd, SB_VERT );
if ( scrollY > rowOffsetT )
SetScrollPos( hWnd, SB_VERT, rowOffsetT, TRUE );
else if ( scrollY+clientHeight < rowOffsetB+(rowRect.bottom - rowRect.top) )
{
int pos = rowOffsetB + (rowRect.bottom - rowRect.top) - (scrollY+clientHeight);
SetScrollPos( hWnd, SB_VERT, scrollY+pos, TRUE );
}
}
void EnsureColumnVisible(HWND hWnd, int columnIndex)
{
// Check DataGrid column visibility
DG_LIST* dgList = GetDGGrid(hWnd);
RECT columnRect, clientRect;
GetClientRect( hWnd, &clientRect );
int scrollX = GetScrollPos( hWnd, SB_HORZ );
int columnOffsetL = 0;
for ( int i=0; i<dgList->dg_SelectedColumn; i++ )
{
GetColumnRect( hWnd, i, &columnRect );
columnOffsetL += (columnRect.right-columnRect.left);
}
GetColumnRect( hWnd, dgList->dg_SelectedColumn, &columnRect );
int columnOffsetR = columnOffsetL + (columnRect.right-columnRect.left);
if ( scrollX + clientRect.left > columnOffsetL )
{
int pos = scrollX + clientRect.left - columnOffsetL;
SetScrollPos( hWnd, SB_HORZ, columnOffsetL, TRUE );
}
else if ( scrollX+clientRect.right < columnOffsetR )
{
int pos = columnOffsetR - (scrollX+clientRect.right);
SetScrollPos( hWnd, SB_HORZ, scrollX+pos, TRUE );
}
}
void CDataGrid::SetItemBgColor(int rowIndex, COLORREF bgColor)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( ( rowIndex >= 0 ) && ( rowIndex < dgList->dg_RowNumber ) )
{
dgList->dg_Rows[rowIndex].bgColor = bgColor;
InvalidateRect( m_hWnd, NULL, TRUE );
UpdateWindow(m_hWnd);
}
}
BOOL AddDGGrid(HWND hWnd, HWND hParent)
{
BOOL result = FALSE;
// Check number of created DataGrids
if ( g_DGGridNumber < DG_MAXGRID )
{
// Create new DataGrid
DG_LIST* newDGGrid = new DG_LIST;
newDGGrid->dg_hWnd = hWnd;
newDGGrid->dg_hParent = hParent;
newDGGrid->dg_Columns = NULL;
newDGGrid->dg_Rows = NULL;
newDGGrid->dg_ColumnNumber = 0;
newDGGrid->dg_RowNumber = 0;
newDGGrid->dg_Column = -1;
newDGGrid->dg_Row = -1;
newDGGrid->dg_SelectedColumn = -1;
newDGGrid->dg_SelectedRow = -1;
newDGGrid->dg_Selected = NULL;
newDGGrid->dg_Cursor = FALSE;
newDGGrid->dg_Resize = FALSE;
newDGGrid->dg_Click = FALSE;
newDGGrid->dg_hColumnFont = NULL;
newDGGrid->dg_hRowFont = NULL;
newDGGrid->dg_hBgBrush = NULL;
newDGGrid->dg_hCellPen = NULL;
newDGGrid->dg_hMemBitmap = NULL;
newDGGrid->dg_hMemDC = NULL;
newDGGrid->dg_hOldMemBitmap = NULL;
newDGGrid->dg_Edit = FALSE;
newDGGrid->dg_hEditWnd = NULL;
newDGGrid->dg_EnableEdit = TRUE;
newDGGrid->dg_EnableSort = TRUE;
newDGGrid->dg_EnableResize = TRUE;
newDGGrid->dg_EnableGrid = TRUE;
newDGGrid->dg_CompareFunc = NULL;
newDGGrid->dg_ColumnTextColor = DGTXT_COLOR;
newDGGrid->dg_RowTextColor = DGTXT_COLOR;
newDGGrid->next = NULL;
DG_LIST* curr = g_DGList;
if ( curr == NULL )
g_DGList = newDGGrid;
else
{
while ( curr->next != NULL )
curr = curr->next;
curr->next = newDGGrid;
}
g_DGGridNumber++;
}
return result;
}
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 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;
}
g_DGGridNumber--;
}
}
DG_LIST* GetDGGrid(HWND hWnd)
{
DG_LIST* result = NULL;
if ( g_DGGridNumber > 0 )
{
// Find DataGrid
DG_LIST *dgList = g_DGList;
while ( ( dgList != NULL ) && ( dgList->dg_hWnd != hWnd ) )
dgList = dgList->next;
result = dgList;
}
return result;
}
DG_LIST* DetachDGGrid(HWND hWnd)
{
DG_LIST* result = NULL;
if ( g_DGGridNumber > 0 )
{
// Find DataGrid
DG_LIST *curr, *prev;
curr = g_DGList;
while ( ( curr != NULL ) && ( curr->dg_hWnd != hWnd ) )
{
prev = curr;
curr = curr->next;
}
if ( curr == g_DGList )
g_DGList = g_DGList->next;
else
prev->next = curr->next;
result = curr;
}
return result;
}
void GetCellRect(HWND hWnd, RECT* cellRect)
{
DG_LIST* dgList = GetDGGrid(hWnd);
if ( dgList != NULL )
{
RECT rowRect, columnRect;
GetColumnRect( hWnd, dgList->dg_SelectedColumn, &columnRect );
GetRowRect( hWnd, 0, &rowRect );
int rowOffset = dgList->dg_SelectedRow * (rowRect.bottom-rowRect.top-1) + (columnRect.bottom-columnRect.top-1);
cellRect->left = columnRect.left;
cellRect->right = cellRect->left + (columnRect.right-columnRect.left) - 1;
cellRect->top = rowOffset + 1;
cellRect->bottom = cellRect->top + (rowRect.bottom-rowRect.top-1) - 1;
}
}
void CDataGrid::EnableSort(BOOL enable)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set sort flag
dgList->dg_EnableSort = enable;
}
}
void CDataGrid::EnableEdit(BOOL enable)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set edit flag
dgList->dg_EnableEdit = enable;
}
}
void CDataGrid::EnableResize(BOOL enable)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set resize flag
dgList->dg_EnableResize = enable;
}
}
void CDataGrid::EnableGrid(BOOL enable)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set grid flag
dgList->dg_EnableGrid = enable;
}
}
void CDataGrid::SetRowTxtColor(COLORREF txtColor)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set DataGrid Text color
dgList->dg_RowTextColor = txtColor;
InvalidateRect( m_hWnd, NULL, TRUE );
UpdateWindow(m_hWnd);
}
}
void CDataGrid::SetColumnTxtColor(COLORREF txtColor)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set DataGrid Text color
dgList->dg_ColumnTextColor = txtColor;
InvalidateRect( m_hWnd, NULL, TRUE );
UpdateWindow(m_hWnd);
}
}
int CDataGrid::GetRowNumber()
{
int result;
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Get DataGrid row number
result = dgList->dg_RowNumber;
}
return result;
}
void CDataGrid::GetColumnFont(LOGFONT* lf)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Get DataGrid column font
memcpy( lf, &dgList->dg_LFColumnFont, sizeof(LOGFONT) );
}
}
void CDataGrid::SetColumnFont(LOGFONT* lf)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set DataGrid column font
memcpy( &dgList->dg_LFColumnFont, lf, sizeof(LOGFONT) );
if ( dgList->dg_hColumnFont )
DeleteObject(dgList->dg_hColumnFont);
dgList->dg_hColumnFont = CreateFontIndirect(lf);
}
}
void CDataGrid::GetRowFont(LOGFONT* lf)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Get DataGrid row font
memcpy( lf, &dgList->dg_LFRowFont, sizeof(LOGFONT) );
}
}
void CDataGrid::SetRowFont(LOGFONT* lf)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set DataGrid row font
memcpy( &dgList->dg_LFRowFont, lf, sizeof(LOGFONT) );
if ( dgList->dg_hRowFont )
DeleteObject(dgList->dg_hRowFont);
dgList->dg_hRowFont = CreateFontIndirect(lf);
}
}
COLORREF CDataGrid::GetColumnTxtColor()
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Get DataGrid column text color
return dgList->dg_ColumnTextColor;
}
else
return RGB(0,0,0);
}
void CDataGrid::GetItemInfo(DG_ITEMINFO* itemInfo)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Get DataGrid item info
if ( ( itemInfo != NULL ) && ( itemInfo->dgItem < dgList->dg_RowNumber ) && ( itemInfo->dgSubitem < dgList->dg_ColumnNumber ) )
{
switch ( itemInfo->dgMask )
{
case DG_TEXTEDIT:
{
// Get DataGrid item text
GetDGItemText( m_hWnd, itemInfo->dgItem, itemInfo->dgSubitem, itemInfo->dgText, itemInfo->dgTextLen );
}
break;
case DG_TEXTALIGN:
{
// Get DataGrid item text alignment
itemInfo->dgTextAlign = dgList->dg_Rows[itemInfo->dgItem].textAlign[itemInfo->dgSubitem];
}
break;
case DG_TEXTHIGHLIGHT:
{
// Get DataGrid row selection state
itemInfo->dgSelected = dgList->dg_Rows[itemInfo->dgItem].selected;
}
break;
case DG_TEXTRONLY:
{
// Get DataGrid item edit mode
itemInfo->dgReadOnly = dgList->dg_Rows[itemInfo->dgItem].readOnly[itemInfo->dgSubitem];
}
break;
case DG_TEXTBGCOLOR:
{
// Get DataGrid row background color
itemInfo->dgBgColor = dgList->dg_Rows[itemInfo->dgItem].bgColor;
}
break;
}
}
}
}
COLORREF CDataGrid::GetRowTxtColor()
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Get DataGrid row text color
return dgList->dg_RowTextColor;
}
else
return RGB(0,0,0);
}
void CDataGrid::EnsureVisible(int row, int column)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Ensure DataGrid item is full visible
::EnsureVisible( m_hWnd, row, column );
}
}
void CDataGrid::SelectItem(int row, int column)
{
DG_LIST* dgList = GetDGGrid(m_hWnd);
if ( dgList != NULL )
{
// Set DataGrid selection
for ( int j=0; j<dgList->dg_RowNumber; j++ )
{
if ( j == row )
{
// Mark selection
dgList->dg_Rows[j].selected = true;
dgList->dg_Selected = &dgList->dg_Rows[j];
dgList->dg_SelectedRow = row;
dgList->dg_SelectedColumn = column;
}
else
dgList->dg_Rows[j].selected = false;
}
}
}