惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
N
Netflix TechBlog - Medium
腾讯CDC
C
Check Point Blog
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
S
SegmentFault 最新的问题
F
Fortinet All Blogs
美团技术团队
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
F
Full Disclosure
Recorded Future
Recorded Future
D
DataBreaches.Net
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
J
Java Code Geeks
I
InfoQ
Y
Y Combinator Blog
A
About on SuperTechFans
AI
AI
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Forbes - Security
Forbes - Security
W
WeLiveSecurity
M
MIT News - Artificial intelligence
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Schneier on Security
Schneier on Security
The GitHub Blog
The GitHub Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Docker
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
V2EX - 技术
V2EX - 技术
Project Zero
Project Zero

博客园 - 凌点

clr20r3 system.InvalidOperationException 程序终止的几种解决方案 能上Q 不能上网 JavaScript中url 传递参数(特殊字符) apache 多站点配置 C#中使用 SendMessage 向非顶端窗体发送组合键 System.Xml.XmlException: 根级别上的数据无效 XP,WIN7双系统启动问题 VM安装XP注意事项 VC 命令行 捕获输出 make 信息重定向 VC 进度条制件CProgressCtrl 用法笔记 List Control 控件技巧总汇 VC中字符串取子串总结 如何禁用Windows屏保和电源管理 VC获取硬盘物理序列号 unicode cstring to char* - 凌点 将unicode的 Cstring 复制到粘贴板 VC由进程ID获取窗口句柄 嵌入式Linux操作系统学习规划
VC List Control控件高级使用
凌点 · 2010-07-29 · via 博客园 - 凌点

最近使用到了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;
}
本篇文章来源于 www.87717.com 原文链接:http://www.87717.com/vc/vc_11899_2.html