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所提供...
  • wxl1986622
  • wxl1986622
  • 2011年11月30日 00:58
  • 1219

sql语句以及mysql详解(中级篇)

sql语句以及mysql详解 在基础篇中我们已经讲解了基础的增删改查的语法,接下来我们将主要讲解sql语句中的select语句,在其中有着很多的知识需要我们来学习。 比较运算符: >,>=, ...
  • chenqingmiaomiao
  • chenqingmiaomiao
  • 2014年02月21日 16:25
  • 931

《深入浅出学Java中级教程》

课程目录 第1节:开发流程及Eclipse使用 第2节:数据类型和数组 第3节:类声明和对象构造 第4节:集合入门 第5节:异常 第6节:JDBC-CLASS-...
  • xo_zhang
  • xo_zhang
  • 2013年05月06日 12:27
  • 1659

C语言学习-通过柴田望洋的《明解C语言》(1)

今天开始看柴田望洋的《明解c语言》,目的是做嵌入式开发的学习,所以会结合arm芯片进行学习。最终的目的是做一架小型的无人机,在2016年之前完成。分为三个阶段。     1.在十一月二日之前,用arm...
  • sinat_23121973
  • sinat_23121973
  • 2015年10月26日 21:32
  • 327

java并发编程学习总结(基础篇)

一、基础概念总结 1.多线程程序可能存在的风险: (1)安全性问题:多线程程序在没有充足同步的情况下,在特定的线程执行时序下,多个线程同时操作一块共享资源时,可能引发错误。 (2)活跃性问题...
  • lantian0802
  • lantian0802
  • 2014年02月16日 14:52
  • 1811

wsgi+webob+routes学习笔记-初学篇(中)

接上文: 可以看到wsgi已经在8090端口上建立了,用Rest client发个消息看下,可以看到已经收到了响应“Hello, World! I am sxmatch” 在以上程序中:方法d...
  • sxmatch
  • sxmatch
  • 2013年08月08日 10:47
  • 811

软考学习笔记

由于工作单位是国企原因,似乎还满看重软考的。 鉴于目前的水平,在同事的建议下想在新年下半年尝试一下软考中级中,软件设计师这个证书。 这个周末开始学习,发现这个考试的考点非常多,而且非常侧重于概念和...
  • stevenliyijun
  • stevenliyijun
  • 2017年03月19日 19:23
  • 88

wsgi+webob+routes学习笔记-初学篇(下)

5      将application封装为class进行调用 为了进一步接近openstack中用法,将上文中的application函数可以封装为class进行调用,代码如下: __autho...
  • sxmatch
  • sxmatch
  • 2013年08月08日 19:38
  • 777

CListCtrl学习笔记(2)---中级篇(1)如何使CListCtrl完全可编辑?

http://www.programfan.com/blog/article.asp?id=21881CListCtrl学习笔记(2)---中级篇(1)(2006-12-24 14:53:00)【收藏...
  • skyremember
  • skyremember
  • 2009年02月21日 15:20
  • 1287

java中级-1-基础知识回顾

------- android培训、java培训、期待与您交流! ---------- 前言 在学习新知识前,我们往往需要借鉴从前的学习经验来世我们能够更加快速的学习。为了能够简化大家的学习时间...
  • Tanzwind
  • Tanzwind
  • 2015年05月26日 17:00
  • 716
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CListCtrl学习笔记(2)---中级篇
举报原因:
原因补充:

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