分享

关于list control的高级应用

 我的读本 2010-09-10
论坛中搜索一下,你们会发现不少类似(的)提问:我们如何编辑list control(的)条目?如何直接编辑list control...等等;list control可用来做数据库表(的)视图,十分有用.
但报表风格(的)list control只能编辑第一列,其余(的)该死(的)微软没为vc做到.它们怕VB卖不出.于是C++程序员只好DIY.主要思想是在list control中动态创建一个控件,动态移动该控件到相应位置.这些技巧早有人讨论过了,本文也是基于如上思想(的),但注重于可扩充性与使用(的)方便.
List control 这头主要是重载OnLButtonDown技巧,计算出被点中(的)条目.这里重要(的)函数是SubItemHitTest和GetSubItemRect,看msdn上有相关说明. 用户点中后,就要负责显示控件了:如果之前选中了其他们,就要验证之前(的)改动是否成功.不成功就要回到原来(的)(地)方,成功就应用修改并移到新位置.看代码:
static     const UINT IDCHAILD=3000;
void CValidateList::OnLButtonDown(UINT nFlags, CPoint point)
{
     CListCtrl::OnLButtonDown(nFlags, point);
    LVHITTESTINFO hi;
    hi.pt = point;
    if(SubItemHitTest(&hi) != -1 )//没有点中条目就不管
    {if(m_col==-1||//-1 还没被选过
           true==(m_col+m_validate)->Validate (m_row))
       {
m_row = hi.iItem, m_col= hi.iSubItem;//m_row,m_col成
//员分别跟踪选中(的)行列
}
((m_col+m_validate))->Move (_GetRect(),m_row);
    }
}
 
WinBlast* CValidateList::SetValidate( WinBlast*in)//设置验证(的)
//控件群,in对应第一列,in+1第二列……
{
    WinBlast*ret=m_validate;
    m_validate=in;
    int counts=GetHeaderCtrl()->GetItemCount();;
    RECT rect;
     memset(&rect,0,sizeof(rect));
    for(int i=0;i<counts;++i)
         (in+i)->Create (this,rect,IDCHAILD+i,i);
    m_col=-1;//没有被选中(的)
    return ret;
}
 
 
RECT CValidateList::_GetRect()//内部使用,(得)到相应显示位置
{
    CRect ret;
GetSubItemRect(m_row,m_col,LVIR_BOUNDS,ret);
return ret;
}
 
void CValidateList::NoSelect()//置未选中状态
{
m_col=-1;//没有被选中(的)
}
看到了WinBlast*ret=m_validate吧.WinBlast是用来修改和验证数据(的)控件看它们(的)实现:
class WinBlast 
{
    int m_col;//跟踪列,为什么要这个?因为你们可以让一种控件对
//不同列用不同(的)验证策略
CWnd* m_win;//你们(的)控件窗口
    CListCtrl *m_parent;//用它们获(得)文本
public:
    WinBlast(){m_win=NULL;}
    ~WinBlast(){m_win->DestroyWindow();delete m_win;}
 
virtual    bool Create( CWnd* pParentWnd,
       const RECT& rect, UINT nID,
       int col)
    {
        m_col=col;m_parent=(CListCtrl *)pParentWnd;
        m_win=new CEdit;
            return  ((CEdit*)m_win)->
           Create(ES_NOHIDESEL,rect,pParentWnd,nID); 
       }
    void Move(const RECT &rect,int row)//最重要(的)函数但前面
//两个动作是必作(的),SetText为虚,你们在那做你们喜欢(的)
    {
        m_win->ShowWindow(SW_SHOW);
        m_win->MoveWindow(&rect);
        SetText(row);
    }
    virtual bool Validate(int row)//验证,虚函数.这里永远返回true
    {
        m_win->ShowWindow(SW_HIDE);
        CString set;
        m_win->GetWindowText(set);
        m_parent->SetItemText(row,m_col,set);
        return true;
    }
    virtual void SetText(int row)
    {
        m_win->SetWindowText(m_parent->GetItemText(row,m_col));

本文来自: 华军天空软件园(www.) 详细出处参考:http://www./dirss/html/179754.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章