爱新觉罗二狗 2024-11-26 08:40 采纳率: 40%
浏览 77
已结题

MFC的CListCtrl控件上添加一个按钮,并添加按钮点击事件

需求是MFC的CListCtrl控件上添加一个按钮,并添加按钮点击事件
遇到的问题是,向BEGIN_MESSAGE_MAP中添加事件,由于创建按钮的父类是CListCtrl,不是Dialog,导致点击事件不触发。现在的实现代码如下:

插入按钮,nAxisList是CListCtrl控件,IDC_DYNAMIC_BUTTON 为按钮统一标识符

    CRect rect;
    UINT uStyle = BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP;
    nAxisList.GetSubItemRect( nRowIndex, 10, LVIR_BOUNDS, rect );
    CButton* nAxisOn = new CButton();
    nAxisOn->Create( _T( "开启使能" ), uStyle, rect, &nAxisList, /*nRowIndex * 100 + 10*/ IDC_DYNAMIC_BUTTON );


按钮点击事件

BEGIN_MESSAGE_MAP( Dlg, CDialogEx )
    ON_BN_CLICKED( IDC_DYNAMIC_BUTTON, &Dlg::OnClickAxis )    
END_MESSAGE_MAP()
  • 写回答

1条回答 默认 最新

  • 赵4老师 2024-11-26 09:24
    关注
    
    CListCtrl 控件本身并不直接支持在列表项上添加按钮。不过,你可以通过一些技巧来实现类似的效果,比如使用自定义绘制来绘制按钮外观,并处理鼠标点击事件来模拟按钮点击。
    
    以下是一个基本步骤的概述,以及相应的代码示例:
    
    ‌自定义绘制列表项‌:
    使用 CListCtrl 的自定义绘制功能(如 NM_CUSTOMDRAW 通知)来在列表项的特定位置绘制一个按钮的外观。
    
    ‌处理鼠标点击‌:
    重载 CListCtrl 的鼠标事件处理函数(如 LButtonDown 或 LButtonUp),检测鼠标点击的位置是否在自定义按钮的区域内,并相应地触发按钮点击事件。
    
    下面是一个简单的示例代码,展示了如何实现这些步骤:
    
    cpp
    class CMyListCtrl : public CListCtrl
    {
        DECLARE_DYNAMIC(CMyListCtrl)
    
    public:
        CMyListCtrl();
        virtual ~CMyListCtrl();
    
    protected:
        DECLARE_MESSAGE_MAP()
    
        afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
        afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
    
        // 用于存储按钮矩形区域的变量(这里以简单示例,只存储一个按钮)
        CRect m_buttonRect;
        bool m_isButtonPressed;
    
    public:
        afx_msg void OnMyButtonClicked(); // 自定义的按钮点击事件处理函数
    };
    
    IMPLEMENT_DYNAMIC(CMyListCtrl, CListCtrl)
    
    CMyListCtrl::CMyListCtrl()
        : m_isButtonPressed(false)
    {
    }
    
    CMyListCtrl::~CMyListCtrl()
    {
    }
    
    BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
        ON_WM_LBUTTONDOWN()
        ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CMyListCtrl::OnNMCustomdraw)
    END_MESSAGE_MAP()
    
    void CMyListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
    {
        CListCtrl::OnLButtonDown(nFlags, point);
    
        // 检查点击是否在按钮区域内
        if (m_buttonRect.PtInRect(point))
        {
            m_isButtonPressed = true;
            // 触发自定义的按钮点击事件
            OnMyButtonClicked();
            // 你可以在这里添加其他处理逻辑,比如改变按钮状态等
        }
    }
    
    void CMyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
    {
        LPNMLVCUSTOMDRAW pLVCD = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
        *pResult = CDRF_DODEFAULT;
    
        // 在这里进行自定义绘制
        if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
        {
            // 获取当前项的矩形区域
            CRect itemRect;
            GetSubItemRect(pLVCD->nmcd.dwItemSpec, pLVCD->iSubItem, LVIR_BOUNDS, itemRect);
    
            // 在项内绘制一个按钮(这里只是示例,你可以根据需要调整位置和大小)
            m_buttonRect = CRect(itemRect.right - 50, itemRect.top + 5, itemRect.right - 10, itemRect.bottom - 5);
            CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
            pDC->Rectangle(m_buttonRect);
            pDC->TextOutW(m_buttonRect.left + 10, m_buttonRect.CenterPoint().y - 5, L"Button");
    
            *pResult = CDRF_SKIPDEFAULT; // 跳过默认绘制
        }
    }
    
    void CMyListCtrl::OnMyButtonClicked()
    {
        // 在这里处理按钮点击事件
        AfxMessageBox(L"Button clicked!");
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月4日
  • 已采纳回答 11月26日
  • 创建了问题 11月26日