Editable MSFLEXGRID Control-Derived Class

Environment: Windows 9x, Me, 2000, NT 4, XP; Microsoft Visual C++ 6.0

How to Make a MS FlexGrid Control Editable

There is not much documentation about MS FlexGrid; however, the technique suggested by Microsoft is to use an auxiliary Edit control for doing the task (see Reference 1).

The idea is simple. When you want to edit the text in a cell, you only need to retieve the cell's rectangle and place an edit control over it. The edit control will manage all the keyboard input. When the editing is finished, the text in the edit control is written into the cell, replacing the previous text. Then, the edit box is hidden until you want to edit other cell again.

The first problem is that the cell's rectangle is returned in TWIPS units. The TWIPS must be converted to pixels. Because a TWIP is 1/20 of a point and 1/1440 of an inch, the conversion between twips and pixels is done as follows:

Pixels=TWIPS*pixelsperinch/1440

The number of pixels per inch can be obtained with GetDeviceCaps(LOGPIXELSX) and GetDeviceCaps(LOGPIXELSY) for horizontal and vertical coordinates, respectively.

I have created two classes, CEditFlexGrid class, derived from CMSFlexGrid; and CCellEdit class, derived from CEdit. CEditFlexGrid has a member variable of the class CCellEdit.

Microsoft provides an example that can be found in the Knowldedge Base site (see Reference 2). This example and mine use a similar technique; however, I have introduced some features that are different from the MS example:

  • The MS example uses the default system font for the edit box. CCellEdit classs uses the current font in the flexgrid.
  • The MS example uses the default B/W edit box. CCellEdit takes the cell color every time.
  • In the MS example, the cells are always editable. In CEditFlexGrid the cells are only editable if the user presses the Return key or double pushes the left mouse button. The cells stops editing when the user clicks in another place, pushes Enter again, or changes the focus.

To change the color in the edit box, I have used the "Message reflection" technique, as shown in Reference 3. The procedure is to take the cell's colors and dynamically change the background and text colors in the edit box. The colors retrieved from the flexgrid are translated to valid RGB colors by using the function OleTranslateColor().

A similar procedure to the "Message reflection" is used for reflecting some MSFlexGrid events.

To handle special keys (Return) in the edit box and the flexgrid, I have used the technique described in Reference 4, overriding OnGetDlgCode() for both CEditFlexGrid and CCellEdit.

A strange problem happened every time a cell was enabled for editing. This problem was that the arrow keys did not work as expected. Normally, when you push an arrow key in an edit box with the focus, the caret moves. This did not happen with the CCellEdit object; the arrow keys produced a change in the grid's cell. The problem is that the arrow keys were treated as accelerator keys. Reference 5 explains this problem and how to solve it with the aid of the PreTranslateMessage() function.

How to Use CEditFlexGrid and CCellEdit in Your MFC Project

Add the four files EditFlexGrid.cpp, EditFlexGrid.h, CellEdit.cpp, and CellEdit.h to your project. Take care that you have written the appropiate #include directives for your project. Put the #include "EditFlexGrid.h" line in your .h file. Add a member variable to your MSFlexGrid object of the type CEditFlexGrid. Use any of the common functions of MSFlexGrid for sizing and filling the grids. When you want to edit a cell, just push Enter or double-click it. The cell edited will be the currently selected cell (take care of your selection mode flag). When you want to finish the editing, you can push Enter again, or click in another place or control. You can use any of the MSFlexGrid functions to retrieve the text in the cells.

Note: You cannot edit fixed cells. The class has been designed to work as said above; there is no guarantee to work if it is used in a different way. Changes of the grid font at run time are not supported.

References

  1. VB3 How to Edit Grid Cells in VB Using Overlapped Text Box: http://support.microsoft.com/ ... /ARTICLES/Q85/1/09.asp&NoWebContent=1

  2. EditGrid.exe: Edit Cells in MSFlexGrid ActiveX Control: http://support.microsoft.com/default.aspx?scid=kb;en-us;196833

  3. TN062: Message Reflection for windows controls: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfcnotes_tn062.asp

  4. How to Trap Arrow Keys in an Edit Control of a Dialog Box: http://support.microsoft.com/ ... /articles/Q104/6/37.asp&NoWebContent=1

  5. PRB: MFC ActiveX Control Ignores ARROW Keys on VB Container: http://support.microsoft.com/ ... /ARTICLES/Q180/4/02.asp&NoWebContent=1

Downloads

Download source code - 23 Kb