#pragma once #include #include class CExpandableListCtrl : public CListCtrl { DECLARE_DYNAMIC(CExpandableListCtrl) public: struct Node { Node* parent = nullptr; std::vector> children; std::vector cols; // ¸÷ÁÐÎı¾ bool expanded = false; int level = 0; // Ëõ½ø²ã¼¶ Node(int nCols = 1) : cols(nCols) {} }; CExpandableListCtrl(); virtual ~CExpandableListCtrl(); // Êý¾Ý¹¹½¨ Node* InsertRoot(const std::vector& cols); Node* InsertChild(Node* parent, const std::vector& cols); // Õ¹¿ª/ÕÛµþ void Expand(Node* n); void Collapse(Node* n); void Toggle(Node* n); // ˢпɼûÁбí void RebuildVisible(); // ±ã½Ý£ºÍ¨¹ý¿É¼ûÐкÅÈ¡ Node* Node* GetNodeByVisibleIndex(int i) const; private: void appendVisible(Node* n); CRect expanderRectForRow(int row) const; // Ê×ÁÐÕ¹¿ª°´Å¥ÇøÓò virtual void PreSubclassWindow(); protected: // ÏûÏ¢ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult); DECLARE_MESSAGE_MAP() private: std::vector> m_roots; // ¶¥²ã½Úµã std::vector m_visible; // Õ¹¿ªºóµÄ¿É¼û½Úµã˳Ðò int m_expanderPadding = 6; // Ê×ÁÐÄÚ²à±ß¾à int m_expanderSize = 10; // СÈý½Ç/·½¿é´óС int m_textGap = 6; };