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.

358 lines
9.5 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1994 **
  4. //*********************************************************************
  5. #include "admincfg.h"
  6. INT_PTR CALLBACK PolicyDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  7. LPARAM lParam);
  8. BOOL OnPolicyDlgCreate(HWND hDlg,LPARAM lParam);
  9. VOID ProcessMouseDown(HWND hwndParent,HWND hwndTree);
  10. VOID ProcessMouseUp(HWND hwndParent,HWND hwndTree);
  11. VOID ProcessMouseMove(HWND hwndParent,HWND hwndTree);
  12. VOID SetKeyboardHook(HWND hDlg);
  13. VOID RemoveKeyboardHook(VOID);
  14. extern VOID EnsureSettingControlVisible(HWND hDlg,HWND hwndCtrl);
  15. extern HIMAGELIST hImageListSmall;
  16. UINT CALLBACK PropSheetHeaderCallback (HWND hDlg, UINT msg, LPARAM lParam)
  17. {
  18. LPDLGTEMPLATE pDlgTemplate = (LPDLGTEMPLATE) lParam;
  19. //
  20. // Turn off context sensitive help
  21. //
  22. if (msg == PSCB_PRECREATE) {
  23. pDlgTemplate->style &= ~DS_CONTEXTHELP;
  24. }
  25. return 1;
  26. }
  27. BOOL DoPolicyDlg(HWND hwndOwner,HGLOBAL hUser)
  28. {
  29. USERHDR UserHdr;
  30. POLICYDLGINFO * pdi;
  31. PROPSHEETPAGE pagePolicies;
  32. HPROPSHEETPAGE hpagePolicies,hpage[2] = {NULL,NULL};
  33. PROPSHEETHEADER psh;
  34. BOOL fRet;
  35. HGLOBAL hUserTmp=NULL;
  36. USERDATA * pUserData=NULL,*pUserDataTmp=NULL;
  37. memset(&pagePolicies,0,sizeof(pagePolicies));
  38. memset(&psh,0,sizeof(psh));
  39. if (!GetUserHeader(hUser,&UserHdr)) {
  40. MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  41. return FALSE;
  42. }
  43. if (!(pUserData = (USERDATA *) GlobalLock(hUser)) ||
  44. !(hUserTmp = GlobalAlloc(GHND,pUserData->dwSize)) ||
  45. !(pUserDataTmp = GlobalLock(hUserTmp)) ||
  46. !(pdi = (POLICYDLGINFO *) GlobalAlloc(GPTR,sizeof(POLICYDLGINFO)))) {
  47. if (pUserData)
  48. GlobalUnlock(hUser);
  49. if (hUserTmp) {
  50. if (pUserDataTmp)
  51. GlobalUnlock(hUserTmp);
  52. GlobalFree(hUserTmp);
  53. }
  54. if (pdi) GlobalFree(pdi);
  55. MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  56. return FALSE;
  57. }
  58. // make a copy of the user buffer to operate on, so that changes can
  59. // be cancelled
  60. memcpy(pUserDataTmp,pUserData,pUserData->dwSize);
  61. GlobalUnlock(hUser);
  62. GlobalUnlock(hUserTmp);
  63. pdi->dwControlTableSize = DEF_CONTROLS * sizeof(POLICYCTRLINFO);
  64. pdi->nControls = 0;
  65. pdi->hUser = hUserTmp;
  66. pdi->pEntryRoot = (UserHdr.dwType & UT_USER ?
  67. gClassList.pUserCategoryList : gClassList.pMachineCategoryList);
  68. pdi->hwndApp = hwndOwner;
  69. if (!(pdi->pControlTable = (POLICYCTRLINFO *)
  70. GlobalAlloc(GPTR,pdi->dwControlTableSize))) {
  71. GlobalFree(hUserTmp);
  72. GlobalFree(pdi);
  73. MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  74. return FALSE;
  75. }
  76. pagePolicies.dwSize = sizeof(PROPSHEETPAGE);
  77. pagePolicies.dwFlags = PSP_DEFAULT;
  78. pagePolicies.hInstance = ghInst;
  79. pagePolicies.pfnDlgProc = PolicyDlgProc;
  80. pagePolicies.pszTemplate = MAKEINTRESOURCE(DLG_POLICIES);
  81. pagePolicies.lParam = (LPARAM) pdi;
  82. if (!(hpagePolicies = CreatePropertySheetPage(&pagePolicies))) {
  83. MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  84. fRet=FALSE;
  85. goto cleanup;
  86. }
  87. hpage[0] = hpagePolicies;
  88. psh.dwSize = sizeof(PROPSHEETHEADER);
  89. psh.dwFlags = PSH_PROPTITLE | PSH_USEICONID | PSH_NOAPPLYNOW | PSH_USECALLBACK;
  90. psh.hwndParent = hwndOwner;
  91. psh.hInstance = ghInst;
  92. psh.nPages = 1;
  93. psh.nStartPage = 0;
  94. psh.phpage = hpage;
  95. psh.pszCaption = UserHdr.szName;
  96. psh.pszIcon = MAKEINTRESOURCE(IDI_APPICON);
  97. psh.pfnCallback = PropSheetHeaderCallback;
  98. fRet=(BOOL) PropertySheet(&psh);
  99. if (fRet) {
  100. // user hit OK, copy the temporary user buffer to the real one.
  101. // may have to resize 'real' buffer.
  102. if (!CopyUser(hUserTmp,hUser)) {
  103. MsgBox(hwndOwner,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  104. fRet = FALSE;
  105. }
  106. dwAppState |= AS_FILEDIRTY;
  107. EnableMenuItems(hwndOwner,dwAppState);
  108. }
  109. cleanup:
  110. GlobalFree(pdi->pControlTable);
  111. GlobalFree(pdi);
  112. GlobalFree(hUserTmp);
  113. return fRet;
  114. }
  115. INT_PTR CALLBACK PolicyDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  116. LPARAM lParam)
  117. {
  118. switch (uMsg) {
  119. case WM_INITDIALOG:
  120. if (!OnPolicyDlgCreate(hDlg,lParam)) {
  121. return FALSE;
  122. }
  123. SetKeyboardHook(hDlg);
  124. break;
  125. case WM_NOTIFY:
  126. if ( ((NMHDR *) lParam)->hwndFrom == GetDlgItem(hDlg,IDD_TVPOLICIES)
  127. && ((POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER))->fActive) {
  128. BOOL fRet;
  129. fRet=OnTreeNotify(hDlg,( (NMHDR *)lParam)->hwndFrom,
  130. (NM_TREEVIEW *) lParam);
  131. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,(LPARAM) fRet);
  132. return fRet;
  133. }
  134. switch ( ((NMHDR * ) lParam)->code) {
  135. case PSN_APPLY:
  136. if (IsSelectedItemChecked(GetDlgItem(hDlg,IDD_TVPOLICIES)) &&
  137. !ProcessSettingsControls(hDlg,PSC_VALIDATENOISY)) {
  138. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,(LPARAM) TRUE);
  139. return TRUE;
  140. }
  141. ((POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER))->fActive=FALSE;
  142. RemoveKeyboardHook();
  143. return TRUE;
  144. break;
  145. case PSN_RESET:
  146. ((POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER))->fActive=FALSE;
  147. RemoveKeyboardHook();
  148. return TRUE;
  149. break;
  150. }
  151. break;
  152. case WM_SETCURSOR:
  153. switch (HIWORD(lParam)) {
  154. case WM_LBUTTONDOWN:
  155. ProcessMouseDown(hDlg,GetDlgItem(hDlg,IDD_TVPOLICIES));
  156. break;
  157. case WM_LBUTTONUP:
  158. ProcessMouseUp(hDlg,GetDlgItem(hDlg,IDD_TVPOLICIES));
  159. break;
  160. case WM_MOUSEMOVE:
  161. ProcessMouseMove(hDlg,GetDlgItem(hDlg,IDD_TVPOLICIES));
  162. break;
  163. }
  164. break;
  165. case WM_MOUSEMOVE:
  166. ProcessMouseMove(hDlg,GetDlgItem(hDlg,IDD_TVPOLICIES));
  167. break;
  168. default:
  169. return FALSE;
  170. }
  171. return TRUE;
  172. }
  173. BOOL OnPolicyDlgCreate(HWND hDlg,LPARAM lParam)
  174. {
  175. POLICYDLGINFO * pdi;
  176. HWND hwndPolicy = GetDlgItem(hDlg,IDD_TVPOLICIES);
  177. CHAR szTitle[255];
  178. USERHDR UserHdr;
  179. WINDOWPLACEMENT wp;
  180. if (!(pdi = (POLICYDLGINFO *) (( (PROPSHEETPAGE *) lParam)->lParam) ))
  181. return FALSE;
  182. if (!GetUserHeader(pdi->hUser,&UserHdr)) return FALSE;
  183. // Set the title of the dialog to "Policies for <user>"
  184. wsprintf(szTitle,LoadSz(IDS_POLICIESFOR,szSmallBuf,sizeof(szSmallBuf)),
  185. UserHdr.szName);
  186. SetWindowText(hDlg,szTitle);
  187. wp.length = sizeof(wp);
  188. GetWindowPlacement(pdi->hwndApp,&wp);
  189. SetWindowPos(hDlg,NULL,wp.rcNormalPosition.left+30,
  190. wp.rcNormalPosition.top+40,0,0,SWP_NOSIZE | SWP_NOZORDER);
  191. // lParam is pointer to POLICYDLGINFO struct with information for this
  192. // instance of the dialog, store the pointer in the window data
  193. pdi->fActive=TRUE;
  194. SetWindowLongPtr(hDlg,DWLP_USER,(LPARAM) pdi);
  195. // now that we've stored pointer to POLICYDLGINFO struct in our extra
  196. // window data, send WM_USER to clip window to tell it to create a
  197. // child container window (and store the handle in our POLICYDLGINFO)
  198. SendDlgItemMessage(hDlg,IDD_TVSETTINGS,WM_USER,0,0L);
  199. SetWindowLong(hwndPolicy,GWL_EXSTYLE,WS_EX_CLIENTEDGE);
  200. SetWindowLong(GetDlgItem(hDlg,IDD_TVSETTINGS),GWL_EXSTYLE,WS_EX_CLIENTEDGE);
  201. SetScrollRange(GetDlgItem(hDlg,IDD_TVSETTINGS),SB_VERT,0,100,TRUE);
  202. SetScrollRange(GetDlgItem(hDlg,IDD_TVSETTINGS),SB_VERT,0,0,TRUE);
  203. SetScrollRange(hwndPolicy,SB_VERT,0,100,TRUE);
  204. SetScrollRange(hwndPolicy,SB_VERT,0,0,TRUE);
  205. TreeView_SetImageList(hwndPolicy,hImageListSmall,TVSIL_NORMAL);
  206. if (!RefreshTreeView(pdi,hwndPolicy,pdi->pEntryRoot,pdi->hUser)) {
  207. MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  208. return FALSE;
  209. }
  210. return TRUE;
  211. }
  212. BOOL SetPolicyState(HWND hDlg,TABLEENTRY * pTableEntry,UINT uState)
  213. {
  214. POLICY * pPolicy = (POLICY *) pTableEntry;
  215. USERDATA * pUserData;
  216. POLICYDLGINFO * pdi;
  217. if (!pPolicy) return FALSE;
  218. if (!(pdi = (POLICYDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER)))
  219. return FALSE;
  220. if (!(pUserData = (USERDATA *) GlobalLock(pdi->hUser))) {
  221. return FALSE;
  222. }
  223. pUserData->SettingData[pPolicy->uDataIndex].uData = uState;
  224. GlobalUnlock(pdi->hUser);
  225. return TRUE;
  226. }
  227. HHOOK hKbdHook = NULL;
  228. HWND hDlgActive = NULL;
  229. LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam,LPARAM lParam)
  230. {
  231. if (wParam == VK_TAB && !(lParam & 0x80000000)) { // tab key depressed
  232. BOOL fShift = (GetKeyState(VK_SHIFT) & 0x80000000);
  233. HWND hwndFocus = GetFocus();
  234. POLICYDLGINFO * pdi;
  235. int iIndex;
  236. int iDelta;
  237. if (!(pdi = (POLICYDLGINFO *) GetWindowLongPtr(hDlgActive, DWLP_USER)))
  238. return 0;
  239. // see if the focus control is one of the setting controls
  240. for (iIndex=0;iIndex<(int)pdi->nControls;iIndex++)
  241. if (pdi->pControlTable[iIndex].hwnd == hwndFocus)
  242. break;
  243. if (iIndex == (int) pdi->nControls)
  244. return 0; // no, we don't care
  245. iDelta = (fShift ? -1 : 1);
  246. // from the current setting control, scan forwards or backwards
  247. // (depending if on shift state, this can be TAB or shift-TAB)
  248. // to find the next control to give focus to
  249. for (iIndex += iDelta;iIndex>=0 && iIndex<(int) pdi->nControls;
  250. iIndex += iDelta) {
  251. if (pdi->pControlTable[iIndex].uDataIndex !=
  252. NO_DATA_INDEX &&
  253. IsWindowEnabled(pdi->pControlTable[iIndex].hwnd)) {
  254. // found it, set the focus on that control and return 1
  255. // to eat the keystroke
  256. SetFocus(pdi->pControlTable[iIndex].hwnd);
  257. EnsureSettingControlVisible(hDlgActive,
  258. pdi->pControlTable[iIndex].hwnd);
  259. return 1;
  260. }
  261. }
  262. // at first or last control in settings table, let dlg code
  263. // handle it and give focus to next (or previous) control in dialog
  264. }
  265. return 0;
  266. }
  267. VOID SetKeyboardHook(HWND hDlg)
  268. {
  269. // hook the keyboard to trap TABs. If this fails for some reason,
  270. // fail silently and go on, not critical that tabs work correctly
  271. // (unless you have no mouse :) )
  272. if (hKbdHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardHookProc,
  273. ghInst,GetCurrentThreadId())) {
  274. hDlgActive = hDlg;
  275. }
  276. }
  277. VOID RemoveKeyboardHook(VOID)
  278. {
  279. if (hKbdHook) {
  280. UnhookWindowsHookEx(hKbdHook);
  281. hKbdHook = NULL;
  282. hDlgActive = NULL;
  283. }
  284. }