使用soui开发的mbc,只支持windows版本
w1146869587
2022-01-24 0408576e9da10015ffa9da0079b8c985113ce4b3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#pragma once
 
#include "core/Swnd.h"
#include "core/SItemPanel.h"
#include "interface/Adapter-i.h"
#include "interface/TvItemLocator-i.h"
 
//
//#define EVT_EXTPANEL_MOUSEHOVER (EVT_EXTERNAL_BEGIN+600)
//#define EVT_EXTPANEL_MOUSELEAVE (EVT_EXTERNAL_BEGIN+601)
//class EventExtPanelMouseHover: public TplEventArgs<EventExtPanelMouseHover>
//{
//    SOUI_CLASS_NAME(EventChatEditKeyReturn,L"on_extpanel_mousehover")
//public:
//    EventExtPanelMouseHover(SObject *pSender):TplEventArgs<EventExtPanelMouseHover>(pSender){}
//    enum {EventID=EVT_EXTPANEL_MOUSEHOVER};
//};
 
namespace SOUI
{
    //////////////////////////////////////////////////////////////////////////
    class AFX_EXT_CLASS CMBTreeViewExItemLocator : public TObjRefImpl<ITreeViewItemLocator>
    {
    public:
        CMBTreeViewExItemLocator(int nIndent=10);
 
        ~CMBTreeViewExItemLocator();
 
        virtual void SetAdapter(ITvAdapter *pAdapter);
 
        virtual void OnBranchChanged(HTREEITEM hItem);
 
        virtual void OnBranchExpandedChanged(HTREEITEM hItem,BOOL bExpandedOld,BOOL bExpandedNew);
 
        virtual int GetTotalHeight() const;
 
        virtual int GetTotalWidth() const;
 
        virtual int GetScrollLineSize() const;
 
        virtual int Item2Position(HTREEITEM hItem) const;
 
        virtual HTREEITEM Position2Item(int position) const;
 
        virtual void SetItemWidth(HTREEITEM hItem,int nWidth);
 
        virtual void SetItemHeight(HTREEITEM hItem,int nHeight);
 
        virtual int GetItemWidth(HTREEITEM hItem) const;
 
        virtual int GetItemHeight(HTREEITEM hItem) const;
 
        virtual int GetItemIndent(HTREEITEM hItem) const;
    protected:
        BOOL IsItemExpanded(HTREEITEM hItem) const;
 
        //更新hItem所在的父窗口中分枝宽度数据
        //hItem:显示宽度发生变化的节点,可以是节点本身宽度变化,也可能是子节点宽度发生了变化
        //nOldWidth:原显示宽度
        //nNewWidth: 新显示宽度
        void _UpdateBranchWidth(HTREEITEM hItem,int nOldWidth,int nNewWidth);
 
        int _GetBranchWidth(HTREEITEM hBranch) const;
 
        void _SetBranchWidth(HTREEITEM hBranch,int nWidth);
 
        void _SetItemWidth(HTREEITEM hItem,int nWidth);
 
 
        int _GetBranchHeight(HTREEITEM hItem) const;
 
        void _SetBranchHeight(HTREEITEM hItem ,int nHeight);
 
        void _UpdateBranchHeight(HTREEITEM hItem,int nDiff);
 
        //向后更新兄弟结点的偏移量
        void _UpdateSiblingsOffset(HTREEITEM hItem);
 
        int _GetItemOffset(HTREEITEM hItem) const;
 
        void _SetItemOffset(HTREEITEM hItem, int nOffset);
 
        void _SetItemHeight(HTREEITEM hItem,int nHeight);
 
 
        int _GetItemVisibleHeight(HTREEITEM hItem) const;
 
        int _GetItemVisibleWidth(HTREEITEM hItem) const;
 
        HTREEITEM _Position2Item(int position,HTREEITEM hParent,int nParentPosition) const;
 
        BOOL _IsItemVisible(HTREEITEM hItem) const;
 
        void _InitBranch(HTREEITEM hItem);
 
 
        CAutoRefPtr<ITvAdapter> m_adapter;
        int                     m_nLineHeight;
        int                     m_nIndent;
        CSize                   m_szDef;
    };
    typedef SArray<HTREEITEM>  SArrayHTreeItem;
    typedef SMap<HTREEITEM,long>   SMapHTreeItem;
    class AFX_EXT_CLASS CMBTreeViewEx : public SPanel, protected IItemContainer
    {
        SOUI_CLASS_NAME(CMBTreeViewEx, L"MBTreeViewEx")
        friend class CMBTreeViewExDataSetObserver;
    public:
        CMBTreeViewEx();
        ~CMBTreeViewEx();
            
        BOOL SetAdapter(ITvAdapter * adapter);
        ITvAdapter * GetAdapter () { return m_adapter; }
        void SetItemLocator(ITreeViewItemLocator *pItemLocator)
        {
            m_tvItemLocator = pItemLocator;
        }
        
        ITreeViewItemLocator * GetItemLocator() const
        {
            return m_tvItemLocator;
        }
        
        
        void SetSel(HTREEITEM hItem,BOOL bNotify=FALSE);
        HTREEITEM  GetSel()const{return m_hSelected;}
        void  GetMulSels( SArrayHTreeItem &arSel);
        SItemPanel * HitTest(CPoint & pt);
 
