Sample Application
Problem
How to edit the MSFlexGrid
cell?
Solution
The idea is simple. When you want to edit the text in a cell, you only need to retrieve the cell's rectangle (that is Top, Bottom, and Left) and place a Combobox
control over it. The combobox
control will manage all the keyboard input. When the editing is finished, the text in the Combobox
control is written into the cell, replacing the previous text. Then, the Combobox
is hidden until you want to edit another cell again.
Step 1
Select the Dialog Based option in the AppWizard and accept all the default setting.
Step 2
Create a new dialog resource with IDD_COMBO_DLG
. Choose resource from Visual C++'s Insert Menu. The Insert Resource dialog appears. Click on Dialog, and then click New. Visual C++ creates a new dialog resource, as shown here.
Step 3
Choose Add To Project from Visual C++'s Project menu, choose Components And Controls from the submenu. Select Registered Activex Controls, and then choose Microsoft FlexGrid
Control, Version 6.0 (SP6). Visual C++ will generate the wrapper class for the control. And add the Combo Box from the control palette.
Step 4
Use ClassWizard
to add data member to the CflexGridComboclass
. Click on the member variables tab, and then add the data members as shown:
Control IDS | Type | Member |
IDC_COMBO | CcomboBox | m_cCombo |
IDC_MSFLEX | CMSFLexGrid | m_FlexGrid |
Step 5
Use Class Wizard to map the WM_INITDIALOG
and event handler functions for Edit Control EN_KILLFOCUS
and MSFlexGrid
control Click.
Step 6
The OnInitDialog
member function needs to set a column width and assign the value for MSFlexGrid
. With the Help of SetColWidth(index, width)
function, I used to set width of the each column in the MSFlexGrid
and initialize, to set text for fixed Row in the MSFlexGrid
using the function SetTextMatrix(Rowindex, Colindex, string)
. Combobox is hidden until you want to edit the cell.
BOOL CFlexGridCombo::OnInitDialog()
{
CDialog::OnInitDialog();
m_FlexGrid.SetColWidth( 0, 1500);
m_FlexGrid.SetColWidth( 1, 1500);
m_FlexGrid.SetColWidth( 2, 1500);
m_FlexGrid.SetTextMatrix( 0, 0, "Name");
m_FlexGrid.SetTextMatrix( 0, 1, "Computer Science");
m_FlexGrid.SetTextMatrix( 0, 2, "Mathematics");
m_FlexGrid.SetTextMatrix( 0, 3, "Status");
m_cCombo.ShowWindow(SW_HIDE);
return TRUE; }
Step 7
Edit the file FlexCombo.h. Add the following public
member function:
void DisplayControl(CRect &rectData);
Step 8
In the DisplayControl
function, with the help of the CMSFlexGrid
Object, I used to get the WindowRect
. Using GetCellLeft()
, GetCellWidth()
, GetCellTop()
and GetCellHeight()
function, the MSFlexGrid
cell left, width
and Height
are easily found out and assigned to the Crect
variable, rectData.bottom
, rectData.top
, rectData.left
and rectData.right
.
void CFlexGridCombo :: DisplayControl(CRect &rectData)
{
CMSFlexGrid *pGridData = 0;
pGridData = &m_FlexGrid;
CRect rectWnd;
pGridData->GetWindowRect(&rectWnd);
ScreenToClient(&rectWnd);
int nleft = rectWnd.left+(pGridData->GetCellLeft()/15);
int ntop = rectWnd.top+(pGridData->GetCellTop()/15); int nright = pGridData->GetCellWidth()/15;
int nbottom = pGridData->GetCellHeight()/15;
rectData.bottom = nbottom;
rectData.top = ntop;
rectData.left = nleft;
rectData.right = nright;
}
Step 9
When the particular column of the cell is clicked. First, retrieve the cell's rectangle (that is Left, Right, Top and Bottom) using the function DisplayControl
. With help of the AddString
function, all the strings are added in the ComboBox
and ComboBox
control displayed in its current state. Using the MoveWindow
function, the ComboBox
control is placed in the particular cell of the FlexGrid
.
void CFlexGridCombo::OnClickMsflex()
{
CRect rectCntrl;
DisplayControl(rectCntrl);
CString mPrevText;
CMSFlexGrid *pGridData = 0;
int iCol = m_FlexGrid.GetColSel();
CString str;
pGridData = &m_FlexGrid;
m_cCombo.ShowWindow(SW_NORMAL);
m_cCombo.ResetContent();
m_cCombo.MoveWindow(rectCntrl.left,rectCntrl.top,
rectCntrl.right,rectCntrl.bottom,TRUE);
if( iCol == 0)
{
m_cCombo.AddString("ShanmugaRaja");
m_cCombo.AddString("Ganesh Mangal");
m_cCombo.AddString("Deepesh");
m_cCombo.AddString("Sathish");
m_cCombo.AddString("Mehta");
m_cCombo.AddString("Annamalai");
m_cCombo.AddString("Java Senthil");
}
if( ( iCol == 1 ) || ( iCol == 2) )
{
for( int i=0; i<=100; i++ )
{
str.Format("%d",i);
m_cCombo.AddString(str);
}
}
if( iCol == 3 )
{
m_cCombo.AddString("Pass");
m_cCombo.AddString("FAIL");
}
m_cCombo.SetFocus();
UpdateData(FALSE);
}
Step 10
Whenever Combobox
control loses focus, the KillFocus
event is triggered and using SetTextMatrix
function, value are placed in the corresponding cell and then, the ComboBox
box is hidden until you want to edit another cell again.
void CFlexGridCombo::OnKillfocusCombo()
{
CString strCombo;
int iRow, iCol;
iRow = m_FlexGrid.GetRowSel();
iCol = m_FlexGrid.GetColSel();
m_cCombo.GetWindowText( strCombo );
m_FlexGrid.SetTextMatrix( iRow, iCol, strCombo );
m_cCombo.ShowWindow(SW_HIDE);
}
Step 11
Build and test the application.
Finally
I hope my control helps you to edit MSFlexGrid
. All friends of CodeProject can use my ActiveX if it is useful.
If you have any ideas, I hope to know and if you find any problems, you can tell me.
Thanks to CodeProject and to all.
History
- 5th June, 2010: Initial version
I am working in R&D department. In programming, I'm very much interested in OOPS concepts and I have written a book on "Programming in C++". My hobbies are playing cricket, painting and I have started a Educational trust "Illuminate Educational Trust".