#pragma once
|
#include <vector>
|
#include <memory>
|
|
class CExpandableListCtrl : public CListCtrl
|
{
|
DECLARE_DYNAMIC(CExpandableListCtrl)
|
|
public:
|
struct Node {
|
Node* parent = nullptr;
|
std::vector<std::unique_ptr<Node>> children;
|
std::vector<CString> cols; // ¸÷ÁÐÎı¾
|
bool expanded = false;
|
int level = 0; // Ëõ½ø²ã¼¶
|
|
Node(int nCols = 1) : cols(nCols) {}
|
};
|
|
CExpandableListCtrl();
|
virtual ~CExpandableListCtrl();
|
|
// Êý¾Ý¹¹½¨
|
Node* InsertRoot(const std::vector<CString>& cols);
|
Node* InsertChild(Node* parent, const std::vector<CString>& 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<std::unique_ptr<Node>> m_roots; // ¶¥²ã½Úµã
|
std::vector<Node*> m_visible; // Õ¹¿ªºóµÄ¿É¼û½Úµã˳Ðò
|
int m_expanderPadding = 6; // Ê×ÁÐÄÚ²à±ß¾à
|
int m_expanderSize = 10; // СÈý½Ç/·½¿é´óС
|
int m_textGap = 6;
|
};
|