首页 > 编程资源分享区 > C/C++源代码共享 > 做一个可编辑的表格控件
2006
10-12

做一个可编辑的表格控件

【实现内容】做一个可编辑的表格控件。


【使用控件】一个MSFLEXGRID表格控件,一个文本控件,一个下拉列表控件。


【实现原理】我喜欢把这个方法称为视觉假象。由于MSFLEXGRID控件本身是不支持直接编辑的。所以需要结合文本控件或者下拉列表控件,使表格控件的运行效果如同可以直接编辑一样。


【实现步骤】


1. 当鼠标点击表格控件的某一格时,首先判断该列的属性,是直接编辑呢,还是用下拉列表进行选择。


2. 显示隐藏的文本控件或者下拉列表控件,显示的位置和大小与选中格的位置大小完全相同,这样可以覆盖选中格


3. 将选中格的内容填到文本控件或者下拉列表控件中


4. 修改完毕后,将新的内容填到选中格中,同时隐藏文本控件或者下拉列表控件。


【主要程序段及说明】


变量定义:


CComboBox m_ChangeCombo;–下拉列表控件,初始时不可见


CEdit m_Change;—————文本控件,初始时不可见


CSring m_sChange;—————-与文本控件关联的字符串


CMSFlexGrid m_FlexGrid;—–表格控件


程序段:


表格点击事件:选中某一格后,就要显示相应的文本控件或者列表控件


void CChartInfoEditDlg::OnClickMsflexgrid()


{


//点击无效区,返回


long lRow = m_FlexGrid.GetRowSel();//获取点击的行号


long lCol = m_FlexGrid.GetColSel(); //获取点击的列号


if(lRow>m_SAttrInfo.attrNum) //如果点击区超过最大行号,则点击是无效的


return;


if(lRow == 0) //如果点击标题行,也无效


return;


//


CRect rect;


m_FlexGrid.GetWindowRect(rect); //获取表格控件的窗口矩形


ScreenToClient(rect); //转换为客户区矩形


// MSFlexGrid 控件的函数的长度单位是”缇(twips)”,


//需要将其转化为像素,1440 缇 = 1 英寸


CDC* pDC =GetDC();


//计算象素点和缇的转换比例


int nTwipsPerDotX = 1440 / pDC->GetDeviceCaps(LOGPIXELSX) ;


int nTwipsPerDotY = 1440 / pDC->GetDeviceCaps(LOGPIXELSY) ;


//计算选中格的左上角的坐标(象素为单位)


long y = m_FlexGrid.GetRowPos(lRow)/nTwipsPerDotY;


long x = m_FlexGrid.GetColPos(lCol)/nTwipsPerDotX;


//计算选中格的尺寸(象素为单位)。加1是实际调试中,发现加1后效果更好


long width = m_FlexGrid.GetColWidth(lCol)/nTwipsPerDotX+1;


long height = m_FlexGrid.GetRowHeight(lRow)/nTwipsPerDotY+1;


//形成选中个所在的矩形区域


CRect rc(x,y,x+width,y+height);


//转换成相对对话框的坐标


rc.OffsetRect(rect.left+1,rect.top+1);


//清空下拉列表的内容


m_ChangeCombo.ResetContent( );


//以下省略哪一列用文本控件,哪一列用下拉列表控件的判断。如果是用下拉列表控件,则会先向下拉列表控件中增加数据,否则为空


……………………………….


……………………………….


//获取选中格的文本信息


CString strValue = m_FlexGrid.GetTextMatrix(lRow,lCol);


int num = m_ChangeCombo.GetCount();


//如果下拉列表控件中有数据,则表示使用下拉列表控件来进行数据选择


if(num!=0)


{
m_ChangeCombo.ShowWindow(SW_SHOW);//显示控件


m_ChangeCombo.MoveWindow(rc); //移动到选中格的位置,覆盖


m_ChangeCombo.SelectString(-1,strValue); //内容全选。方便直接修改


m_ChangeCombo.SetFocus(); //获取焦点


UpdateData(false);


return;


}


//


m_Change.ShowWindow(SW_SHOW); //显示控件


m_Change.SetWindowText(strValue); //显示文本


m_Change.SetFocus(); //获取焦点


m_Change.SetSel(0,-1); //全选


m_Change.MoveWindow(rc); //移动到选中格的位置,覆盖


}


文本编辑完毕后,回车即将新的文本信息填到选中格中


void CChartInfoEditDlg::OnKillfocusEditChange()


{


UpdateData(true);


m_FlexGrid.SetText(m_SChange);//设置文本信息


m_Change.ShowWindow(SW_HIDE); //隐藏文本控件


UpdateData(false);


}


下拉列表编辑完毕后,将新的新息填到选中格中


void CChartInfoEditDlg::OnKillfocusChangecombo()


{


UpdateData(true);


CString str;


m_ChangeCombo.GetWindowText(str);


m_FlexGrid.SetText(str);


m_ChangeCombo.ShowWindow(SW_HIDE);


UpdateData(false);


}


【总结】这是一个比较简单的程序。如果表格中列较多,属性各有不同,也许大家可以试着用更加复杂的控件来编辑信息。也可以同时做多个文本控件和下拉列表控件,以对应不同列的不同信息要求(比如有的格信息可能又不同的格式要求,那么可以预先做好各种不同风格的控件与之对应)。


【笔者注】虽然当前有许多这样的例子。但笔者做这个程序时,并没有借鉴现有的东西。因此可能在方法上不见得最简单。但确实效果不错,对付一般情况是没有问题的。大家如果对此有疑问或新思想,可以和笔者讨论。联系信箱: happyparrot@126.com


留下一个回复