        void EnsureVisible(HTREEITEM hItem);
        void SetSelNULL();
        void RemoveSel(HTREEITEM hItem);
        BOOL CheckIsSelected(HTREEITEM hItem);
        BOOL IsMulSel();
        void onBranchChanged(HTREEITEM hBranch);
    protected:
        bool OnItemClick(EventArgs *pEvt);
        bool OnItemDblClick(EventArgs *pEvt);
 
        
        void onBranchInvalidated(HTREEITEM hBranch);
        void onBranchExpandedChanged(HTREEITEM hBranch,BOOL bExpandedOld,BOOL bExpandedNew);
 
    protected:
        void OnPaint(IRenderTarget * pRT);
        void OnSize(UINT nType, CSize size);
        void OnDestroy();
         void OnKeyDown(TCHAR nChar, UINT nRepCnt, UINT nFlags);//实现键盘选择
        LRESULT OnKeyEvent( UINT uMsg,WPARAM wParam,LPARAM lParam );
        
        void OnMouseLeave();
        BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
        LRESULT OnMouseEvent(UINT uMsg,WPARAM wParam,LPARAM lParam);
 
        void OnKillFocus(SWND wndFocus);
        void OnSetFocus(SWND wndOld);
        
 
        SOUI_MSG_MAP_BEGIN()
            MSG_WM_PAINT_EX(OnPaint)
            MSG_WM_SIZE(OnSize)
            MSG_WM_DESTROY(OnDestroy)
            MSG_WM_KEYDOWN(OnKeyDown)
            MSG_WM_KILLFOCUS_EX(OnKillFocus)
            MSG_WM_SETFOCUS_EX(OnSetFocus)
            MSG_WM_MOUSEWHEEL(OnMouseWheel)
            MSG_WM_MOUSELEAVE(OnMouseLeave)
            MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST,WM_MOUSELAST,OnMouseEvent)
             MESSAGE_RANGE_HANDLER_EX(WM_KEYFIRST,WM_KEYLAST,OnKeyEvent)
             MESSAGE_RANGE_HANDLER_EX(WM_IME_STARTCOMPOSITION,WM_IME_KEYLAST,OnKeyEvent)
        SOUI_MSG_MAP_END()
        
    protected:
        HRESULT OnAttrIndent(const SStringW & strValue,BOOL bLoading);
        
        SOUI_ATTRS_BEGIN()
            ATTR_CUSTOM(L"indent",OnAttrIndent)
            ATTR_INT(L"wantTab", m_bWantTab,FALSE)
            ATTR_INT(L"mulsel", m_bIsMulSel,FALSE)
        SOUI_ATTRS_END()
    protected:
        virtual UINT OnGetDlgCode();
        virtual BOOL OnSetCursor(const CPoint &pt);
        virtual BOOL OnUpdateToolTip(CPoint pt, SwndToolTipInfo & tipInfo);
        virtual void OnColorize(COLORREF cr);
        virtual void OnScaleChanged(int nScale);
        virtual HRESULT OnLanguageChanged();
 
        virtual BOOL OnScroll(BOOL bVertical,UINT uCode,int nPos);
        virtual int  GetScrollLineSize(BOOL bVertical);
        virtual BOOL CreateChildren(pugi::xml_node xmlNode);
    
        virtual void OnItemSetCapture(SItemPanel *pItem,BOOL bCapture); //设置or释放鼠标捕获
        virtual BOOL OnItemGetRect(SItemPanel *pItem,CRect &rcItem);    //获得表项的显示位置
        virtual BOOL IsItemRedrawDelay();                               //指示表项的更新方式
        virtual void OnItemRequestRelayout(SItemPanel *pItem);          //列表项请求重新布局
    protected:
 
        void UpdateScrollBar();
        void UpdateVisibleItems();
 
 
        void RedrawItem(SItemPanel *pItem);
        void _SetSel(int iItem,BOOL bNotify, SWND hHitWnd);
        SItemPanel * GetItemPanel(HTREEITEM hItem);
 
        void DispatchMessage2Items(UINT uMsg,WPARAM wParam,LPARAM lParam);
    protected:
        CAutoRefPtr<ITvAdapter>        m_adapter;
        CAutoRefPtr<ITvDataSetObserver>   m_observer;
        CAutoRefPtr<ITreeViewItemLocator> m_tvItemLocator;
        
        struct ItemInfo
        {
            SItemPanel* pItem;
            int         nType;
        };
        SArray<SList<SItemPanel*> *>    m_itemRecycle;//item回收站,每一种样式在回收站中保持一个列表,以便重复利用
        SList<ItemInfo> m_visible_items; //可见元素
        
        typedef SMap<HTREEITEM,ItemInfo> VISIBLEITEMSMAP;
        VISIBLEITEMSMAP * m_pVisibleMap;
        
        pugi::xml_document m_xmlTemplate;
 
        SItemPanel * m_itemCapture;
        SItemPanel * m_pHoverItem;
        
        SMapHTreeItem m_mapSelected;
        HTREEITEM    m_hSelected;               /**< 当前选择项 */ 
        
        BOOL            m_bWantTab;             /**< want tab */ 
        BOOL           m_bIsMulSel;             /**时候允许多选 */ 
    };
}