List Control控件高级应用——利用List Control控件制作表格

原创 2007年09月26日 17:38:00
 

List Control控件高级应用——利用List Control控件制作表格

最近使用到了List Control控件。使用中,要求不但能够在List Control中显示数据,而且能够动态修改选中的Item中的内容,其功能类似与在程序中插入一张可以随意修改的表(Table)。虽然整个过程很简单,却体现了MFC编程的灵活性。通过实现高级List Control控件,也可以从更深层次理解MFC界面编程。

下面将实现步骤总结如下:

这里我们来实现一个自己的类CEditTable,该类继承与CListCtrl

先说一下我们的思路:CListCtrl类给提供了现实数据的基本操作,但要像Word中编辑表格一样编辑ClistCtrl中的内容,首先必须获取要编辑的Item的位置,然后用新输入的内容代替原来Item中的内容。基本思路很简单,就是先触发输入操作,然后新建一个CEdit编辑框对象,从CEdit编辑框中获取新的内容,以新内容替换指定Item中的内容,回车结束,销毁CEdit编辑框对象。下面来一步步实现。

 

1.  CEdit控件继承一个CItemEdit类,作为CListCtrl的成员,用来接收输入内容。

2.  重载CEdit的消息翻译函数BOOL PreTranslateMessage(MSG* pMsg); 在函数中拦截ESC键和RETURN键按下的消息,解释为WM_KILLFOCUS消息(ESC和ENTER分别表示取消输入和输入结束)

BOOL CItemEdit::PreTranslateMessage(MSG* pMsg) 
{
    
//拦截ESC键和RETURN键按下的消息,解释为WM_KILLFOCUS消息,这里也可以根据需要设置其它键作为输入结束或取消输入的标志
    
if( pMsg->message==WM_KEYDOWN )
    {
        
if( pMsg->wParam==13 )        //回车键
            pMsg
->message = WM_KILLFOCUS;
        
else if( pMsg->wParam==27 )    //ESC键
        {
            m_bInputValid 
= FALSE;    //此时的编辑结果无效
            pMsg
->message = WM_KILLFOCUS;
        }
    }
    
    
return CEdit::PreTranslateMessage(pMsg);
}

3. 重载OnKillFocus函数

void CItemEdit::OnKillFocus(CWnd* pNewWnd) 
{
    
// 得到父窗口,并通知父窗口结束编辑过程
    lj_CListCtrl 
*parent = (lj_CListCtrl *)GetParent();
    
if( parent )
        parent
->MyEndEdit( m_bInputValid );

    m_bInputValid 
= TRUE;
    
    CEdit::OnKillFocus(pNewWnd);
}

4.   从CListCtrl类继承新的CEditTable类

5.   在CEditTable中分别添加编辑控件成员 CItemEdit  m_edit; 便是行和列的坐标变量

              int m_nItem;   //被编辑表项的行号

             int m_nSubItem; //列号

6.   在CEditTable中重载鼠标左键按下消息的回调函数 void OnLButtonDown(UINT nFlags, CPoint point);

              应用中要通过点击鼠标左键开始编辑Table中的某一项。

void CEditTable::OnLButtonDown(UINT nFlags, CPoint point) 
{
    POSITION pos;
    BOOL bSelected 
= FALSE;

    
// 检查是否有Item正被编辑
    
if( m_bEditing ==TRUE)
        goto defalt_session;

    
// 检查是否有Item被选中,没有时不进入编辑
    pos 
= GetFirstSelectedItemPosition();
    
if( pos )
    {
        
// 得到被点击的Item
        LVHITTESTINFO testinfo;
        testinfo.pt.x 
= point.x;
        testinfo.pt.y 
= point.y;            //点击时的鼠标位置
        testinfo.flags 
= LVHT_ONITEMLABEL;    //点击的必须是标题
        
if( SubItemHitTest(&testinfo)<0 )
            goto defalt_session;            
//没有点在有效区域,不进入编辑
        m_nItem 
= testinfo.iItem;            //被点击表项的行号
        m_nSubItem 
= testinfo.iSubItem;    //被点击表项的列号

        
//if(m_nSubItem == 0)
        
//{
            
//goto defalt_session;            //选中第一列,不编辑
        
//}

        
// 检查该表项是否被选中,没被选中不进入编辑
        
while( pos )
            
if( m_nItem==GetNextSelectedItem(pos) )
            {
                bSelected 
= TRUE;
                
break;
            }
        
if( bSelected==FALSE )
            goto defalt_session;            
//没有点在有效区域,不编辑

        
// 开始编辑
        m_bEditing 
= BeginEdit();
        
return;
    }

defalt_session:
    CListCtrl::OnLButtonDown(nFlags, point);
}

