Win32 Grid Control with Low Overhead (BABYGRID)



Click here for a larger image.

Environment: VC6, Win32

Introduction

There are a lot of grid controls available. Why is this one different?

Quite simply, this grid is different because it can be implemented without the overhead of MFC, ATL, or COM. It doesn't even require C++ classes. It is implemented just like a standard listbox or edit control. It uses SendMessage() Win32 API function calls to control and notify messages via WM_COMMAND to communicate back to your application. Quite frankly, this is the control that Microsoft should have supplied as a standard control with your compiler.

One would get the impression that grid controls must be overwhelmingly complicated to produce because nearly all of the commercial ones cost anywhere from from $150 to over $400. To boot, nearly all of them require MFC, COM, ATL, or C++ classes to use.

I have seen many requests on Usenet for a grid control that didn't require this overhead, and was programmable similarly to the standard controls that are available to Win32 API programmers. After a lengthy search and failure to find one, and noting that practically every application I was writing could benefit from one, I took on the task of writing one.

One thing I found from my search is that every custom grid control looks different. I didn't need a grid with a hundred bells and whistles. I needed a grid that looked like a Windows standard control and, at least as importantly, I needed a grid that I could program like I was used to, with the standard Win32 API SendMessage() function calls. Also, I didn't want a grid control that required any additional support files, OCXs, or DLLs that I would have to distribute with my applications. Call me old-fashioned, but I like to have everything all wrapped up in the executable.

Project Goals

Before my grid project began, I realized that I needed to set some strict goals and stick to them. If I didn't, I'd never know when the control was finished. These goals for the control were:

  • It had to be created in an application with the CreateWindow() API function.
  • It had to respond 100% to SendMessage() API function calls.
  • It would send the parent application notifications via WM_COMMAND messages like the standard controls.
  • It had to have the look and feel of an Excel spreadsheet.
  • It had to be editable by the user.
  • It had to support sizeable/hideable columns.
  • It had to be extremely customizable.
  • It had to support protected cells (read-only).
  • It had to make my life as a programmer easier.

That didn't seem to be an unreasonable set of goals. I went for it. Many months later, the BABYGRID project is complete.

I realized in development that knowing what features to leave out of the grid was just as important, if not more so, than knowing what to put in. Too many features would make the grid control too specific and not easily adaptable to any grid application.

I used Microsoft Excel as a model for the grid behavior, so anyone using BABYGRID should feel comfortable with its reaction to a user's mouse/keyboard input.

I didn't want to have to predefine anything about the grid other than the number of visible rows and columns. This meant that any cell in any column might get any type of data, whether numeric, alphanumeric, or boolean. Boolean values are displayed in BABYGRID as checked or unchecked check boxes. This meant that ALL data in the grid would need to be internally represented as NULL-terminated character strings. When data is entered into a cell, BABYGRID determines the type of data that it is, and then displays it accordingly.

I want you to know that this control is not untested. It is already in use in many applications in a manufacturing environment. This is not a declaration that I guarantee it is bug free, only that I believe it to be bug free and of commercial quality. I initially called it BABYGRID because I initially wanted only a grid for reporting purposes. BABYGRID has grown up since its inception. Don't be fooled by the name.

BABYGRID is intended to be compiled as a static library. This is the most logical way to use this control. Just compile "babygrid.cpp" along with its header file "babygrid.h" as a static library. Include the resulting "babygrid.lib" file in your projects, along with "babygrid.h", and you're set to go.

If you don't want to use it as a static library, just include "babygrid.cpp" and include "babygrid.h" in your source project; that will work, too.

There are over 40 BGM_ messages to control BABYGRID and 25 BGN_ notification messages that BABYGRID uses to communicate back to your application. This is WAY too many messages to document here, but I use a good many of them in the sample project downloadable with this article. I'm pretty sure you won't have any difficulty following the source code to see what's happening between it and the BABYGRID control.

Let me show you a code snippet to demonstrate how simple this control is to use:

#include "babygrid.h"             //<----- You've got to do this.

HWND hgrid                        //<----- Define a window handle
                                  //       for your BABYGRID

_BGCELL cell;                     //<----- Use this structure to
                                  //       reference cells in the
                                  //       grid
                                  //       _BGCELL is defined in
                                  //       "babygrid.h"

char tbuffer[200];                //<----- A place to put data FROM
                                  //       a grid cell

