Leaked source code of windows server 2003
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.

416 lines
11 KiB

  1. // TestSettingsCtrl.cpp : Implementation of CTestSettingsCtrl
  2. #include "precomp.h"
  3. #include "TestSettingsCtrl.h"
  4. #include "connect.h"
  5. #include <commctrl.h>
  6. #include <cassert>
  7. std::set<CTestInfo*, CompareTests>* g_psTests;
  8. // CTestSettingsCtrl
  9. HWND
  10. CTestSettingsCtrl::CreateControlWindow(
  11. HWND hwndParent,
  12. RECT& rcPos
  13. )
  14. {
  15. CTestInfo* pTest = NULL;
  16. WCHAR wszDescription[MAX_PATH];
  17. LVCOLUMN lvc;
  18. LVITEM lvi;
  19. HWND hWndListView;
  20. UINT uCount;
  21. assert(!g_aAppInfo.empty());
  22. HWND hwnd =
  23. CComCompositeControl<CTestSettingsCtrl>::CreateControlWindow(hwndParent, rcPos);
  24. hWndListView = GetDlgItem(IDC_SETTINGS_LIST);
  25. lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  26. lvc.fmt = LVCFMT_LEFT;
  27. lvc.cx = 300;
  28. lvc.iSubItem = 0;
  29. lvc.pszText = L"xxx";
  30. ListView_InsertColumn(hWndListView, 0, &lvc);
  31. ListView_SetExtendedListViewStyleEx(hWndListView,
  32. LVS_EX_CHECKBOXES,
  33. LVS_EX_CHECKBOXES);
  34. ListView_DeleteAllItems(hWndListView);
  35. for (uCount = 0, pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); uCount++, pTest++) {
  36. if (g_bWin2KMode && !pTest->bWin2KCompatible) {
  37. continue;
  38. }
  39. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  40. lvi.pszText = (LPWSTR)pTest->strTestFriendlyName.c_str();
  41. lvi.lParam = (LPARAM)pTest;
  42. lvi.iItem = uCount;
  43. lvi.iSubItem = 0;
  44. int nItem = ListView_InsertItem(hWndListView, &lvi);
  45. std::set<CTestInfo*, CompareTests>::iterator iter;
  46. iter = g_psTests->find(pTest);
  47. BOOL bCheck = (iter != g_psTests->end()) ? TRUE : FALSE;
  48. ListView_SetCheckState(hWndListView, nItem, bCheck);
  49. }
  50. LoadString(g_hInstance,
  51. IDS_VIEW_TEST_DESC,
  52. wszDescription,
  53. ARRAYSIZE(wszDescription));
  54. //
  55. // Initially, our description tells them to select a test
  56. // to view it's description.
  57. //
  58. SetDlgItemText(IDC_TEST_DESCRIPTION, wszDescription);
  59. m_bLVCreated = TRUE;
  60. return hwnd;
  61. }
  62. //
  63. // We receive this when the dialog is being displayed.
  64. //
  65. LRESULT
  66. CTestSettingsCtrl::OnSetFocus(
  67. UINT uMsg,
  68. WPARAM wParam,
  69. LPARAM lParam,
  70. BOOL& bHandled
  71. )
  72. {
  73. HWND hWndList;
  74. hWndList = GetDlgItem(IDC_SETTINGS_LIST);
  75. ListView_SetItemState(hWndList,
  76. 0,
  77. LVIS_FOCUSED | LVIS_SELECTED,
  78. 0x000F);
  79. bHandled = TRUE;
  80. return 0;
  81. }
  82. void
  83. CTestSettingsCtrl::DisplayRunAloneError(
  84. IN LPCWSTR pwszTestName
  85. )
  86. {
  87. WCHAR wszWarning[MAX_PATH];
  88. WCHAR wszTemp[MAX_PATH];
  89. LoadString(g_hInstance,
  90. IDS_MUST_RUN_ALONE,
  91. wszTemp,
  92. ARRAYSIZE(wszTemp));
  93. StringCchPrintf(wszWarning,
  94. ARRAYSIZE(wszWarning),
  95. wszTemp,
  96. pwszTestName);
  97. MessageBox(wszWarning,
  98. 0,
  99. MB_OK | MB_ICONEXCLAMATION);
  100. }
  101. //
  102. // Ensures that we warn the user for tests that are
  103. // marked 'run alone'.
  104. //
  105. BOOL
  106. CTestSettingsCtrl::CheckForRunAlone(
  107. IN HWND hWndListView,
  108. IN CTestInfo* pTest
  109. )
  110. {
  111. int nCount, cItems, cItemsChecked;
  112. LVITEM lvi;
  113. cItems = ListView_GetItemCount(hWndListView);
  114. //
  115. // First pass, determine how tests are selected.
  116. //
  117. for (nCount = 0, cItemsChecked = 0; nCount < cItems; nCount++) {
  118. if (ListView_GetCheckState(hWndListView, nCount)) {
  119. cItemsChecked++;
  120. }
  121. }
  122. //
  123. // If there aren't any tests selected, we're fine.
  124. //
  125. if (cItemsChecked == 0) {
  126. return FALSE;
  127. }
  128. //
  129. // If this test must run alone, we're in hot water
  130. // because somebody else is already checked.
  131. //
  132. if (pTest->bRunAlone) {
  133. DisplayRunAloneError(pTest->strTestFriendlyName.c_str());
  134. return TRUE;
  135. }
  136. //
  137. // Second pass, determine if any tests that are checked
  138. // must run alone.
  139. //
  140. for (nCount = 0; nCount < cItems; nCount++) {
  141. ZeroMemory(&lvi, sizeof(LVITEM));
  142. lvi.iItem = nCount;
  143. lvi.iSubItem = 0;
  144. lvi.mask = LVIF_PARAM;
  145. ListView_GetItem(hWndListView, &lvi);
  146. CTestInfo* pTest = (CTestInfo*)lvi.lParam;
  147. if (pTest->bRunAlone) {
  148. if (ListView_GetCheckState(hWndListView, nCount)) {
  149. DisplayRunAloneError(pTest->strTestFriendlyName.c_str());
  150. return TRUE;
  151. }
  152. }
  153. }
  154. return FALSE;
  155. }
  156. BOOL
  157. CTestSettingsCtrl::CheckForConflictingTests(
  158. IN HWND hWndListView,
  159. IN LPCWSTR pwszTestName
  160. )
  161. {
  162. WCHAR wszWarning[MAX_PATH];
  163. int nCount, cItems;
  164. LVITEM lvi;
  165. //
  166. // They're attempting to enable a test that we're concerned
  167. // about. Determine if the other conflicting test is already
  168. // enabled.
  169. //
  170. cItems = ListView_GetItemCount(hWndListView);
  171. for (nCount = 0; nCount < cItems; nCount++) {
  172. ZeroMemory(&lvi, sizeof(LVITEM));
  173. lvi.iItem = nCount;
  174. lvi.iSubItem = 0;
  175. lvi.mask = LVIF_PARAM;
  176. ListView_GetItem(hWndListView, &lvi);
  177. CTestInfo* pTestInfo = (CTestInfo*)lvi.lParam;
  178. wstring strTestName = pTestInfo->strTestName;
  179. if (strTestName == pwszTestName) {
  180. if (ListView_GetCheckState(hWndListView, nCount)) {
  181. //
  182. // Display the warning.
  183. //
  184. LoadString(g_hInstance,
  185. IDS_TESTS_CONFLICT,
  186. wszWarning,
  187. ARRAYSIZE(wszWarning));
  188. MessageBox(wszWarning,
  189. 0,
  190. MB_OK | MB_ICONEXCLAMATION);
  191. return TRUE;
  192. }
  193. }
  194. }
  195. return FALSE;
  196. }
  197. BOOL
  198. CTestSettingsCtrl::IsChecked(
  199. NM_LISTVIEW* pNMListView
  200. )
  201. {
  202. return (CHECK_BIT(pNMListView->uNewState) != 0);
  203. }
  204. BOOL
  205. CTestSettingsCtrl::CheckChanged(
  206. NM_LISTVIEW* pNMListView
  207. )
  208. {
  209. if (pNMListView->uOldState == 0) {
  210. return FALSE; // adding new items...
  211. }
  212. return CHECK_CHANGED(pNMListView) ? TRUE : FALSE;
  213. }
  214. LRESULT
  215. CTestSettingsCtrl::OnNotify(
  216. UINT uMsg,
  217. WPARAM wParam,
  218. LPARAM lParam,
  219. BOOL& bHandled
  220. )
  221. {
  222. //
  223. // Ensure that this is intended for the listview control.
  224. //
  225. if (wParam != IDC_SETTINGS_LIST) {
  226. bHandled = FALSE;
  227. return FALSE;
  228. }
  229. if (!m_bLVCreated) {
  230. bHandled = FALSE;
  231. return TRUE;
  232. }
  233. bHandled = FALSE;
  234. LPNMHDR pnmh = (LPNMHDR)lParam;
  235. HWND hWndListView = GetDlgItem(IDC_SETTINGS_LIST);
  236. switch (pnmh->code) {
  237. case LVN_ITEMCHANGING:
  238. {
  239. //
  240. // We handle this message so we can prevent the user from
  241. // checking items that conflict.
  242. //
  243. LPNMLISTVIEW lpnmlv;
  244. CTestInfo* pTest = NULL;
  245. const WCHAR wszLogFileChanges[] = L"LogFileChanges";
  246. const WCHAR wszWinFileProtect[] = L"WindowsFileProtection";
  247. lpnmlv = (LPNMLISTVIEW)lParam;
  248. pTest = (CTestInfo*)lpnmlv->lParam;
  249. bHandled = TRUE;
  250. //
  251. // Only process if someone is checking an item.
  252. //
  253. if (CheckChanged(lpnmlv) && (IsChecked(lpnmlv))) {
  254. if (CheckForRunAlone(hWndListView, pTest)) {
  255. return TRUE;
  256. }
  257. //
  258. // Determine if the tests conflict.
  259. //
  260. if (pTest->strTestName == wszLogFileChanges) {
  261. if (CheckForConflictingTests(hWndListView, wszWinFileProtect)) {
  262. return TRUE;
  263. }
  264. } else if (pTest->strTestName == wszWinFileProtect) {
  265. if (CheckForConflictingTests(hWndListView, wszLogFileChanges)) {
  266. return TRUE;
  267. }
  268. }
  269. //
  270. // No problems - insert the test.
  271. //
  272. g_psTests->insert(pTest);
  273. } else if (CheckChanged(lpnmlv) && (!IsChecked(lpnmlv))) {
  274. //
  275. // Remove the test.
  276. //
  277. g_psTests->erase(pTest);
  278. }
  279. break;
  280. }
  281. case LVN_ITEMCHANGED:
  282. {
  283. LPNMLISTVIEW lpnmlv;
  284. CTestInfo* pTest = NULL;
  285. lpnmlv = (LPNMLISTVIEW)lParam;
  286. pTest = (CTestInfo*)lpnmlv->lParam;
  287. if ((lpnmlv->uChanged & LVIF_STATE) &&
  288. (lpnmlv->uNewState & LVIS_SELECTED)) {
  289. SetDlgItemText(IDC_TEST_DESCRIPTION,
  290. pTest->strTestDescription.c_str());
  291. ListView_SetItemState(hWndListView,
  292. lpnmlv->iItem,
  293. LVIS_FOCUSED | LVIS_SELECTED,
  294. 0x000F);
  295. }
  296. bHandled = TRUE;
  297. break;
  298. }
  299. }
  300. return FALSE;
  301. }
  302. LRESULT
  303. CTestSettingsCtrl::OnSize(
  304. UINT uMsg,
  305. WPARAM wParam,
  306. LPARAM lParam,
  307. BOOL& bHandled
  308. )
  309. {
  310. TEXTMETRIC tm;
  311. HDC hdc;
  312. int nWidth = LOWORD(lParam);
  313. int nHeight = HIWORD(lParam);
  314. // If below a certain size, just proceed as if that size.
  315. // This way, if the user makes the window really small, all our controls won't just
  316. // scrunch up. Better way would be to make it impossible for the user to make the window
  317. // this small, but devenv doesn't pass the WM_SIZING message to the ActiveX control.
  318. if (nWidth < 200) {
  319. nWidth = 200;
  320. }
  321. if (nHeight < 250) {
  322. nHeight = 250;
  323. }
  324. hdc = GetDC();
  325. GetTextMetrics(hdc, &tm);
  326. ReleaseDC(hdc);
  327. // Resize all child window controls
  328. ::MoveWindow(GetDlgItem(IDC_SETTINGS_LIST),
  329. tm.tmMaxCharWidth, tm.tmHeight, nWidth-2* tm.tmMaxCharWidth, nHeight - (2 * tm.tmHeight + 5 * tm.tmHeight) , FALSE);
  330. int nY = nHeight - (2 * tm.tmHeight + 5 *tm.tmHeight) + tm.tmHeight;
  331. ::MoveWindow(GetDlgItem(IDC_DESCRIPTION_STATIC),
  332. tm.tmMaxCharWidth, nY, nWidth-2*tm.tmMaxCharWidth,
  333. tm.tmHeight, FALSE);
  334. ::MoveWindow(GetDlgItem(IDC_TEST_DESCRIPTION),
  335. tm.tmMaxCharWidth, nY+tm.tmHeight, nWidth-2*tm.tmMaxCharWidth,
  336. tm.tmHeight*4, FALSE);
  337. InvalidateRect(NULL);
  338. bHandled = TRUE;
  339. return 0;
  340. }