ZeeGrid Quick-Start Tutorial

Getting Started

For this example, we will create a grid control that occupies the top half of the application client area and extends the full width of the client area. It will have 10 columns of data.

In your global variables section you will need to create the following:


#include "zeegrid.h"
HMODULE hgridmod;    //for result of LoadLibrary() function
HWND hgrid;          //window handle for the grid.

In the window procedure, in the WM_CREATE section, we will need to load the DLL file with the LoadLibrary() function. We will then check the result of the LoadLibrary() function to determine if the load was successful. If LoadLibrary() fails, it's because the ZeeGrid.DLL file is not in the correct directory. It should be in the same directory as your program's source code file.


	case WM_CREATE:
		hgridmod=LoadLibrary("zeegrid.dll");
		if(!hgridmod)
		{
			MessageBox(hWnd,"Unable to load ZeeGrid.DLL","Error",MB_OK);
			PostQuitMessage(0);
		}
		break;

We will now continue modifying the WM_CREATE section to actually create the zeegrid control. Since the grid will need to resize itself to the application window size, I create the zeegrid control with a width and height of 0 pixels, then size the grid control in the WM_SIZE section.

	case WM_CREATE:
		hgridmod=LoadLibrary("zeegrid.dll");
		if(!hgridmod)
		{
			MessageBox(hWnd,"Unable to load ZeeGrid.DLL","Error",MB_OK);
			PostQuitMessage(0);
		}
		//if you’re here, then the DLL loaded successfully
		hgrid=CreateWindow("ZeeGrid","My First ZeeGrid",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,0,0,hWnd,(HMENU)700,hInst,NULL);

		break;


...and the WM_SIZE section code to handle resizing the grid based on the size of the appliction window...

	case WM_SIZE:
		{
			RECT rect;
			GetClientRect(hWnd,&rect);
			MoveWindow(hgrid,0,0,rect.right,rect.bottom/2,TRUE);
		}
		break;



Now, compile and run this application and you'll see the default ZeeGrid control occupying the top half of your application window. (Figure-1)

Figure-1
Figure-1 Default ZeeGrid in application client area.

Notice that by default, any newly created ZeeGrid has only 5 columns. Since we want 10 columns in this example, the first message we will use is the ZGM_DIMGRID (dimension grid) to tell it how many columns we want. ZGM_DIMGRID does not have ANYTHING to do with how many ROWS the grid will have. It only refers to the number of columns. The wParam parameter is the number of columns we want in the grid. The lParam parameter is the number of FIXED columns. So to continue modifying the WM_CREATE section, right after the ZeeGrid is created with the CreateWindow() function, we will add the SendMessage() function to set the number of columns to 10. This is done as follows:


	case WM_CREATE:
		hgridmod=LoadLibrary("zeegrid.dll");
		if(!hgridmod)
		{
			MessageBox(hWnd,"Unable to load ZeeGrid.DLL","Error",MB_OK);
			PostQuitMessage(0);
		}
		//if you’re here, then the DLL loaded successfully
		hgrid=CreateWindow("ZeeGrid","My First ZeeGrid",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,0,0,hWnd,(HMENU)700,hInst,NULL);
		
		SendMessage(hgrid,ZGM_DIMGRID,10,0);  //set the grid to have 10 columns instead of the default 5
		break;


Compile and run this application and you'll see the grid is now configured with 10 columns. (Figure-2)

Figure-1
Figure-2 ZeeGrid with 10 columns.

The very next step after dimensioning the grid columns is to determine the maximum number of rows that the grid will handle by sending the grid a ZGM_ALLOCATEROWS message. By default, even if you don't do this step, ZeeGrids are set to handle a maximum of 2000 rows of data. If you know your grid might be loaded with 5,000 rows of data, it is absolutely critical to allocate the needed space with ZGM_ALLOCATEROWS.

For demonstration purposes, we'll pretend that this grid might under some conditions need to handle a maximum of 5,000 rows of data. Continue editing the WM_CREATE section to add the ZGM_ALLOCATEROWS message. In order to not clutter up the WM_CREATE code section, I will create a function called FormatGrid() that we will use to continue experimenting with the ZeeGrid. We will display the row numbers, and create 5 empty rows of data cells. We'll also set the column headers to something besides the default numbers. Then one more thing, we'll set column 3 to be editable by the user. Sending the grid the ZGM_AUTOSIZE_ALL_COLUMNS will adjust all the column widths to fit the column contents. In this case, the 7th column is wide and will display with ellipsis (...) if the autosize is not performed.


	void FormatGrid(HWND hg)
		{
			SendMessage(hg,ZGM_SHOWROWNUMBERS,TRUE,0);
			//create 5 rows of empty cells
			int j;
			for(j=1;j<=5;j++)
			{
				SendMessage(hg,ZGM_APPENDROW,0,0);
			}
			//set column header titles
			SendMessage(hg,ZGM_SETCELLTEXT,1,(LPARAM)"First\nColumn");
			SendMessage(hg,ZGM_SETCELLTEXT,2,(LPARAM)"Second\nColumn");
			SendMessage(hg,ZGM_SETCELLTEXT,3,(LPARAM)"Third\nColumn");
			SendMessage(hg,ZGM_SETCELLTEXT,4,(LPARAM)"Fourth\nColumn");
			SendMessage(hg,ZGM_SETCELLTEXT,5,(LPARAM)"Fifth\nColumn");
			SendMessage(hg,ZGM_SETCELLTEXT,6,(LPARAM)"Sixth\nColumn");
			SendMessage(hg,ZGM_SETCELLTEXT,7,(LPARAM)"Seventh Column is wide");
			SendMessage(hg,ZGM_SETCELLTEXT,8,(LPARAM)"Eighth\nColumn");
			SendMessage(hg,ZGM_SETCELLTEXT,9,(LPARAM)"Ninth\nColumn");
			SendMessage(hg,ZGM_SETCELLTEXT,10,(LPARAM)"Tenth\nand\nlast\nColumn");

			//make column 3 editable by the user
			SendMessage(hg,ZGM_SETCOLEDIT,3,1);

			//auto size all columns
			SendMessage(hg,ZGM_AUTOSIZE_ALL_COLUMNS,0,0);
		}


	case WM_CREATE:
		hgridmod=LoadLibrary("zeegrid.dll");
		if(!hgridmod)
		{
			MessageBox(hWnd,"Unable to load ZeeGrid.DLL","Error",MB_OK);
			PostQuitMessage(0);
		}
		//if you’re here, then the DLL loaded successfully
		hgrid=CreateWindow("ZeeGrid","My First ZeeGrid",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,0,0,hWnd,(HMENU)700,hInst,NULL);
		
		SendMessage(hgrid,ZGM_DIMGRID,10,0);         //set the grid to have 10 columns instead of the default 5
		SendMessage(hgrid,ZGM_ALLOCATEROWS,5000,0);  //allocate memory for 5000 rows of data (50,000 cells)
		FormatGrid(hgrid);

		break;


Compile and run and you'll see the grid formatted. (Figure-3)

Figure-1
Figure-3 ZeeGrid with row numbers, column titles and autosized.

Notice that column 3 is user editable. The other cells in all the other columns are read-only for the user. In our example, we set the entire column 3 (wParam) to editable of edit style 1 (lParam). Edit style 0 is read-only. Edit style 1 is an edit box. Edit style 2 is a dropdown selection list. Edit style 3 is a boolean edit (toggle). Edit style 4 is a dropdown calendar for selecting dates.

Notice that we used ZGM_SETCOLEDIT to set an entire column's edit style. This can be a little bit confusing, but what it's actually doing is looping through each cell in that column and setting the edit style cell by cell. What I'm saying here is that the cells have to be there first before they can have their edit style set. In other words, if you now append another row with ZGM_APPENDROW, that new row will not have its column 3 editable. So you need to set your edit styles after the cells have been created. Even though we allocated 5,000 rows, the only cells that exist at the moment are the cells in the first 5 rows, so executing the ZGM_SETCOLEDIT only applies to those 5 rows.

Cell Indexing (Addressing)

All cells in ZeeGrid are addressed by their index. In all cases, index 0 is the ZeeGrid title. Then the column headers are indexed 1 through however many columns the grid has. The cell index of the first row and first column will be the number of columns + 1. There is one message that you'll find yourself using a lot. That's ZGM_GETCELLINDEX which takes the row in wParam and the column in lParam. It returns an integer which is the cell index of the specified row and column.

Most messages will use the index of the cell to determine which cell the message pertains to. Although we didn't use it in the above example of ZGM_APPENDROW, that message also returns the cell index of the first column in the appended row.

I assume the data you want to put into the grid is held in a database of some sort, so you'll normally execute code to read that database one record at a time. Or maybe you're reading and parsing from a text file, or a binary random access file. In any case, you will loop through the file reading each record then you'll append a row in the grid and load each cell of that row with your data.

The code below will show you how you will probably want to load the grid.


//Do not enter and compile this section of code.  This is psuedo code for an example
//of loading the grid from a database.

	void LoadGrid(HWND hg)
		{
			int field1;
			double field2;
			char field3[255];

			//loop through your data file reading a record at a time
			//psuedo code follows
			while(!EOF)
				{
					//read record  Assume three fields for this example
					//assume field1 is integer type
					//assume field2 is double (float) type
					//assume field3 is a character string

					index=SendMessage(hg,ZGM_APPENDROW,0,0);
					SendMessage(hg,ZGM_SETCELLINT,index,(LPARAM)&field1);
					SendMessage(hg,ZGM_SETCELLDOUBLE,index+1,(LPARAM)&field2);
					SendMessage(hg,ZGM_SETCELLTEXT,index+2,(LPARAM)field3);		
				}
		}


Emptying the ZeeGrid

To empty the grid, but leave the grid title and column headers intact, use ZGM_EMPTYGRID. To remove all rows, set wParam to TRUE. To empty the grid, but leave the rows, set wParam to FALSE. lParam is not used.

Column Reordering and Sorting

By default, ZeeGrid allows its columns to be reordered by the user. This is accomplished by clicking on a column header, then using the left and right arrows to move that column to the user's preference. Column reordering does not affect cell addressing. Sorting the grid moves the contents on the cells to other cells, but the cell's index will remain the same. It just might have different contents. Sorting of the grid is done by double-clicking in the column header. To sort in descending order, use shift-double-click of the column header.

ZeeGrid Built-In Toolbar

If the user presses the [F8] function key while the ZeeGrid has the keyboard focus, the toolbar can be toggled on and off. You can set this capability by sending the message ZGM_ENABLETOOLBARTOGGLE with TRUE or FALSE in wParam. Sorting and column reordering can be controlled the same way with ZGM_ENABLESORT and ZGM_ENABLECOLMOVE.

Browse the Header File!

Until I complete documentation for each and every message, you should browse (or print out) the zeegrid.h header file. If the name looks like it's a boolean operation, wParam will be the boolean value, and lParam won't be used. If it looks like it references a cell, the wParam will be the cell index and lParam will be the parameter passed to the cell. If it looks like it references a row, wParam is the row number. If it looks like it references a column, wParam is the column number. In other words, you should be able to figure it out pretty quickly.

Back to Home page