Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
8.2 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1993 **
  4. //*********************************************************************
  5. #include "admincfg.h"
  6. HTREEITEM hItemPressed = NULL;
  7. VOID ProcessMouseDown(HWND hDlg,HWND hwndTree);
  8. VOID ProcessMouseUp(HWND hDlg,HWND hwndTree);
  9. BOOL ProcessExpand(HWND hDlg,HWND hwndTree,TV_ITEM * ptvi,
  10. BOOL fExpanding);
  11. BOOL ProcessSelection(HWND hDlg,HWND hwndTree,NM_TREEVIEW * pntv);
  12. VOID ProcessPolicyCheckbox(HWND hDlg,HWND hwndTree,HTREEITEM hItem,BOOL fHasSel);
  13. UINT AdvanceCheckboxState(UINT uImage);
  14. BOOL IsAncestorOfSelection(HWND hwndTree,HTREEITEM hParent);
  15. BOOL IsSelectedItemChecked(HWND hwndTree);
  16. BOOL ProcessCheckboxFromKeyboard(HWND hDlg,HWND hwndTree);
  17. BOOL OnTreeNotify(HWND hDlg,HWND hwndTree,NM_TREEVIEW *pntv)
  18. {
  19. switch (pntv->hdr.code) {
  20. case NM_CLICK:
  21. ProcessMouseUp(hDlg,hwndTree);
  22. return 0;
  23. break;
  24. case TVN_ITEMEXPANDING:
  25. // if we're collapsing a branch that contains the current
  26. // selection, validate its controls
  27. if ( ((pntv->action & TVE_ACTIONMASK) == TVE_COLLAPSE)
  28. && IsSelectedItemChecked(hwndTree)
  29. && IsAncestorOfSelection(hwndTree,pntv->itemNew.hItem)
  30. && !ProcessSettingsControls(hDlg,PSC_VALIDATENOISY))
  31. return TRUE; // invalid stuff in ctrls, don't allow collapse
  32. return ProcessExpand(hDlg,hwndTree,&pntv->itemNew,
  33. ((pntv->action & TVE_ACTIONMASK) == TVE_EXPAND) );
  34. break;
  35. case TVN_SELCHANGING:
  36. return ProcessSelection(hDlg,hwndTree,pntv);
  37. break;
  38. case TVN_KEYDOWN:
  39. {
  40. WORD wKey = ( (TV_KEYDOWN *) pntv)->wVKey;
  41. if (wKey == VK_SPACE) {
  42. return ProcessCheckboxFromKeyboard(hDlg,hwndTree);
  43. }
  44. return FALSE;
  45. }
  46. break;
  47. }
  48. return 0;
  49. }
  50. VOID ProcessMouseDown(HWND hDlg,HWND hwndTree)
  51. {
  52. TV_HITTESTINFO ht;
  53. TV_ITEM tvi;
  54. POLICYDLGINFO * pdi;
  55. TABLEENTRY * pTableEntry;
  56. if (!(pdi = (POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER)))
  57. return;
  58. GetCursorPos(&ht.pt);
  59. ScreenToClient(hwndTree,&ht.pt);
  60. if (TreeView_HitTest(hwndTree,&ht) && ht.flags & TVHT_ONITEMICON) {
  61. tvi.mask = TVIF_HANDLE;
  62. tvi.hItem = ht.hItem;
  63. if (!TreeView_GetItem(hwndTree,&tvi)) return;
  64. pTableEntry = (TABLEENTRY *) tvi.lParam;
  65. if (!pTableEntry || pTableEntry->dwType != ETYPE_POLICY) return;
  66. hItemPressed = tvi.hItem;
  67. }
  68. }
  69. VOID ProcessMouseUp(HWND hDlg,HWND hwndTree)
  70. {
  71. BOOL fHasSel = TRUE;
  72. if (hItemPressed) {
  73. // if checkbox for item other than selected item is being changed,
  74. // validate setting controls for current selection because selection
  75. // will change.
  76. if (hItemPressed != TreeView_GetSelection(hwndTree)) {
  77. if (!ProcessSettingsControls(hDlg,PSC_NOVALIDATE)) {
  78. hItemPressed = NULL;
  79. return;
  80. }
  81. fHasSel = FALSE;
  82. }
  83. ProcessPolicyCheckbox(hDlg,hwndTree,hItemPressed,fHasSel);
  84. hItemPressed = NULL;
  85. }
  86. }
  87. BOOL ProcessCheckboxFromKeyboard(HWND hDlg,HWND hwndTree)
  88. {
  89. TV_ITEM tvi;
  90. TABLEENTRY * pTableEntry;
  91. if (!(tvi.hItem = TreeView_GetSelection(hwndTree)))
  92. return FALSE;
  93. tvi.mask = TVIF_PARAM;
  94. if (!TreeView_GetItem(hwndTree,&tvi))
  95. return FALSE;
  96. pTableEntry = (TABLEENTRY *) tvi.lParam;
  97. if (!pTableEntry || pTableEntry->dwType != ETYPE_POLICY)
  98. return FALSE;
  99. ProcessPolicyCheckbox(hDlg,hwndTree,tvi.hItem,TRUE);
  100. return TRUE;
  101. }
  102. VOID ProcessMouseMove(HWND hwndDlg,HWND hwndTree)
  103. {
  104. if (!hItemPressed) return;
  105. {
  106. TV_HITTESTINFO ht;
  107. GetCursorPos(&ht.pt);
  108. ScreenToClient(hwndDlg,&ht.pt);
  109. if (TreeView_HitTest(hwndTree,&ht) &&
  110. ((ht.flags & TVHT_ONITEMICON )
  111. && (ht.hItem == hItemPressed)) )
  112. return;
  113. hItemPressed=NULL;
  114. }
  115. }
  116. VOID ProcessPolicyCheckbox(HWND hDlg,HWND hwndTree,HTREEITEM hItem,BOOL fHasSel)
  117. {
  118. TV_ITEM tvi;
  119. BOOL fPrevEnabled;
  120. POLICYDLGINFO * pdi;
  121. if (!(pdi = (POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER)))
  122. return;
  123. tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
  124. tvi.hItem = hItem;
  125. if (!TreeView_GetItem(hwndTree,&tvi) || !tvi.lParam) return;
  126. fPrevEnabled = (tvi.iImage == IMG_CHECKED);
  127. tvi.iSelectedImage=tvi.iImage = AdvanceCheckboxState(tvi.iImage);
  128. SetPolicyState(hDlg,(TABLEENTRY *) tvi.lParam,tvi.iImage);
  129. tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  130. TreeView_SetItem(hwndTree,&tvi);
  131. if (fHasSel && pdi->nControls) {
  132. if (fPrevEnabled)
  133. ProcessSettingsControls(hDlg,PSC_NOVALIDATE);
  134. EnableSettingsControls( hDlg,(tvi.iImage == IMG_CHECKED) );
  135. }
  136. }
  137. BOOL ProcessExpand(HWND hDlg,HWND hwndTree,TV_ITEM * ptvi,BOOL fExpanding)
  138. {
  139. DWORD dwType;
  140. HTREEITEM hItem;
  141. POLICYDLGINFO * pdi;
  142. if (!(pdi = (POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER)) || !ptvi->lParam)
  143. return 0;
  144. dwType = ((TABLEENTRY *) ptvi->lParam)->dwType;
  145. if (dwType == ETYPE_ROOT) {
  146. // OK to expand (which happens right after root item is added),
  147. // not OK to collapse
  148. return !fExpanding;
  149. }
  150. if (dwType == ETYPE_POLICY) {
  151. return 0;
  152. }
  153. ptvi->iSelectedImage=ptvi->iImage = GetImageIndex(dwType,fExpanding,TRUE);
  154. ptvi->mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  155. TreeView_SetItem(hwndTree,ptvi);
  156. // if collapsing, set all children's images to "collapsed"
  157. if (!fExpanding && (hItem = TreeView_GetChild(hwndTree,ptvi->hItem))) {
  158. TV_ITEM tvi;
  159. do {
  160. tvi.hItem = hItem;
  161. tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  162. if (!TreeView_GetItem(hwndTree,&tvi)) return 0;
  163. ProcessExpand(hDlg,hwndTree,&tvi,fExpanding);
  164. hItem = TreeView_GetNextSibling(hwndTree,hItem);
  165. } while (hItem);
  166. }
  167. return 0; // OK to proceed
  168. }
  169. UINT AdvanceCheckboxState(UINT uImage)
  170. {
  171. switch (uImage) {
  172. case IMG_CHECKED:
  173. return IMG_UNCHECKED;
  174. break;
  175. case IMG_UNCHECKED:
  176. return (dwAppState & AS_POLICYFILE ? IMG_INDETERMINATE :
  177. IMG_CHECKED);
  178. break;
  179. case IMG_INDETERMINATE:
  180. return IMG_CHECKED;
  181. break;
  182. }
  183. return IMG_UNCHECKED;
  184. }
  185. BOOL ProcessSelection(HWND hDlg,HWND hwndTree,NM_TREEVIEW * pntv)
  186. {
  187. TABLEENTRY * pTableEntry = (TABLEENTRY *) pntv->itemNew.lParam;
  188. POLICY * pPolicy;
  189. CHAR szText[MAXSTRLEN+SMALLBUF+1];
  190. TV_ITEM tvi;
  191. POLICYDLGINFO * pdi;
  192. if (!(pdi = (POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER)) ||
  193. !pTableEntry)
  194. return FALSE;
  195. tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  196. if (tvi.hItem = pntv->itemOld.hItem) {
  197. if (TreeView_GetItem(hwndTree,&tvi) && tvi.iImage == IMG_CHECKED)
  198. if (!ProcessSettingsControls(hDlg,PSC_VALIDATENOISY)) return TRUE;
  199. }
  200. FreeSettingsControls(hDlg);
  201. tvi.hItem = pntv->itemNew.hItem;
  202. if (!TreeView_GetItem(hwndTree,&tvi)) return FALSE;
  203. if ( (pTableEntry->dwType==ETYPE_POLICY)) {
  204. pPolicy = (POLICY *) pTableEntry;
  205. if (pPolicy->pChild) {
  206. BOOL fEnabled = (tvi.iImage == IMG_CHECKED);
  207. wsprintf(szText,LoadSz(IDS_SETTINGSFOR,szSmallBuf,sizeof(szSmallBuf)),
  208. (CHAR *) (GETNAMEPTR(pPolicy)));
  209. SetDlgItemText(hDlg,IDD_TXSETTINGS,szText);
  210. CreateSettingsControls(hDlg,(SETTINGS *) pPolicy->pChild,fEnabled);
  211. EnableSettingsControls(hDlg,fEnabled);
  212. } else {
  213. SetDlgItemText(hDlg,IDD_TXSETTINGS,szNull);
  214. }
  215. } else {
  216. SetDlgItemText(hDlg,IDD_TXSETTINGS,szNull);
  217. }
  218. return FALSE;
  219. }
  220. /*******************************************************************
  221. NAME: IsAncestorOfSelection
  222. SYNOPSIS: For specified tree control, checks to see if specified
  223. item is an ancestor of the currently selected item
  224. in the tree control.
  225. NOTES: Used to figure out if a tree collapse is going to hide
  226. the selected item
  227. ********************************************************************/
  228. BOOL IsAncestorOfSelection(HWND hwndTree,HTREEITEM hParent)
  229. {
  230. HTREEITEM hItem;
  231. hItem= TreeView_GetSelection(hwndTree);
  232. while (hItem) {
  233. if (hItem == hParent) return TRUE;
  234. hItem = TreeView_GetParent(hwndTree,hItem);
  235. }
  236. return FALSE;
  237. }
  238. /*******************************************************************
  239. NAME: IsSelectedItemChecked
  240. SYNOPSIS: Returns true if selected treeview item is checked
  241. ********************************************************************/
  242. BOOL IsSelectedItemChecked(HWND hwndTree)
  243. {
  244. HTREEITEM hItem= TreeView_GetSelection(hwndTree);
  245. if (hItem) {
  246. TV_ITEM tvi;
  247. tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
  248. tvi.hItem = hItem;
  249. if (TreeView_GetItem(hwndTree,&tvi) && tvi.iImage == IMG_CHECKED)
  250. return TRUE;
  251. }
  252. return FALSE;
  253. }