7.   添加开始编辑函数BOOL BeginEdit();  完成新建CEdit对象、获取Edit输入文字等功能

BOOL CEditTable::BeginEdit()
{
    
// 得到被编辑表项的区域
    CRect rect;
    
if( GetSubItemRect(m_nItem, m_nSubItem, LVIR_LABEL, rect)==FALSE )
        
return FALSE;

    
// 创建编辑控件
    
int style =     WS_CHILD | 
                    WS_CLIPSIBLINGS 
|
                    WS_EX_TOOLWINDOW 
|
                    WS_BORDER;
    
if( m_edit.Create(style, rect, this, ID_MYEDIT)==FALSE )
        
return FALSE;

    
// 取被编辑表项的文字
    CString txtItem 
= GetItemText( m_nItem, m_nSubItem );

    
// 取出的文字填写到编辑控件
    m_edit
.SetWindowText( txtItem );
    m_edit
.SetFocus();
    m_edit
.SetSel( 0, -1 );
    m_edit
.ShowWindow( SW_SHOW );

    
return TRUE;
}

8.     添加结束编辑函数 void EndEdit( BOOL bValidate );  主要完成 替换Item内容、销毁编辑框等功能。

void CEditTable::EndEdit( BOOL bValidate )
{
    
// 编辑结果是有效的,重设被编辑表项的文字
    
if( bValidate )
    {
        CString txtItem;
        m_edit.GetWindowText( txtItem );
        SetItemText(m_nItem, m_nSubItem, txtItem);
    }

    
// 销毁编辑窗口
    m_edit.DestroyWindow();
    m_bEditing 
= FALSE;
}

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

LVITEM 列表视图控件(List Control) 显示图标

LVITEM列表视图控件(List Control) 列表视图控件是一种非常常用的控件,在需要以报表形式显示数据时,列表控件通常是最好的选择,许多专用的数据报表控件,也是在它的基础上派生而来。与树视...
  • form88
  • form88
  • 2017年02月17日 23:55
  • 608

PreTranslateMessage作用和使用方法

 PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗口的消息都要通过这里,比较常用,当需要在MFC之前处理某些消息时,常常要在这里添加代码...
  • wzyzb
  • wzyzb
  • 2009年03月05日 13:47
  • 35352

MFC点点滴滴——列表框使用list control(总结3)(控件技巧总汇 转)

以下未经说明,listctrl默认view风格为report ------------------------------------------------------------------...
  • zhd320
  • zhd320
  • 2011年09月11日 00:57
  • 1230

mfc控件——list control的使用

【前话】     编译原理的第一个实验——词法分析器验收时,老师要求最后的结果用GUI的形式表现出来。想想确实,黑白的控制台应用程序界面在用户操作时的确不如GUI 友好。GUI界面也算是大势所趋。我现...

List_Control控件技巧总汇

  • 2010年07月10日 13:58
  • 42KB
  • 下载

MFC List Control控件添加单元格编辑和单元格下拉列表项以适用于数据库相关操作

作为现代的软件,往往是连着数据库的,而连着和操作方便之间,还有着用户界面这道坎。MFC是Windows上比较好开发用户界面的封装类,然而其自带的控件中没有对于数据库表格支持较好的控件,这时利Activ...

Html List Control 控件

  • 2008年12月02日 09:07
  • 37KB
  • 下载

【MFC】List Control 控件实现翻页

  • 2012年07月25日 13:58
  • 1.85MB
  • 下载

MFC控件List Control的样式LVS_与扩展样式LVS_EX_

1. 首先区分LVS_与LVS_EX_,哪些是常规样式,哪些是扩展样式:能在属性对话框里看到的样式都是常规样式,例如LVS_REPORT。 扩展样式: LVS_EX_CHECKBOX...
  • whysnlc
  • whysnlc
  • 2012年07月25日 11:37
  • 2697
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:List Control控件高级应用——利用List Control控件制作表格
举报原因:
原因补充:

(最多只允许输入30个字)