(...WndProc...)

  WM_CREATE:
    RegisterGridClass(hInst);     //<----- Call this one time
                                  //       to initialize the
                                  //       BABYGRID control.


                                  // Now create a window using the
                                  // registered "BABYGRID" class

    hgrid=CreateWindowEx(WS_EX_CLIENTEDGE,"BABYGRID",
        "Custom Grid Control",
    WS_VISIBLE|WS_CHILD,0,0,500,500,hWnd,(HMENU)500,hInst,NULL);

                                  // A default BABYGRID grid control
                                  // is now visible on your
                                  // application window.

                                  //put "Hello" in row 5, column 3

    SetCell(&cell,5,3);           //<----- SetCell function is
                                  //       defined in "babygrid.h"

    SendMessage(hgrid,BGM_SETCELLDATA,(UINT)&cell,(long)"Hello");

                                  // Not that it would make sense
                                  // to do it right now, but this
                                  // is how you would get the
                                  // contents of a cell in the grid

                                  // Get the data (character string)
                                  // in row 5, column 3
    SetCell(&cell,5,3);
    SendMessage(hgrid,BGM_SETCELLDATA,(UINT)&cell,(long)tbuffer);

                                  // The contents of tbuffer is
                                  // "Hello"


  break;

Now, I ask you. Is that simple or what?!

Some Features of BABYGRID

  • Dimensionable from 1 to 256 columns and from 0 to 32000 rows
  • Optional owner-drawn cell contents
  • Sizeable grid title (programmatically or auto-size)
  • Sizeable column headers (programmatically or auto-size)
  • Sizeable column widths (programmatically or auto-size or user preference)
  • Optionally enable or disable user resizing of columns (keep hidden stuff hidden)
  • Sizeable row heights (programmatically or auto-size—all data rows are same height)
  • Protected cells (read-only)
  • Customizable highlight row and color
  • Customizable cursor color
  • Customizable grid background color
  • Customizable gridline color
  • Customizable protected cell background color
  • Enable or Disable auto numbering of rows
  • User definable fonts for title, column headings, and grid body
  • Enable or Disable user editing
  • Enable or Disable extending last column to fill grid window

All I ask is that, if you find BABYGRID useful and you use it in an application, you e-mail me to let me know. I'd like to know my work has helped you in your work. I'd like to know what the application using BABYGRID does.

Downloads

Download demo project - 30 Kb
Download source - 18 Kb

IT Offers

