soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SAdapterBase.h
1#ifndef __SADAPTERBASE__H__
2#define __SADAPTERBASE__H__
3
4#include "interface/SAdapter-i.h"
5#include <souicoll.h>
6#include "control/STree.h"
7
8SNSBEGIN
9
10/**
11 * @class SLvObserverMgr
12 * @brief 管理列表数据集观察者的类
13 */
15 public:
16 /**
17 * @brief 构造函数
18 */
20 {
21 }
22
23 /**
24 * @brief 析构函数,释放所有观察者
25 */
27 {
28 SPOSITION pos = m_lstObserver.GetHeadPosition();
29 while (pos)
30 {
31 ILvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
32 pObserver->Release();
33 }
34 m_lstObserver.RemoveAll();
35 }
36
37 /**
38 * @brief 注册一个观察者
39 * @param observer 观察者对象指针
40 */
41 void registerObserver(ILvDataSetObserver *observer)
42 {
43 SASSERT(observer);
44 if (m_lstObserver.Find(observer))
45 return;
46 m_lstObserver.AddTail(observer);
47 observer->AddRef();
48 }
49
50 /**
51 * @brief 注销一个观察者
52 * @param observer 观察者对象指针
53 */
54 void unregisterObserver(ILvDataSetObserver *observer)
55 {
56 SASSERT(observer);
57 SPOSITION pos = m_lstObserver.Find(observer);
58 if (!pos)
59 return;
60 m_lstObserver.RemoveAt(pos);
61 observer->Release();
62 }
63
64 /**
65 * @brief 通知所有观察者数据集已更改
66 */
68 {
69 SPOSITION pos = m_lstObserver.GetHeadPosition();
70 while (pos)
71 {
72 ILvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
73 pObserver->onChanged();
74 }
75 }
76
77 /**
78 * @brief 通知所有观察者数据集已失效
79 */
81 {
82 SPOSITION pos = m_lstObserver.GetHeadPosition();
83 while (pos)
84 {
85 ILvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
86 pObserver->onInvalidated();
87 }
88 }
89
90 /**
91 * @brief 通知所有观察者指定项的数据已更改
92 * @param iItem 项索引
93 */
94 void notifyItemChanged(int iItem)
95 {
96 SPOSITION pos = m_lstObserver.GetHeadPosition();
97 while (pos)
98 {
99 ILvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
100 pObserver->OnItemChanged(iItem);
101 }
102 }
103
104 protected:
105 SList<ILvDataSetObserver *> m_lstObserver; ///< 观察者列表
106};
107
108/**
109 * @class LvAdatperImpl
110 * @brief 列表适配器实现模板类
111 * @tparam BaseClass 基类类型
112 */
113template <class BaseClass>
114class LvAdatperImpl : public BaseClass {
115 public:
116 /**
117 * @brief 通知所有观察者数据集已更改
118 */
120 {
121 m_obzMgr.notifyChanged();
122 }
123
124 /**
125 * @brief 通知所有观察者数据集已失效
126 */
128 {
129 m_obzMgr.notifyInvalidated();
130 }
131
132 /**
133 * @brief 通知所有观察者指定项的数据已更改
134 * @param iItem 项索引
135 */
136 void notifyItemDataChanged(int iItem)
137 {
138 m_obzMgr.notifyItemChanged(iItem);
139 }
140
141 /**
142 * @brief 注册一个数据集观察者
143 * @param observer 观察者对象指针
144 */
145 STDMETHOD_(void, registerDataSetObserver)(ILvDataSetObserver *observer) OVERRIDE
146 {
147 m_obzMgr.registerObserver(observer);
148 }
149
150 /**
151 * @brief 注销一个数据集观察者
152 * @param observer 观察者对象指针
153 */
154 STDMETHOD_(void, unregisterDataSetObserver)(ILvDataSetObserver *observer) OVERRIDE
155 {
156 m_obzMgr.unregisterObserver(observer);
157 }
158
159 /**
160 * @brief 获取视图
161 * @param position 位置索引
162 * @param pItem 项窗口对象
163 * @param pXmlTemplate XML模板对象
164 */
165 STDMETHOD_(void, getView)(int position, IWindow *pItem, IXmlNode *pXmlTemplate) OVERRIDE
166 {
167 SItemPanel *pItemPanel = sobj_cast<SItemPanel>(pItem);
168 SXmlNode xmlTemplate(pXmlTemplate);
169 getView(position, pItemPanel, xmlTemplate);
170 }
171
172 /**
173 * @brief 获取视图(模板函数)
174 * @param position 位置索引
175 * @param pItem 项面板对象
176 * @param xmlTemplate XML模板对象
177 */
178 STDMETHOD_(void, getView)(int position, SItemPanel *pItem, SXmlNode xmlTemplate)
179 {
180 SASSERT(FALSE);
181 }
182
183 /**
184 * @brief 获取项视图类型
185 * @param position 位置索引
186 * @return 视图类型
187 */
188 STDMETHOD_(int, getItemViewType)(int position)
189 {
190 (position);
191 return 0;
192 }
193
194 /**
195 * @brief 获取项视图类型(重载)
196 * @param position 位置索引
197 * @param dwState 状态
198 * @return 视图类型
199 */
200 STDMETHOD_(int, getItemViewType)(THIS_ int position, DWORD dwState) OVERRIDE
201 {
202 (dwState);
203 return getItemViewType(position);
204 }
205
206 /**
207 * @brief 获取视图类型数量
208 * @return 视图类型数量
209 */
210 STDMETHOD_(int, getViewTypeCount)() OVERRIDE
211 {
212 return 1;
213 }
214
215 /**
216 * @brief 检查数据集是否为空
217 * @return 数据集为空返回TRUE,否则返回FALSE
218 */
219 STDMETHOD_(BOOL, isEmpty)(THIS) OVERRIDE
220 {
221 return getCount() <= 0;
222 }
223
224 /**
225 * @brief 获取数据集项数量
226 * @return 数据集项数量
227 */
228 STDMETHOD_(int, getCount)(THIS) PURE;
229
230 /**
231 * @brief 获取项描述
232 * @param position 位置索引
233 * @return 项描述字符串
234 */
235 STDMETHOD_(SStringW, getItemDesc)(int position)
236 {
237 return L"";
238 }
239
240 /**
241 * @brief 获取项描述(重载)
242 * @param position 位置索引
243 * @param pDesc 描述字符串对象
244 */
245 STDMETHOD_(void, getItemDesc)(int position, IStringW *pDesc) OVERRIDE
246 {
247 SStringW strDesc = getItemDesc(position);
248 pDesc->Copy(&strDesc);
249 }
250
251 /**
252 * @brief 通过模板初始化适配器
253 * @param xmlTemplate XML模板对象
254 */
255 STDMETHOD_(void, InitByTemplate)(SXmlNode xmlTemplate)
256 {
257 (xmlTemplate);
258 }
259
260 /**
261 * @brief 通过模板初始化适配器(重载)
262 * @param pXmlTemplate XML模板对象指针
263 */
264 STDMETHOD_(void, InitByTemplate)(IXmlNode *pXmlTemplate) OVERRIDE
265 {
266 SXmlNode xmlTempalte(pXmlTemplate);
267 InitByTemplate(xmlTempalte);
268 }
269
270 /**
271 * @brief 获取视图所需大小
272 * @param ret 返回的大小对象
273 * @param position 位置索引
274 * @param pItem 项面板对象
275 * @param wid 宽度
276 * @param hei 高度
277 */
278 STDMETHOD_(void, getViewDesiredSize)(SIZE *ret, int position, SItemPanel *pItem, int wid, int hei)
279 {
280 pItem->GetDesiredSize(ret, wid, hei);
281 }
282
283 /**
284 * @brief 获取视图所需大小(重载)
285 * @param ret 返回的大小对象
286 * @param position 位置索引
287 * @param pItem 项窗口对象
288 * @param wid 宽度
289 * @param hei 高度
290 */
291 STDMETHOD_(void, getViewDesiredSize)(SIZE *ret, int position, IWindow *pItem, int wid, int hei) OVERRIDE
292 {
293 SItemPanel *pItemPanel = sobj_cast<SItemPanel>(pItem);
294 getViewDesiredSize(ret, position, pItemPanel, wid, hei);
295 }
296
297 /**
298 * @brief 查询接口
299 * @param id 接口ID
300 * @param ppObj 接口对象指针
301 * @return 查询结果
302 */
303 STDMETHOD_(HRESULT, QueryInterface)(THIS_ REFGUID id, IObjRef **ppObj) OVERRIDE
304 {
305 return E_NOINTERFACE;
306 }
307
308 protected:
309 SLvObserverMgr m_obzMgr; ///< 观察者管理器
310};
311
312/**
313 * @class SAdapterBase
314 * @brief 列表适配器基类
315 */
316class SAdapterBase : public TObjRefImpl<LvAdatperImpl<ILvAdapter>> {
317 public:
318 /**
319 * @brief 构造函数
320 */
322 {
323 }
324
325 /**
326 * @brief 析构函数
327 */
329 {
330 }
331};
332
333/**
334 * @class SMcAdapterBase
335 * @brief 多列适配器基类
336 */
337class SMcAdapterBase : public TObjRefImpl<LvAdatperImpl<IMcAdapter>> {
338 public:
339 /**
340 * @brief 构造函数
341 */
343 {
344 }
345
346 /**
347 * @brief 析构函数
348 */
350 {
351 }
352
353 /**
354 * @brief 排序项
355 * @param iCol 列索引
356 * @param pFmts 格式数组
357 * @param nCols 列数量
358 * @return 排序结果
359 */
360 STDMETHOD_(BOOL, OnSort)(int iCol, UINT *pFmts, int nCols) OVERRIDE
361 {
362 (iCol);
363 (pFmts);
364 (nCols);
365 return FALSE;
366 }
367
368 /**
369 * @brief 获取列名
370 * @param iCol 列索引
371 * @return 列名字符串
372 */
373 STDMETHOD_(SStringW, GetColumnName)(int iCol) SCONST
374 {
375 return L"";
376 }
377
378 /**
379 * @brief 获取列名(重载)
380 * @param iCol 列索引
381 * @param pName 列名字符串对象
382 */
383 STDMETHOD_(void, GetColumnName)(THIS_ int iCol, IStringW *pName) SCONST
384 {
385 SStringW strName = GetColumnName(iCol);
386 pName->Copy(&strName);
387 }
388
389 /**
390 * @brief 检查列是否可见
391 * @param iCol 列索引
392 * @return 列可见返回TRUE,否则返回FALSE
393 */
394 STDMETHOD_(BOOL, IsColumnVisible)(THIS_ int iCol) SCONST OVERRIDE
395 {
396 (iCol);
397 return TRUE;
398 }
399
400 /**
401 * @brief 通过模板初始化适配器
402 * @param xmlTemplate XML模板对象
403 */
404 STDMETHOD_(void, InitByTemplate)(THIS_ SXmlNode xmlTemplate)
405 {
406 }
407
408 /**
409 * @brief 通过模板初始化适配器(重载)
410 * @param xmlTemplate XML模板对象指针
411 */
412 STDMETHOD_(void, InitByTemplate)(THIS_ IXmlNode *xmlTemplate) OVERRIDE
413 {
414 SXmlNode xmlNode(xmlTemplate);
415 InitByTemplate(xmlNode);
416 }
417
418 /**
419 * @brief 设置列宽
420 * @param pColWid 列宽数组
421 * @param nCols 列数量
422 */
423 STDMETHOD_(void, SetColumnsWidth)(THIS_ int *pColWid, int nCols) OVERRIDE
424 {
425 (pColWid);
426 (nCols);
427 }
428};
429
430/**
431 * @class STvObserverMgr
432 * @brief 管理树形数据集观察者的类
433 */
435 public:
436 /**
437 * @brief 构造函数
438 */
440 {
441 }
442
443 /**
444 * @brief 析构函数,释放所有观察者
445 */
447 {
448 SPOSITION pos = m_lstObserver.GetHeadPosition();
449 while (pos)
450 {
451 ITvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
452 pObserver->Release();
453 }
454 m_lstObserver.RemoveAll();
455 }
456
457 /**
458 * @brief 注册一个观察者
459 * @param observer 观察者对象指针
460 */
461 void registerObserver(ITvDataSetObserver *observer)
462 {
463 SASSERT(observer);
464 if (m_lstObserver.Find(observer))
465 return;
466 m_lstObserver.AddTail(observer);
467 observer->AddRef();
468 }
469
470 /**
471 * @brief 注销一个观察者
472 * @param observer 观察者对象指针
473 */
474 void unregisterObserver(ITvDataSetObserver *observer)
475 {
476 SASSERT(observer);
477 SPOSITION pos = m_lstObserver.Find(observer);
478 if (!pos)
479 return;
480 m_lstObserver.RemoveAt(pos);
481 observer->Release();
482 }
483
484 /**
485 * @brief 通知所有观察者分支已更改
486 * @param hBranch 分支句柄
487 */
488 void notifyChanged(HSTREEITEM hBranch)
489 {
490 SPOSITION pos = m_lstObserver.GetHeadPosition();
491 while (pos)
492 {
493 ITvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
494 pObserver->onBranchChanged(hBranch);
495 }
496 }
497
498 /**
499 * @brief 通知所有观察者分支已失效
500 * @param hBranch 分支句柄
501 * @param bInvalidParents 父节点是否失效
502 * @param bInvalidChildren 子节点是否失效
503 */
504 void notifyInvalidated(HSTREEITEM hBranch, bool bInvalidParents, bool bInvalidChildren)
505 {
506 SPOSITION pos = m_lstObserver.GetHeadPosition();
507 while (pos)
508 {
509 ITvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
510 pObserver->onBranchInvalidated(hBranch, bInvalidParents, bInvalidChildren);
511 }
512 }
513
514 /**
515 * @brief 通知所有观察者分支展开状态已更改
516 * @param hBranch 分支句柄
517 * @param bExpandedOld 旧展开状态
518 * @param bExpandedNew 新展开状态
519 */
520 void notifyExpandChanged(HSTREEITEM hBranch, BOOL bExpandedOld, BOOL bExpandedNew)
521 {
522 SPOSITION pos = m_lstObserver.GetHeadPosition();
523 while (pos)
524 {
525 ITvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
526 pObserver->onBranchExpandedChanged(hBranch, bExpandedOld, bExpandedNew);
527 }
528 }
529
530 /**
531 * @brief 通知所有观察者项将被移除
532 * @param hItem 项句柄
533 */
534 void notifyItemBeforeRemove(HSTREEITEM hItem)
535 {
536 SPOSITION pos = m_lstObserver.GetHeadPosition();
537 while (pos)
538 {
539 ITvDataSetObserver *pObserver = m_lstObserver.GetNext(pos);
540 pObserver->notifyItemBeforeRemove(hItem);
541 }
542 }
543
544 protected:
545 SList<ITvDataSetObserver *> m_lstObserver; ///< 观察者列表
546};
547
548/**
549 * @class TvAdatperImpl
550 * @brief 树形适配器实现模板类
551 * @tparam BaseClass 基类类型
552 */
553template <class BaseClass>
554class TvAdatperImpl : public BaseClass {
555 public:
556 /**
557 * @brief 通知所有观察者分支已更改
558 * @param hBranch 分支句柄
559 */
560 void notifyBranchChanged(HSTREEITEM hBranch)
561 {
562 m_obzMgr.notifyChanged(hBranch);
563 }
564
565 /**
566 * @brief 通知所有观察者分支已失效
567 * @param hBranch 分支句柄
568 * @param bInvalidParents 父节点是否失效
569 * @param bInvalidChildren 子节点是否失效
570 */
571 void notifyBranchInvalidated(HSTREEITEM hBranch, bool bInvalidParents = true, bool bInvalidChildren = true)
572 {
573 m_obzMgr.notifyInvalidated(hBranch, bInvalidParents, bInvalidChildren);
574 }
575
576 /**
577 * @brief 通知所有观察者分支展开状态已更改
578 * @param hBranch 分支句柄
579 * @param bExpandedOld 旧展开状态
580 * @param bExpandedNew 新展开状态
581 */
582 void notifyBranchExpandChanged(HSTREEITEM hBranch, BOOL bExpandedOld, BOOL bExpandedNew)
583 {
584 m_obzMgr.notifyExpandChanged(hBranch, bExpandedOld, bExpandedNew);
585 }
586
587 /**
588 * @brief 通知所有观察者项将被移除
589 * @param hItem 项句柄
590 */
591 void notifyItemBeforeRemove(HSTREEITEM hItem)
592 {
593 m_obzMgr.notifyItemBeforeRemove(hItem);
594 }
595
596 /**
597 * @brief 注册一个数据集观察者
598 * @param observer 观察者对象指针
599 */
600 STDMETHOD_(void, registerDataSetObserver)(ITvDataSetObserver *observer) OVERRIDE
601 {
602 m_obzMgr.registerObserver(observer);
603 }
604
605 /**
606 * @brief 注销一个数据集观察者
607 * @param observer 观察者对象指针
608 */
609 STDMETHOD_(void, unregisterDataSetObserver)(ITvDataSetObserver *observer) OVERRIDE
610 {
611 m_obzMgr.unregisterObserver(observer);
612 }
613
614 protected:
615 STvObserverMgr m_obzMgr; ///< 观察者管理器
616};
617
618/**
619 * @class STreeAdapterBase
620 * @brief 树形适配器基类模板
621 * @tparam T 数据类型
622 */
623template <typename T>
624class STreeAdapterBase : public TObjRefImpl<TvAdatperImpl<ITvAdapter>> {
625 public:
626 /**
627 * @brief 数据释放函数类型
628 */
629 typedef void (*FunTvItemDataFreer)(T cb);
630
631 /**
632 * @struct ItemInfo
633 * @brief 树节点数据结构
634 */
635 struct ItemInfo
636 {
637 ULONG_PTR userData[DATA_INDEX_NUMBER]; ///< 用户数据数组
638 T data; ///< 数据对象
639 };
640
641 /**
642 * @class TreeDataFreer
643 * @brief 树节点数据释放器类
644 */
645 class TreeDataFreer : public CSTree<ItemInfo>::IDataFreer {
646 public:
647 /**
648 * @brief 构造函数
649 */
651 : m_dataFreer(NULL)
652 {
653 }
654
655 FunTvItemDataFreer m_dataFreer; ///< 数据释放函数
656
657 /**
658 * @brief 释放数据
659 * @param data 数据对象引用
660 */
661 void OnDataFree(ItemInfo &data) override
662 {
663 if (m_dataFreer)
664 m_dataFreer(data.data);
665 }
666 };
667
668 public:
669 /**
670 * @brief 构造函数
671 */
673 {
674 memset(m_rootUserData, 0, sizeof(m_rootUserData));
675 m_tree.SetDataFreer(&m_treeFreer);
676 }
677
678 /**
679 * @brief 析构函数
680 */
682 {
683 m_tree.DeleteAllItems();
684 }
685
686 /**
687 * @brief 获取hItem中的指定索引的数据
688 * @param hItem 项句柄
689 * @param idx 索引
690 * @return 用户数据
691 */
692 STDMETHOD_(ULONG_PTR, GetItemDataByIndex)(HSTREEITEM hItem, DATA_INDEX idx) const OVERRIDE
693 {
694 if (hItem == ITEM_ROOT)
695 return m_rootUserData[idx];
696 ItemInfo &ii = m_tree.GetItemRef((HSTREEITEM)hItem);
697 return ii.userData[idx];
698 }
699
700 /**
701 * @brief 保存hItem指定索引的数据
702 * @param hItem 项句柄
703 * @param idx 索引
704 * @param data 数据
705 */
706 STDMETHOD_(void, SetItemDataByIndex)(HSTREEITEM hItem, DATA_INDEX idx, ULONG_PTR data) OVERRIDE
707 {
708 if (hItem == ITEM_ROOT)
709 m_rootUserData[idx] = data;
710 else
711 {
712 ItemInfo &ii = m_tree.GetItemRef((HSTREEITEM)hItem);
713 ii.userData[idx] = data;
714 }
715 }
716
717 /**
718 * @brief 获取父项
719 * @param hItem 项句柄
720 * @return 父项句柄
721 */
722 STDMETHOD_(HSTREEITEM, GetParentItem)(HSTREEITEM hItem) const OVERRIDE
723 {
724 if (hItem == ITEM_ROOT)
725 return ITEM_NULL;
726 HSTREEITEM hParent = m_tree.GetParentItem((HSTREEITEM)hItem);
727 if (hParent == 0)
728 hParent = ITEM_ROOT;
729 return (HSTREEITEM)hParent;
730 }
731
732 /**
733 * @brief 检查是否有子项
734 * @param hItem 项句柄
735 * @return 有子项返回TRUE,否则返回FALSE
736 */
737 STDMETHOD_(BOOL, HasChildren)(HSTREEITEM hItem) const OVERRIDE
738 {
739 return GetFirstChildItem(hItem) != ITEM_NULL;
740 }
741
742 /**
743 * @brief 获取第一个子项
744 * @param hItem 项句柄
745 * @return 第一个子项句柄
746 */
747 STDMETHOD_(HSTREEITEM, GetFirstChildItem)(HSTREEITEM hItem) const OVERRIDE
748 {
749 SASSERT(hItem != ITEM_NULL);
750 return (HSTREEITEM)m_tree.GetChildItem((HSTREEITEM)hItem, TRUE);
751 }
752
753 /**
754 * @brief 获取最后一个子项
755 * @param hItem 项句柄
756 * @return 最后一个子项句柄
757 */
758 STDMETHOD_(HSTREEITEM, GetLastChildItem)(HSTREEITEM hItem) const OVERRIDE
759 {
760 SASSERT(hItem != ITEM_NULL);
761 return (HSTREEITEM)m_tree.GetChildItem((HSTREEITEM)hItem, FALSE);
762 }
763
764 /**
765 * @brief 获取前一个兄弟项
766 * @param hItem 项句柄
767 * @return 前一个兄弟项句柄
768 */
769 STDMETHOD_(HSTREEITEM, GetPrevSiblingItem)(HSTREEITEM hItem) const OVERRIDE
770 {
771 SASSERT(hItem != ITEM_NULL && hItem != ITEM_ROOT);
772 return (HSTREEITEM)m_tree.GetPrevSiblingItem((HSTREEITEM)hItem);
773 }
774
775 /**
776 * @brief 获取下一个兄弟项
777 * @param hItem 项句柄
778 * @return 下一个兄弟项句柄
779 */
780 STDMETHOD_(HSTREEITEM, GetNextSiblingItem)(HSTREEITEM hItem) const OVERRIDE
781 {
782 SASSERT(hItem != ITEM_NULL && hItem != ITEM_ROOT);
783 return (HSTREEITEM)m_tree.GetNextSiblingItem((HSTREEITEM)hItem);
784 }
785
786 /**
787 * @brief 检查是否为后代项
788 * @param hItem 父项句柄
789 * @param hChild 子项句柄
790 * @return 是后代项返回TRUE,否则返回FALSE
791 */
792 STDMETHOD_(BOOL, IsDecendentItem)(CTHIS_ HSTREEITEM hItem, HSTREEITEM hChild) const OVERRIDE
793 {
794 HSTREEITEM hParent = GetParentItem(hChild);
795 while (hParent)
796 {
797 if (hParent == hItem)
798 return TRUE;
799 hParent = GetParentItem(hParent);
800 }
801 return FALSE;
802 }
803
804 /**
805 * @brief 获取项视图类型
806 * @param hItem 项句柄
807 * @return 视图类型
808 */
809 STDMETHOD_(int, getViewType)(HSTREEITEM hItem) const OVERRIDE
810 {
811 return 0;
812 }
813
814 /**
815 * @brief 获取视图类型数量
816 * @return 视图类型数量
817 */
818 STDMETHOD_(int, getViewTypeCount)() const OVERRIDE
819 {
820 return 1;
821 }
822
823 /**
824 * @brief 获取视图
825 * @param hItem 项句柄
826 * @param pItem 项面板对象
827 * @param xmlTemplate XML模板对象
828 */
829 STDMETHOD_(void, getView)(THIS_ HSTREEITEM hItem, SItemPanel *pItem, SXmlNode xmlTemplate)
830 {
831 }
832
833 /**
834 * @brief 获取视图(重载)
835 * @param hItem 项句柄
836 * @param pItem 项窗口对象
837 * @param pXmlTemplate XML模板对象指针
838 */
839 STDMETHOD_(void, getView)(THIS_ HSTREEITEM hItem, IWindow *pItem, IXmlNode *pXmlTemplate) OVERRIDE
840 {
841 SItemPanel *pItemPanel = sobj_cast<SItemPanel>(pItem);
842 SXmlNode xmlTemplate(pXmlTemplate);
843 return getView(hItem, pItemPanel, xmlTemplate);
844 }
845
846 /**
847 * @brief 获取视图所需大小
848 * @param ret 返回的大小对象
849 * @param hItem 项句柄
850 * @param pItem 项面板对象
851 * @param wid 宽度
852 * @param hei 高度
853 */
854 STDMETHOD_(void, getViewDesiredSize)(SIZE *ret, HSTREEITEM hItem, SItemPanel *pItem, int wid, int hei)
855 {
856 pItem->GetDesiredSize(ret, wid, hei);
857 }
858
859 /**
860 * @brief 获取视图所需大小(重载)
861 * @param ret 返回的大小对象
862 * @param hItem 项句柄
863 * @param pItem 项窗口对象
864 * @param wid 宽度
865 * @param hei 高度
866 */
867 STDMETHOD_(void, getViewDesiredSize)(SIZE *ret, HSTREEITEM hItem, IWindow *pItem, int wid, int hei) OVERRIDE
868 {
869 SItemPanel *pItemPanel = sobj_cast<SItemPanel>(pItem);
870 getViewDesiredSize(ret, hItem, pItemPanel, wid, hei);
871 }
872
873 /**
874 * @brief 通过模板初始化适配器
875 * @param xmlTemplate XML模板对象
876 */
877 STDMETHOD_(void, InitByTemplate)(SXmlNode xmlTemplate)
878 {
879 (xmlTemplate);
880 }
881
882 /**
883 * @brief 通过模板初始化适配器(重载)
884 * @param pXmlTemplate XML模板对象指针
885 */
886 STDMETHOD_(void, InitByTemplate)(IXmlNode *pXmlTemplate) OVERRIDE
887 {
888 SXmlNode xmlTemplate(pXmlTemplate);
889 return InitByTemplate(xmlTemplate);
890 }
891
892 /**
893 * @brief 检查视图宽度是否匹配父容器
894 * @return 匹配返回TRUE,否则返回FALSE
895 */
896 STDMETHOD_(BOOL, isViewWidthMatchParent)() const OVERRIDE
897 {
898 return FALSE;
899 }
900
901 /**
902 * @brief 展开或折叠项
903 * @param hItem 项句柄
904 * @param uCode 展开/折叠代码
905 */
906 STDMETHOD_(void, ExpandItem)(HSTREEITEM hItem, UINT uCode) OVERRIDE
907 {
908 BOOL bExpandedOld = IsItemExpanded(hItem);
909 BOOL bExpandedNew = bExpandedOld;
910 switch (uCode)
911 {
912 case TVC_COLLAPSE:
913 bExpandedNew = FALSE;
914 break;
915 case TVC_EXPAND:
916 bExpandedNew = TRUE;
917 break;
918 case TVC_TOGGLE:
919 bExpandedNew = !bExpandedOld;
920 break;
921 }
922 if (bExpandedOld == bExpandedNew)
923 return;
924
925 SetItemExpanded(hItem, bExpandedNew);
926 notifyBranchExpandChanged(hItem, bExpandedOld, bExpandedNew);
927 }
928
929 /**
930 * @brief 检查项是否展开
931 * @param hItem 项句柄
932 * @return 展开返回TRUE,否则返回FALSE
933 */
934 STDMETHOD_(BOOL, IsItemExpanded)(HSTREEITEM hItem) const OVERRIDE
935 {
936 if (hItem == ITEM_ROOT)
937 return TRUE; // 虚拟根节点自动展开
938 return (BOOL)GetItemDataByIndex(hItem, DATA_INDEX_ITEM_EXPANDED);
939 }
940
941 /**
942 * @brief 设置项展开状态
943 * @param hItem 项句柄
944 * @param bExpanded 展开状态
945 */
946 STDMETHOD_(void, SetItemExpanded)(HSTREEITEM hItem, BOOL bExpanded) OVERRIDE
947 {
948 SetItemDataByIndex(hItem, DATA_INDEX_ITEM_EXPANDED, bExpanded);
949 }
950
951 /**
952 * @brief 检查项是否可见
953 * @param hItem 项句柄
954 * @return 可见返回TRUE,否则返回FALSE
955 */
956 STDMETHOD_(BOOL, IsItemVisible)(HSTREEITEM hItem) const OVERRIDE
957 {
958 HSTREEITEM hParent = GetParentItem(hItem);
959 while (hParent != ITEM_NULL)
960 {
961 if (!IsItemExpanded(hParent))
962 return FALSE;
963 hParent = GetParentItem(hParent);
964 }
965 return TRUE;
966 }
967
968 /**
969 * @brief 获取第一个可见项
970 * @return 第一个可见项句柄
971 */
972 STDMETHOD_(HSTREEITEM, GetFirstVisibleItem)() const OVERRIDE
973 {
974 return GetFirstChildItem(ITEM_ROOT);
975 }
976
977 /**
978 * @brief 获取最后一个可见项
979 * @return 最后一个可见项句柄
980 */
981 STDMETHOD_(HSTREEITEM, GetLastVisibleItem)() const OVERRIDE
982 {
983 HSTREEITEM hItem = GetLastChildItem(ITEM_ROOT);
984 if (hItem == ITEM_NULL)
985 return hItem;
986 for (; IsItemExpanded(hItem);)
987 {
988 HSTREEITEM hChild = GetLastChildItem(hItem);
989 if (hChild == ITEM_NULL)
990 break;
991 hItem = hChild;
992 }
993 return hItem;
994 }
995
996 /**
997 * @brief 获取前一个可见项
998 * @param hItem 项句柄
999 * @return 前一个可见项句柄
1000 */
1001 STDMETHOD_(HSTREEITEM, GetPrevVisibleItem)(HSTREEITEM hItem) const OVERRIDE
1002 {
1003 SASSERT(IsItemVisible(hItem));
1004 HSTREEITEM hRet = GetPrevSiblingItem(hItem);
1005 if (hRet == ITEM_NULL)
1006 {
1007 hRet = GetParentItem(hItem);
1008 if (hRet == ITEM_ROOT)
1009 hRet = ITEM_NULL;
1010 }
1011 return hRet;
1012 }
1013
1014 /**
1015 * @brief 获取下一个可见项
1016 * @param hItem 项句柄
1017 * @return 下一个可见项句柄
1018 */
1019 STDMETHOD_(HSTREEITEM, GetNextVisibleItem)(HSTREEITEM hItem) const OVERRIDE
1020 {
1021 SASSERT(IsItemVisible(hItem));
1022 if (IsItemExpanded(hItem))
1023 {
1024 HSTREEITEM hChild = GetFirstChildItem(hItem);
1025 if (hChild != ITEM_NULL)
1026 return hChild;
1027 }
1028
1029 HSTREEITEM hParent = hItem;
1030 while (hParent != ITEM_NULL && hParent != ITEM_ROOT)
1031 {
1032 HSTREEITEM hRet = GetNextSiblingItem(hParent);
1033 if (hRet)
1034 return hRet;
1035 hParent = GetParentItem(hParent);
1036 }
1037 return ITEM_NULL;
1038 }
1039
1040 /**
1041 * @brief 查询接口
1042 * @param id 接口ID
1043 * @param ppObj 接口对象指针
1044 * @return 查询结果
1045 */
1046 STDMETHOD_(HRESULT, QueryInterface)(THIS_ REFGUID id, IObjRef **ppObj) OVERRIDE
1047 {
1048 return E_NOINTERFACE;
1049 }
1050
1051 public:
1052 /**
1053 * @brief 插入项
1054 * @param data 数据对象
1055 * @param hParent 父项句柄
1056 * @param hInsertAfter 插入位置
1057 * @return 插入的项句柄
1058 */
1059 HSTREEITEM InsertItem(const T &data, HSTREEITEM hParent = STVI_ROOT, HSTREEITEM hInsertAfter = STVI_LAST)
1060 {
1061 ItemInfo ii = { 0 };
1062 ii.data = data;
1063 return m_tree.InsertItem(ii, hParent, hInsertAfter);
1064 }
1065
1066 /**
1067 * @brief 删除项
1068 * @param hItem 项句柄
1069 * @param bNotifyChange 是否通知更改
1070 */
1071 void DeleteItem(HSTREEITEM hItem, BOOL bNotifyChange = TRUE)
1072 {
1073 HSTREEITEM hParent = GetParentItem(hItem);
1074 if (!hParent)
1075 hParent = STVI_ROOT;
1076 if (bNotifyChange)
1077 {
1079 }
1080 m_tree.DeleteItem(hItem);
1081 if (bNotifyChange)
1082 {
1083 notifyBranchChanged(hParent);
1084 }
1085 }
1086
1087 /**
1088 * @brief 删除项(扩展)
1089 * @param hItem 项句柄
1090 * @return 删除结果
1091 */
1092 BOOL DeleteItemEx(HSTREEITEM hItem)
1093 {
1094 return m_tree.DeleteItemEx(hItem);
1095 }
1096
1097 /**
1098 * @brief 获取项数据
1099 * @param hItem 项句柄
1100 * @return 数据对象引用
1101 */
1102 const T &GetItemData(HSTREEITEM hItem) const
1103 {
1104 SASSERT(hItem != STVI_ROOT);
1105 ItemInfo &ii = m_tree.GetItemRef((HSTREEITEM)hItem);
1106 return ii.data;
1107 }
1108
1109 /**
1110 * @brief 设置项数据
1111 * @param hItem 项句柄
1112 * @param data 数据对象
1113 */
1114 void SetItemData(HSTREEITEM hItem, const T &data)
1115 {
1116 SASSERT(hItem != STVI_ROOT);
1117 ItemInfo &ii = m_tree.GetItemRef((HSTREEITEM)hItem);
1118 ii.data = data;
1119 }
1120
1121 /**
1122 * @brief 设置数据释放函数
1123 * @param freer 数据释放函数
1124 */
1126 {
1127 m_treeFreer.m_dataFreer = freer;
1128 }
1129
1130 protected:
1131 CSTree<ItemInfo> m_tree; ///< 树对象
1132 TreeDataFreer m_treeFreer; ///< 树数据释放器
1133 ULONG_PTR m_rootUserData[DATA_INDEX_NUMBER]; ///< 根节点用户数据
1134};
1135
1136SNSEND
1137
1138#endif // __SADAPTERBASE__H__
Tree template for general data types.
#define STVI_ROOT
Definition STree.h:43
#define STVI_LAST
Definition STree.h:45
Template class for a tree structure.
Definition STree.h:56
列表适配器实现模板类
void notifyDataSetChanged()
通知所有观察者数据集已更改
int getItemViewType(int position)
获取项视图类型
void getView(int position, IWindow *pItem, IXmlNode *pXmlTemplate) OVERRIDE
获取视图
SLvObserverMgr m_obzMgr
观察者管理器
HRESULT QueryInterface(REFGUID id, IObjRef **ppObj) OVERRIDE
查询接口
void InitByTemplate(SXmlNode xmlTemplate)
通过模板初始化适配器
void unregisterDataSetObserver(ILvDataSetObserver *observer) OVERRIDE
注销一个数据集观察者
BOOL isEmpty() OVERRIDE
检查数据集是否为空
SStringW getItemDesc(int position)
获取项描述
void registerDataSetObserver(ILvDataSetObserver *observer) OVERRIDE
注册一个数据集观察者
void notifyItemDataChanged(int iItem)
通知所有观察者指定项的数据已更改
void getViewDesiredSize(SIZE *ret, int position, SItemPanel *pItem, int wid, int hei)
获取视图所需大小
int getViewTypeCount() OVERRIDE
获取视图类型数量
void notifyDataSetInvalidated()
通知所有观察者数据集已失效
int getCount() PURE
获取数据集项数量
SAdapterBase()
构造函数
~SAdapterBase()
析构函数
管理列表数据集观察者的类
void notifyInvalidated()
通知所有观察者数据集已失效
void notifyChanged()
通知所有观察者数据集已更改
void unregisterObserver(ILvDataSetObserver *observer)
注销一个观察者
SList< ILvDataSetObserver * > m_lstObserver
观察者列表
SLvObserverMgr()
构造函数
void registerObserver(ILvDataSetObserver *observer)
注册一个观察者
~SLvObserverMgr()
析构函数,释放所有观察者
void notifyItemChanged(int iItem)
通知所有观察者指定项的数据已更改
void InitByTemplate(SXmlNode xmlTemplate)
通过模板初始化适配器
~SMcAdapterBase()
析构函数
void SetColumnsWidth(int *pColWid, int nCols) OVERRIDE
设置列宽
SMcAdapterBase()
构造函数
BOOL OnSort(int iCol, UINT *pFmts, int nCols) OVERRIDE
排序项
SStringW GetColumnName(int iCol) SCONST
获取列名
BOOL IsColumnVisible(int iCol) SCONST OVERRIDE
检查列是否可见
A class representing an ASCII string.
Definition sstringw.h:96
树节点数据释放器类
FunTvItemDataFreer m_dataFreer
数据释放函数
void OnDataFree(ItemInfo &data) override
释放数据
HSTREEITEM GetParentItem(HSTREEITEM hItem) const OVERRIDE
获取父项
void SetDataFreer(FunTvItemDataFreer freer)
设置数据释放函数
TreeDataFreer m_treeFreer
树数据释放器
HSTREEITEM GetFirstVisibleItem() const OVERRIDE
获取第一个可见项
void getViewDesiredSize(SIZE *ret, HSTREEITEM hItem, SItemPanel *pItem, int wid, int hei)
获取视图所需大小
HSTREEITEM InsertItem(const T &data, HSTREEITEM hParent=STVI_ROOT, HSTREEITEM hInsertAfter=STVI_LAST)
插入项
~STreeAdapterBase()
析构函数
void(* FunTvItemDataFreer)(T cb)
数据释放函数类型
BOOL IsDecendentItem(HSTREEITEM hItem, HSTREEITEM hChild) const OVERRIDE
检查是否为后代项
void getView(HSTREEITEM hItem, SItemPanel *pItem, SXmlNode xmlTemplate)
获取视图
CSTree< ItemInfo > m_tree
树对象
BOOL IsItemExpanded(HSTREEITEM hItem) const OVERRIDE
检查项是否展开
void ExpandItem(HSTREEITEM hItem, UINT uCode) OVERRIDE
展开或折叠项
BOOL IsItemVisible(HSTREEITEM hItem) const OVERRIDE
检查项是否可见
HSTREEITEM GetNextSiblingItem(HSTREEITEM hItem) const OVERRIDE
获取下一个兄弟项
HSTREEITEM GetFirstChildItem(HSTREEITEM hItem) const OVERRIDE
获取第一个子项
HSTREEITEM GetNextVisibleItem(HSTREEITEM hItem) const OVERRIDE
获取下一个可见项
ULONG_PTR m_rootUserData[DATA_INDEX_NUMBER]
根节点用户数据
BOOL HasChildren(HSTREEITEM hItem) const OVERRIDE
检查是否有子项
void DeleteItem(HSTREEITEM hItem, BOOL bNotifyChange=TRUE)
删除项
void SetItemData(HSTREEITEM hItem, const T &data)
设置项数据
const T & GetItemData(HSTREEITEM hItem) const
获取项数据
HSTREEITEM GetPrevVisibleItem(HSTREEITEM hItem) const OVERRIDE
获取前一个可见项
STreeAdapterBase()
构造函数
HSTREEITEM GetPrevSiblingItem(HSTREEITEM hItem) const OVERRIDE
获取前一个兄弟项
HRESULT QueryInterface(REFGUID id, IObjRef **ppObj) OVERRIDE
查询接口
ULONG_PTR GetItemDataByIndex(HSTREEITEM hItem, DATA_INDEX idx) const OVERRIDE
获取hItem中的指定索引的数据
void InitByTemplate(SXmlNode xmlTemplate)
通过模板初始化适配器
BOOL isViewWidthMatchParent() const OVERRIDE
检查视图宽度是否匹配父容器
HSTREEITEM GetLastVisibleItem() const OVERRIDE
获取最后一个可见项
int getViewTypeCount() const OVERRIDE
获取视图类型数量
HSTREEITEM GetLastChildItem(HSTREEITEM hItem) const OVERRIDE
获取最后一个子项
void SetItemExpanded(HSTREEITEM hItem, BOOL bExpanded) OVERRIDE
设置项展开状态
int getViewType(HSTREEITEM hItem) const OVERRIDE
获取项视图类型
BOOL DeleteItemEx(HSTREEITEM hItem)
删除项(扩展)
void SetItemDataByIndex(HSTREEITEM hItem, DATA_INDEX idx, ULONG_PTR data) OVERRIDE
保存hItem指定索引的数据
管理树形数据集观察者的类
void notifyChanged(HSTREEITEM hBranch)
通知所有观察者分支已更改
void notifyExpandChanged(HSTREEITEM hBranch, BOOL bExpandedOld, BOOL bExpandedNew)
通知所有观察者分支展开状态已更改
void registerObserver(ITvDataSetObserver *observer)
注册一个观察者
SList< ITvDataSetObserver * > m_lstObserver
观察者列表
STvObserverMgr()
构造函数
void unregisterObserver(ITvDataSetObserver *observer)
注销一个观察者
void notifyInvalidated(HSTREEITEM hBranch, bool bInvalidParents, bool bInvalidChildren)
通知所有观察者分支已失效
void notifyItemBeforeRemove(HSTREEITEM hItem)
通知所有观察者项将被移除
~STvObserverMgr()
析构函数,释放所有观察者
Class representing an XML node.
Definition SXml.h:352
树形适配器实现模板类
void registerDataSetObserver(ITvDataSetObserver *observer) OVERRIDE
注册一个数据集观察者
void notifyBranchInvalidated(HSTREEITEM hBranch, bool bInvalidParents=true, bool bInvalidChildren=true)
通知所有观察者分支已失效
void notifyBranchChanged(HSTREEITEM hBranch)
通知所有观察者分支已更改
void notifyItemBeforeRemove(HSTREEITEM hItem)
通知所有观察者项将被移除
STvObserverMgr m_obzMgr
观察者管理器
void unregisterDataSetObserver(ITvDataSetObserver *observer) OVERRIDE
注销一个数据集观察者
void notifyBranchExpandChanged(HSTREEITEM hBranch, BOOL bExpandedOld, BOOL bExpandedNew)
通知所有观察者分支展开状态已更改
Interface for reference counting.
Definition obj-ref-i.h:19
Interface for XML nodes.
Definition sxml-i.h:128
树节点数据结构
ULONG_PTR userData[DATA_INDEX_NUMBER]
用户数据数组