我用的是带复选按钮的那种样式。DWORD OldStyle = m_listExchange.GetExtendedStyle();
    m_listExchange.SetExtendedStyle( OldStyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | WS_EX_STATICEDGE | LVS_EX_CHECKBOXES );
我需要做的操作是,单击listctrl控件的第一列的某个单元格即表示选中这个项所表示的这一行,那个复选框主要是为了标识此行是否选中。我所做的项目主要是商品交易相关的。我要把所有可兑换的商品都列出来,由于数据量可能会比较大,因此我们采取按页获取数据信息(每次请求获取一次数据,因为安全考虑,我目前只能获得一串字符串然后自己解析,所以我不能用SQL语句来做)。我就自己用CCtrlList来实现翻页功能。如果要翻页的话,那么上一页的信息是必须要保存的,而且用户选中一下则他的可用积分就会减少,我要进行判断并给出提示(是否超出积分可用值),因此不可能最终通过点击一个按钮,然后逐个判断选中状态来处理。所以我采用用户单击最左面那一列的某项,我就进行相应的处理。问题是:
1、如果单击那个复选框,则指示正常,如果单击的地方不在复选框上(还在那个单元格,但单击的地方在复选框旁边一点),则此时依然会触发单击事件,但复选框却是未选中状态。2、由于上面的原因我就采取下面的方式:void CExChange::OnClickListToExchange(NMHDR* pNMHDR, LRESULT* pResult) 
{
    // TODO: Add your control notification handler code here
    int nRow = ( (NM_LISTVIEW *)pNMHDR )->iItem;
    int nCol = ( (NM_LISTVIEW *)pNMHDR )->iSubItem;
    BOOL bSelected = FALSE;    // 选择数据区域无效
    if( nRow > m_vecItem.size() )
    {
        *pResult = 0;
        return;
    }
    
    // 选中或取消选中
    if( nCol == 0 )
    {
        ...
        bSelected = m_listExchange.GetCheck( nRow );        // 选中操作
        if( !bSelected )
        {
            ...
         }
        // 取消选中操作
        else
        {
            ...
        }
    }
    
    *pResult = 0;
}
这样的话问题又来了,此时点击复选框旁边的确可以实现我的功能,但如果此时点中的正是复选框,则复选框则没有动作了。有没有办法来区分第一列某项所点击的是复选框还是其它区域,或者在我目前代码基础上改变复选框状态也行(我试过此时调用SetCheck好像不行),或者复选框状态改变时有没有什么消息?谢谢!!

解决方案 »

  1.   

    哈哈,完美解决,列出答案,也和马克思同志共享一下。
    void CTestDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult) 
    {
        // TODO: Add your control notification handler code here
        int nRow = ((NM_LISTVIEW *)pNMHDR)->iItem;
        int nClo = ((NM_LISTVIEW *)pNMHDR)->iSubItem;
        BOOL bCheck = m_listExchange.GetCheck( nRow );
        m_listExchange.SetCheck( nRow, !bCheck );
        m_listExchange.SetItemState( nRow, LVIS_SELECTED, LVIS_SELECTED );    *pResult = 1;
    }