Comments

  • Setting binary data fixed

    Posted by mlcarey1959 on 10/28/2011 03:27pm

    tbuffer[j] must be an unsigned char
    
    
            if(isalpha( (unsigned char)tbuffer[j])){ALPHA=TRUE;}
             if(isdigit( (unsigned char)tbuffer[j])){DIGIT=TRUE;}
             if(iswspace( (unsigned char)tbuffer[j])){WHITESPACE=TRUE;}
             if((unsigned char)tbuffer[j]=='.'){PERIOD=TRUE;numberofperiods++;}
    		 if((unsigned char)tbuffer[j]=='+'){if(j>0){ALPHA=TRUE;}}
    		 if((unsigned char)tbuffer[j]=='-'){if(j>0){ALPHA=TRUE;}}

    Reply
  • Setting binary data crashes

    Posted by mlcarey1959 on 10/28/2011 08:56am

    DetermineDataType() fails when setting binary data. Debug Assertion Faile!

    Reply
  • Great work!

    Posted by mr519 on 08/15/2011 07:50am

    Just what I was lookign for. Many thanks. Is there a new release on a way?

    Reply
  • Combobox?

    Posted by james2432 on 07/08/2009 02:18pm

    I find it simply amazing except for the lack of a combobox option for a col/row combination.

    Reply
  • Thanks !

    Posted by inbugable on 04/24/2006 03:48am

    Hi, Thank for this control. It's exactly what I was looking for ! There is a little error in the code fragment at the end of the article : in the last line, it should be BGM_GETCELLDATA, not BGM_SETCELLDATA... Thank you. ClC)ment.

    Reply
  • i'm eagerly to see new version!

    Posted by ilvu on 10/20/2004 07:24am

    wonderful!i'm eagerly to see new version!

    • cute grid

      Posted by strawberry.jam on 02/19/2006 09:24pm

      if it had fixed cols, fixed rows and merged cells, it would be better.

      Reply
    Reply
  • I am looking forward...

    Posted by lizhaoming on 10/14/2004 01:54am

    Dear Hillard, This is Li Zhaoming. about one year ago, i sent an email to your talking about the integration of datascape and your babygrid. I have done some work recently. And I am looking forward your new version of babygrid! You can find the Datascape (before the integration) on TUCOWS.

    Reply
  • Yes, David, there is interest in your BABYGRID!

    Posted by cottonviking on 08/15/2004 02:11am

    David, I'm learning to program Windows w/ C using VC6 starting out with just the win32 api. Once I get my head around that somewhat I'll starting looking at the C++ and MFC stuff. SO... your babygrid falls perfectly into a learning project I'm doing right now which is rewriting an Access 2000 app entirely in C w/ MySQL, sans MFC. I just came across your babygrid this evening so I will be studying it for a while to get it working in my project. The updates you describe are *very* appealing and I would love to see the next version. Thank you for sharing your hard work!! Paul

    Reply
  • New version of BABYGRID coming soon!

    Posted by DHillard on 08/11/2004 01:41pm

    I have been working on a new version of this grid for several months now. 
    
    The new version will be implemented as a DLL with mostly the same programming interface (SendMessage) as this grid. This will allow for easier access to programmers using other languages besides C/C++.
    
    The new version is being developed from the ground up, using a grid engine for direct access to the grid cell contents. This replaces the binary lookup used in this grid. It also draws and displays MUCH faster than BABYGRID using a backbuffer the create the grid display in memory, then bitblting it to the screen.
    
    
    It also has these features: 
    
    REAL incell editing (using an edit control) 
    Merging cells of rows with identical data 
    Column reordering 
    Search Grid or Search Column 
    Sort by Column 
    127 Color Pallette 
    127 Font Pallette 
    Protected cells 
    Export grid contents to CSV file 
    Print grid 
    9 point cell justification 
    Cell left and right indents
    Individual cell background, foreground colors
    Column resizing/hiding
    Fixed columns
    No limit on number of columns (other than available memory)
    No limit on rows (also... available memory)
    127 icon pallette,  Can combine cell text with graphic (icon)
    
    (Essentially fixing all the annoying things with BABYGRID) 
    
    What I DON'T KNOW is: Is ANYBODY using BABYGRID? Is ANYBODY interested in a new version? 
    
    I cannot tell how many or if anybody visits this page, so I need comments or email from you letting me know. If there is no response, there's no point in posting a new version.
    
     David

    • Lcc-win32 version babygrid

      Posted by rickleaf on 04/09/2008 05:16am

      I have modified some source code for lcc-win32 compiler. and now,it is running successfully. Anyone who interesting it can contact me. My mail is zqyy_w@hotmail.com

      Reply
    • Lcc-win32 version babygrid

      Posted by rickleaf on 04/09/2008 05:15am

      I have modified some source code for lcc-win32 compiler. and now,it is running successfully. Anyone who interesting it can contact me. My mail is zqyy_w@hotmail.com

      Reply
    • New version of BABYGRID coming soon!

      Posted by PK4BCX2 on 10/24/2004 01:42pm

      What I DON'T KNOW is: Is ANYBODY using BABYGRID? Is ANYBODY interested in a new version? There are versions for LCC-win32 , PellesC and a version of xbLite Basic and maybee more !! We are using it !!! Thanks for all your work . Peter.

      Reply
    • New version of BABYGRID coming soon!

      Posted by mechanic on 10/23/2004 07:22pm

      Are we using it? Sure! The improvements sound great! I want to use babygrid for a CMMS application I'm writing. Thank you for continuing your work on this!
      
      Doyle

      Reply
    • New version of BABYGRID coming soon!

      Posted by pcronk on 09/05/2004 10:00pm

      David;
      
      Of course we're using it, and looking forward to subsequent versions of the baby.  (no pun intended).
      
      We also recognize a good thing and will be peeking periodically on your progress ;)
      
      Contrary to Hailer's comments, I find the removal of limitations and fixed columns exciting.  
      
      Cheers,
      Paul.

      Reply
    • Sure, show them how its done

      Posted by DFaber on 08/25/2004 02:01am

      Thanks David for sharing this code. I've been looking for a grid control which I can use without MFC. Now I found it. Modifying the control to your needs is really simple. Why isn't there a section "WIN32 API ONLY"?. The print and export functions would be a great improvement. So I'm looking forward to the next release. Douwe

      Reply
    • Please continue your work on BabyGrid!

      Posted by bhailer on 08/18/2004 12:38pm

      Hi David, I'm working since quite some time on a program which uses BabyGrid. I have learnt a lot from your code. Actually I'm using lcc-win32 instead of Visual C++ (see http://www.cs.virginia.edu/~lcc-win32/), only some minor modifications were necessary to make your code work. I have tried also to improve the memory management for BabyGrid (not complete yet). The new features you mentioned, namely the print and CSV export support, are really interesting, and I'm looking forward to see your new version! So my message to you is: yes please continue your work on BabyGrid! The really free license you have provided has enabled me to learn a lot about Windows programming. Best regards - and keep up the great work! Bernhard

      Reply
    Reply
  • How about documentation for BabyGrid?

    Posted by mechanic on 04/14/2004 06:33am

    I would like to see some documentation for BabyGrid. Is anything available? Is so, a URL or email addy would be great! Thanks!

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Whitepapers and More

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds