CListCtrl学习笔记(2)---中级篇

转载 2012年03月23日 00:22:25

专题1: 如何使CListCtrl完全可编辑?

1.       背景 : 我们知道如果CListCtrl是报表样式,那么CListCtrl所提供的编辑功能只局限于第一列.也就是说只有第一列可编辑.这样显然无法满足一般数据库的要求.我们想要每个子项都能编辑.

2.       思路 : CEdit是一个很好的可控制编辑控件.如何把CEdit和我们的CListCtrl联系起来?一种很好的想法是------一般我们如果想编辑某一项,那么就应该去双击.双击以后就让CEdit在那里显示,当然要把大小调整和子项表格一样.如果CEdit失去了焦点,表示修改完毕,那么立即更改子项的数据,同时让CEdit隐藏.因为每次只能编辑一项,所以只需要一个CEdit就够了.

3.       方法:

(1)    首先从CListCtrl派生一个类,其他已经有的变量或者函数设置我已经介绍,如果不清楚的读者,可以去参考”基础篇”.

(2)    有一点可以肯定,我们必须响应双击事件:

void Cmylist::OnLButtonDblClk(UINT nFlags, CPoint point)

{

int index;//行号

int colnum;//列号

GetWindowRect(r);//稍后说明

GetParent()->ScreenToClient(r);//稍后说明

if((index=HitTestEx(point,&colnum))!=-1)

    EditSubItem(index,colnum);

CListCtrl::OnLButtonDblClk(nFlags, point);

}

其中HitTestEx是用来求出双击点所在的行列号,如果行号不为-1,那么就调用函数EditSubItem. 这个函数会根据行列号求出该子项具体坐标,方便CEdit调整位置.

(3)    如何求出行列号?行号是很好求出来的 ,但是列号就不是很简单了,必须详细判断.

int Cmylist::HitTestEx(CPoint &point, int *pcolumn)

{

       int columnNum=0;

//获取页面内首行索引号,不一定是0,要考虑滚动条的情况

int row=GetTopIndex();

// GetCountPerPage()获取在页面内行的总数

       int bottom=row+this->GetCountPerPage();

       // 防止超出范围

       if(bottom>this->GetItemCount())

              bottom=GetItemCount();

       //获取列的总数

       int ncolumncount=this->GetHeaderCtrl()->GetItemCount();

       //可以肯定双击点肯定在页面内,因此从页面首行索引号开始判断

       for(;row<=bottom;++row)

       {

              CRect rect;

              //求出行的rect

              GetItemRect(row,&rect,LVIR_BOUNDS);

              //点是否在行的矩形内

              if(rect.PtInRect(point))

              //如果点在行的矩形内,求出点在哪一列

                     for(columnNum=0;columnNum<ncolumncount;columnNum++)

                     {

                            //求出列的宽度

                            int colwidth=this->GetColumnWidth(columnNum);

                            if(point.x>=rect.left&&point.x<=(rect.left+colwidth))

                            {

                                   *pcolumn=columnNum;

                                   return row;

                            }

                            rect.left+=colwidth;

                     }

       }

       return -1;

}

当然上面那种方法有点复杂,是完全从头开始判断.其实我们可以先利用CListCtrl提供的函数求出行号,再求列号,这样稍微简单点

int Cmylist::HitTestEx(CPoint &point, int *pcolumn)

{

       int columnNum=0;

       int row=HitTest(point);//求出行号

    int ncolumncount=this->GetHeaderCtrl()->GetItemCount();

         LVHITTESTINFO Info;
        Info.pt=point;
        this->SubItemHitTest(&Info);
       *pcolumn=Info.iSubItem;

       if(*pcolumn>=0&&*pcolumn<ncolumncount)
       return row;

       else

        return -1;

       /* int ncolumncount=this->GetHeaderCtrl()->GetItemCount();

       

              CRect rect;

              GetItemRect(row,&rect,LVIR_BOUNDS);

              if(rect.PtInRect(point))

                     for(columnNum=0;columnNum<ncolumncount;columnNum++)

                     {

                            int colwidth=this->GetColumnWidth(columnNum);

                            if(point.x>=rect.left&&point.x<=(rect.left+colwidth))

                            {

                                   *pcolumn=columnNum;

                                   return row;

                            }

                            rect.left+=colwidth;

                     }*/

       

       }

(4)    求出具体CEdit移动坐标

int Cmylist::Item_X(int row, int column,CRect& rect_X)

{

       int offset=0;

       for(int i=0;i<column;i++)

              offset+=GetColumnWidth(i);

       CRect rect;

       GetItemRect(row,rect,LVIR_BOUNDS);

       //注意水平滚动条的影响,如果已经移动了水平滚动条,可能left0,或者超出总大小

       if(offset+rect.left<0||offset+rect.left>client_rect.right)

       {

              CSize size;

              //offset肯定为正,如果出现了rect.left为负

              if(offset+rect.left>0)

                     size.cx=- (offset+rect.left);

              else

                     size.cx=offset+rect.left;

              size.cy=0;//垂直不用管

              //如果某一列的一半在滚动条左边,一半在右边,就再次调整滚动条的位置.

              Scroll(size);

              rect.left - =size.cx;

       }

       rect.left+=offset+2;

       rect.right=rect.left+GetColumnWidth(column)-2;

       //bottomtop不用管

       rect_X=rect;

       return rect.right;

}

(5)    移动CEdit

void Cmylist::EditSubItem(int Item, int Column)

{

       CRect rect;

       //求出行列所在rect

       this->Item_X(Item,Column,rect);

       EditCellShow(rect,Item,Column,r);

}

void Cmylist::EditCellShow(CRect rect, int Item, int Column,CRect r)

{

       //还记得r?在开始的双击函数OnLButtonDblClk,它是CListCtrl在父窗口中的位置

    rect.left+=r.left;

       rect.top+=r.top+2;

       rect.right+=r.left;

       rect.bottom+=r.top+2;

//peditCEdit对象的指针,提供接口,只要在程序中让pedit指向一个对象即可

       pedit->MoveWindow(rect,TRUE);

       pedit->ShowWindow(TRUE);  

       pedit->SetFocus();

}

^_^!这样就完成了.效果还可以.当然你还要去响应CEdit失去焦点和得到焦点的事件.这个就不是我的任务了,因为每个人的要求不一样啊!

看看我的效果!

相关文章推荐

CListCtrl学习笔记(2)---中级篇

CListCtrl学习笔记(2)---中级篇 专题1: 如何使CListCtrl完全可编辑? 1.       背景 : 我们知道如果CListCtrl是报表样式,那么CListCtrl所提供...

Android中级学习笔记(二)之Source Insight 查看Android源码(图文)

第一步:创建一个新的项目。打开Source Insight,点击菜单栏中的Project,选中其中的New Project。得到如下的窗口:(注意:第二空尽量不要含有中文,会带来麻烦)        ...
  • o411524
  • o411524
  • 2016年03月20日 14:45
  • 1507

Android中级学习笔记(一)之eclipse查看Android源码(图文)

第一步:首先得下载你想查看的Android源码,以下是Android2.3的源码下载地址。 http://download.csdn.net/detail/o411524/9465987 第二...
  • o411524
  • o411524
  • 2016年03月18日 18:47
  • 135

vim菜鸟学习-中级篇2(vim常用快捷键)

首先声明,这个文章不是用来学习的,是用来查阅的。 原文地址:http://www.cnblogs.com/wangkangluo1/archive/2012/04/12/2444952.html ...

mybatis学习教程中级(十一)mybatis和spring框架整合(前奏篇2)

1、前言 我们前奏篇讲解了用dao+daoimpl+spring整合sqlconfig。我们发现还有daoimpl这个东西,这一章我们也就讲解,去掉这个impl吧。使用mapper代理方式。 ...

Struts2学习笔记

  • 2017年11月02日 20:27
  • 257KB
  • 下载

javascript学习笔记2

  • 2017年07月31日 00:43
  • 3KB
  • 下载

2、Websphere学习笔记之二安装Installation Manager篇

2、Websphere学习笔记之一安装Installation Manager篇          继续来看下如何安装Websphere吧。 关键字:Websphere 安装  IBM Install...
  • notbaron
  • notbaron
  • 2015年03月30日 23:06
  • 31135

code__opengl学习笔记2-绘制矩形

  • 2013年09月24日 23:03
  • 797KB
  • 下载

struts2學習筆記

  • 2013年04月18日 00:27
  • 1.96MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CListCtrl学习笔记(2)---中级篇
举报原因:
原因补充:

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