ComboTreeCtrl2.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. // ComboTreeCtrl2.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "ComboTreeCtrl2.h"
  5. #include "TreeComboBox2.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CComboTreeCtrl2
  13. CComboTreeCtrl2::CComboTreeCtrl2()
  14. :m_pCombo(NULL)
  15. {
  16. }
  17. CComboTreeCtrl2::~CComboTreeCtrl2()
  18. {
  19. }
  20. BEGIN_MESSAGE_MAP(CComboTreeCtrl2, CTreeCtrl)
  21. //{{AFX_MSG_MAP(CComboTreeCtrl2)
  22. ON_NOTIFY_REFLECT(NM_KILLFOCUS, OnKillfocus)
  23. ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
  24. ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeydown)
  25. //}}AFX_MSG_MAP
  26. ON_MESSAGE(TREECTRL_CHECK_STATE_CHANGE, OnTreeCtrlCheckStateChange)
  27. END_MESSAGE_MAP()
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CComboTreeCtrl2 message handlers
  30. void CComboTreeCtrl2::Display(CRect rc, CString str)
  31. {
  32. SetWindowPos(&wndNoTopMost, rc.left, rc.top, rc.right, rc.bottom, SWP_SHOWWINDOW);
  33. CWnd* pTopParent = GetParent()->GetParentOwner();
  34. if(pTopParent != NULL)
  35. {
  36. pTopParent->SendMessage(WM_NCACTIVATE,TRUE);
  37. pTopParent->SetRedraw(TRUE);
  38. }
  39. ///////////////////////
  40. if(str=="")return;
  41. HTREEITEM hItem;
  42. HTREEITEM hRoot=GetRootItem();
  43. if(GetNextSiblingItem(hRoot))
  44. {
  45. FindItem2("xxxyyyzzz", hRoot);
  46. hItem=FindItem(str, hRoot);
  47. if(hItem)
  48. {
  49. // AfxMessageBox("111");
  50. SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
  51. EnsureVisible(hItem);
  52. }
  53. HTREEITEM hNext=GetNextSiblingItem(hRoot);
  54. while(hNext)
  55. {
  56. FindItem2("xxxyyyzzz", hNext);
  57. hItem=FindItem(str, hNext);
  58. if(hItem)
  59. {
  60. // AfxMessageBox("222");
  61. SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
  62. EnsureVisible(hItem);
  63. }
  64. hNext=GetNextSiblingItem(hNext);
  65. }
  66. }
  67. else
  68. {
  69. FindItem2("xxxyyyzzz", hRoot);
  70. hItem=FindItem(str, hRoot);
  71. if(hItem)
  72. {
  73. // AfxMessageBox("dddd");
  74. SetItemState(hItem, TVIS_SELECTED, TVIS_SELECTED);
  75. EnsureVisible(hItem);
  76. }
  77. }
  78. }
  79. BOOL CComboTreeCtrl2::PreTranslateMessage(MSG* pMsg)
  80. {
  81. // TODO: Add your specialized code here and/or call the base class
  82. if(pMsg->hwnd == m_hWnd && pMsg->message == WM_KEYDOWN &&
  83. (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
  84. {
  85. ::PostMessage(m_pCombo->m_hWnd,WMU_CLOSE_CONTROL,(WPARAM)0,(LPARAM)0);
  86. return TRUE;
  87. }
  88. return CTreeCtrl::PreTranslateMessage(pMsg);
  89. }
  90. void CComboTreeCtrl2::OnKillfocus(NMHDR* pNMHDR, LRESULT* pResult)
  91. {
  92. // TODO: Add your control notification handler code here
  93. ::PostMessage(m_pCombo->m_hWnd,WMU_CLOSE_CONTROL,(WPARAM)0,(LPARAM)0);
  94. }
  95. LRESULT CComboTreeCtrl2::OnTreeCtrlCheckStateChange(WPARAM wParam, LPARAM lParam)
  96. {
  97. HTREEITEM hItemChanged = (HTREEITEM)lParam;
  98. BOOL bCheckState = GetCheck(hItemChanged);
  99. SelectItem(hItemChanged);
  100. if(! bCheckState)UncheckChilds(hItemChanged,TRUE);
  101. else
  102. {
  103. while(hItemChanged = GetParentItem(hItemChanged))
  104. SetCheck(hItemChanged);
  105. }
  106. return 1;
  107. }
  108. void CComboTreeCtrl2::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
  109. {
  110. // TODO: Add your control notification handler code here
  111. UINT nFlags;
  112. HTREEITEM hItem;
  113. // verify that we have a mouse click in the check box area
  114. DWORD dwPos = GetMessagePos();
  115. CPoint point(LOWORD(dwPos),HIWORD(dwPos));
  116. ScreenToClient(&point);
  117. hItem = HitTest(point,&nFlags);
  118. if(hItem)
  119. {
  120. if(GetParentItem(hItem))
  121. ::PostMessage(m_pCombo->m_hWnd,WMU_CLOSE_CONTROL,(WPARAM)0,(LPARAM)hItem);
  122. // AfxMessageBox(GetItemText(hItem));
  123. }
  124. // if(hItem && (nFlags & TVHT_ONITEMSTATEICON))
  125. // PostMessage(TREECTRL_CHECK_STATE_CHANGE,0,(LPARAM)hItem);
  126. *pResult = 0;
  127. }
  128. void CComboTreeCtrl2::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
  129. {
  130. TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
  131. // TODO: Add your control notification handler code here
  132. if(pTVKeyDown->wVKey == VK_SPACE)
  133. {
  134. HTREEITEM hItem = GetSelectedItem();
  135. if(hItem != NULL)
  136. {
  137. // handle state change here or post message to another handler
  138. // Post message state has changed
  139. PostMessage(TREECTRL_CHECK_STATE_CHANGE,0,(LPARAM)hItem);
  140. }
  141. }
  142. *pResult = 0;
  143. }
  144. int CComboTreeCtrl2::UncheckChilds(HTREEITEM hItem/* = NULL*/, BOOL bRecurse/* = TRUE*/)
  145. {
  146. int nCount = 0;
  147. if(hItem == NULL)GetSelectedItem();
  148. if(ItemHasChildren(hItem))
  149. {
  150. hItem = GetNextItem(hItem,TVGN_CHILD);
  151. while(hItem)
  152. {
  153. nCount++;
  154. SetCheck(hItem,FALSE);
  155. if(bRecurse)nCount += UncheckChilds(hItem,bRecurse);
  156. hItem = GetNextItem(hItem,TVGN_NEXT);
  157. }
  158. }
  159. return nCount;
  160. }
  161. void CComboTreeCtrl2::GetTreeHierarchy(HTREEITEM hItem, CString &sTreeHierarchy, const BOOL bTopToBottom)
  162. {
  163. HTREEITEM hRoot = GetParentItem(hItem);
  164. if(hRoot != NULL)
  165. {
  166. sTreeHierarchy += GetItemText(hItem) + "\\";
  167. return;
  168. }
  169. if(! bTopToBottom)sTreeHierarchy += GetItemText(hItem) + "\\";
  170. GetTreeHierarchy(hRoot,sTreeHierarchy,bTopToBottom);
  171. if(bTopToBottom)sTreeHierarchy += GetItemText(hItem) + "\\";
  172. }
  173. HTREEITEM CComboTreeCtrl2::FindItem(const CString& sName, HTREEITEM hRoot)
  174. {
  175. // check whether the current item is the searched one
  176. CString sText = GetItemText(hRoot);
  177. if(sText.Compare(sName) == 0)return hRoot;
  178. // get a handle to the first child item
  179. HTREEITEM hSub = GetChildItem(hRoot);
  180. // iterate as long a new item is found
  181. while(hSub)
  182. {
  183. // check the children of the current item
  184. HTREEITEM hFound = FindItem(sName, hSub);
  185. if(hFound)return hFound;
  186. // get the next sibling of the current item
  187. hSub = GetNextSiblingItem(hSub);
  188. }
  189. return NULL;
  190. }
  191. HTREEITEM CComboTreeCtrl2::FindItem2(const CString& sName, HTREEITEM hRoot)
  192. {
  193. // check whether the current item is the searched one
  194. CString sText = GetItemText(hRoot);
  195. if(sText.Compare(sName) == 0)return hRoot;
  196. SetItemState(hRoot, 0, TVIS_SELECTED);
  197. // SetItemState(hRoot, 0, TVIS_EXPANDED);
  198. // get a handle to the first child item
  199. HTREEITEM hSub = GetChildItem(hRoot);
  200. // iterate as long a new item is found
  201. while(hSub)
  202. {
  203. SetItemState(hSub, 0, TVIS_SELECTED);
  204. // SetItemState(hSub, 0, TVIS_EXPANDED);
  205. // check the children of the current item
  206. HTREEITEM hFound = FindItem(sName, hSub);
  207. if(hFound)return hFound;
  208. // get the next sibling of the current item
  209. hSub = GetNextSiblingItem(hSub);
  210. }
  211. return NULL;
  212. }