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.

591 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999
  5. //
  6. // File: tracedlg.cpp
  7. //
  8. // Contents: Implementation of the debug trace code
  9. //
  10. // History: 15-Jul-99 VivekJ Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include "stdafx.h"
  14. #include "resource.h"
  15. #include "tracedlg.h"
  16. #ifdef DBG
  17. //############################################################################
  18. //############################################################################
  19. //
  20. // Implementation of class CTraceDialog
  21. //
  22. //############################################################################
  23. //############################################################################
  24. /*+-------------------------------------------------------------------------*
  25. *
  26. * CTraceDialog::RecalcCheckboxes
  27. *
  28. * PURPOSE: Recomputes the settings of the check boxes. This is in response to
  29. * a trace tag selection change.
  30. *
  31. * RETURNS:
  32. * void
  33. *
  34. *+-------------------------------------------------------------------------*/
  35. void
  36. CTraceDialog::RecalcCheckboxes()
  37. {
  38. DWORD dwMask = TRACE_ALL; //initialize with all ones
  39. bool bAtLeastOneItem = false;
  40. int iItem = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);
  41. while(iItem != -1)
  42. {
  43. CTraceTag *pTag = reinterpret_cast<CTraceTag *>(m_listCtrl.GetItemData(iItem));
  44. ASSERT(pTag != NULL);
  45. if(pTag == NULL)
  46. return;
  47. bAtLeastOneItem = true;
  48. dwMask &= pTag->GetFlag(TRACE_ALL); // AND all the selected item's bits.
  49. iItem = m_listCtrl.GetNextItem(iItem, LVNI_SELECTED);
  50. }
  51. // disable the checkbox if no item selected.
  52. ::EnableWindow(GetDlgItem(IDC_TRACE_TO_COM2), bAtLeastOneItem);
  53. ::EnableWindow(GetDlgItem(IDC_TRACE_OUTPUTDEBUGSTRING),bAtLeastOneItem);
  54. ::EnableWindow(GetDlgItem(IDC_TRACE_TO_FILE), bAtLeastOneItem);
  55. ::EnableWindow(GetDlgItem(IDC_TRACE_DEBUG_BREAK), bAtLeastOneItem);
  56. ::EnableWindow(GetDlgItem(IDC_TRACE_DUMP_STACK), bAtLeastOneItem);
  57. if(!bAtLeastOneItem)
  58. return;
  59. CheckDlgButton(IDC_TRACE_TO_COM2, dwMask & TRACE_COM2 ? BST_CHECKED : BST_UNCHECKED);
  60. CheckDlgButton(IDC_TRACE_OUTPUTDEBUGSTRING, dwMask & TRACE_OUTPUTDEBUGSTRING ? BST_CHECKED : BST_UNCHECKED);
  61. CheckDlgButton(IDC_TRACE_TO_FILE, dwMask & TRACE_FILE ? BST_CHECKED : BST_UNCHECKED);
  62. CheckDlgButton(IDC_TRACE_DEBUG_BREAK, dwMask & TRACE_DEBUG_BREAK ? BST_CHECKED : BST_UNCHECKED);
  63. CheckDlgButton(IDC_TRACE_DUMP_STACK, dwMask & TRACE_DUMP_STACK ? BST_CHECKED : BST_UNCHECKED);
  64. }
  65. /*+-------------------------------------------------------------------------*
  66. *
  67. * CTraceDialog::OnSelChanged
  68. *
  69. * PURPOSE: Handles a selection change notification.
  70. *
  71. * PARAMETERS:
  72. * int idCtrl :
  73. * LPNMHDR pnmh :
  74. * BOOL& bHandled :
  75. *
  76. * RETURNS:
  77. * LRESULT
  78. *
  79. *+-------------------------------------------------------------------------*/
  80. LRESULT
  81. CTraceDialog::OnSelChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
  82. {
  83. RecalcCheckboxes();
  84. return 0;
  85. }
  86. /*+-------------------------------------------------------------------------*
  87. *
  88. * CTraceDialog::OnColumnClick
  89. *
  90. * PURPOSE: Handles the column click notification - causes a sort by the
  91. * specified column.
  92. *
  93. * PARAMETERS:
  94. * int idCtrl :
  95. * LPNMHDR pnmh :
  96. * BOOL& bHandled :
  97. *
  98. * RETURNS:
  99. * LRESULT
  100. *
  101. *+-------------------------------------------------------------------------*/
  102. LRESULT
  103. CTraceDialog::OnColumnClick(int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
  104. {
  105. NM_LISTVIEW *pnmlv = (NM_LISTVIEW *) pnmh;
  106. m_dwSortData = pnmlv->iSubItem; // iSubItem is the column clicked on. Cache this value for later
  107. DoSort();
  108. return 0;
  109. }
  110. /*+-------------------------------------------------------------------------*
  111. *
  112. * CTraceDialog::SetMaskFromCheckbox
  113. *
  114. * PURPOSE: Sets the trace tag flag from the state of the specified check box.
  115. *
  116. * PARAMETERS:
  117. * UINT idControl : The check box control
  118. * DWORD dwMask : The bit(s) to enable/disable depending on the state
  119. * of the control.
  120. *
  121. * RETURNS:
  122. * void
  123. *
  124. *+-------------------------------------------------------------------------*/
  125. void
  126. CTraceDialog::SetMaskFromCheckbox(UINT idControl, DWORD dwMask)
  127. {
  128. bool bEnabled = IsDlgButtonChecked(idControl) == BST_CHECKED;
  129. int iItem = m_listCtrl.GetNextItem(-1, LVNI_SELECTED);
  130. ASSERT(iItem != -1);
  131. while(iItem != -1)
  132. {
  133. CTraceTag *pTag = reinterpret_cast<CTraceTag *>(m_listCtrl.GetItemData(iItem));
  134. ASSERT(pTag != NULL);
  135. if(pTag == NULL)
  136. return;
  137. if(bEnabled)
  138. pTag->SetFlag(dwMask);
  139. else
  140. pTag->ClearFlag(dwMask);
  141. // update the UI
  142. m_listCtrl.SetItemText(iItem, COLUMN_ENABLED, pTag->FAnyTemp() ? TEXT("X") : TEXT(""));
  143. iItem = m_listCtrl.GetNextItem(iItem, LVNI_SELECTED);
  144. }
  145. // sort the items again
  146. DoSort();
  147. }
  148. /*+-------------------------------------------------------------------------*
  149. *
  150. * CTraceDialog::DoSort
  151. *
  152. * PURPOSE: Perform a sort of the items in the dialog
  153. *
  154. * RETURNS:
  155. * void
  156. *
  157. *+-------------------------------------------------------------------------*/
  158. void
  159. CTraceDialog::DoSort()
  160. {
  161. m_listCtrl.SortItems(CompareItems, m_dwSortData);
  162. }
  163. /*+-------------------------------------------------------------------------*
  164. *
  165. * CTraceDialog::OnOutputToCOM2
  166. *
  167. * PURPOSE: Handles checking/unchecking the "output to Com2" button.
  168. *
  169. * PARAMETERS:
  170. * WORD wNotifyCode :
  171. * WORD wID :
  172. * HWND hWndCtl :
  173. * BOOL& bHandled :
  174. *
  175. * RETURNS:
  176. * LRESULT
  177. *
  178. *+-------------------------------------------------------------------------*/
  179. LRESULT
  180. CTraceDialog::OnOutputToCOM2(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  181. {
  182. SetMaskFromCheckbox(IDC_TRACE_TO_COM2, TRACE_COM2);
  183. return 0;
  184. }
  185. /*+-------------------------------------------------------------------------*
  186. *
  187. * CTraceDialog::OnOutputDebugString
  188. *
  189. * PURPOSE: Handles checking/unchecking the "OutputDebugString" button.
  190. *
  191. * PARAMETERS:
  192. * WORD wNotifyCode :
  193. * WORD wID :
  194. * HWND hWndCtl :
  195. * BOOL& bHandled :
  196. *
  197. * RETURNS:
  198. * LRESULT
  199. *
  200. *+-------------------------------------------------------------------------*/
  201. LRESULT
  202. CTraceDialog::OnOutputDebugString(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  203. {
  204. SetMaskFromCheckbox(IDC_TRACE_OUTPUTDEBUGSTRING, TRACE_OUTPUTDEBUGSTRING);
  205. return 0;
  206. }
  207. /*+-------------------------------------------------------------------------*
  208. *
  209. * CTraceDialog::OnOutputToFile
  210. *
  211. * PURPOSE: Handles checking/unchecking the "output to File" button.
  212. *
  213. * PARAMETERS:
  214. * WORD wNotifyCode :
  215. * WORD wID :
  216. * HWND hWndCtl :
  217. * BOOL& bHandled :
  218. *
  219. * RETURNS:
  220. * LRESULT
  221. *
  222. *+-------------------------------------------------------------------------*/
  223. LRESULT
  224. CTraceDialog::OnOutputToFile(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  225. {
  226. SetMaskFromCheckbox(IDC_TRACE_TO_FILE, TRACE_FILE);
  227. return 0;
  228. }
  229. /*+-------------------------------------------------------------------------*
  230. *
  231. * CTraceDialog::OnDebugBreak
  232. *
  233. * PURPOSE: Handles checking/unchecking the "DebugBreak" button.
  234. *
  235. * PARAMETERS:
  236. * WORD wNotifyCode :
  237. * WORD wID :
  238. * HWND hWndCtl :
  239. * BOOL& bHandled :
  240. *
  241. * RETURNS:
  242. * LRESULT
  243. *
  244. *+-------------------------------------------------------------------------*/
  245. LRESULT
  246. CTraceDialog::OnDebugBreak(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  247. {
  248. SetMaskFromCheckbox(IDC_TRACE_DEBUG_BREAK, TRACE_DEBUG_BREAK);
  249. return 0;
  250. }
  251. /*+-------------------------------------------------------------------------*
  252. *
  253. * CTraceDialog::OnDumpStack
  254. *
  255. * PURPOSE: Handles checking/unchecking the "Stack Dump" button.
  256. *
  257. * PARAMETERS:
  258. * WORD wNotifyCode :
  259. * WORD wID :
  260. * HWND hWndCtl :
  261. * BOOL& bHandled :
  262. *
  263. * RETURNS:
  264. * LRESULT
  265. *
  266. *+-------------------------------------------------------------------------*/
  267. LRESULT
  268. CTraceDialog::OnDumpStack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  269. {
  270. SetMaskFromCheckbox(IDC_TRACE_DUMP_STACK, TRACE_DUMP_STACK);
  271. return 0;
  272. }
  273. /*+-------------------------------------------------------------------------*
  274. *
  275. * CTraceDialog::OnRestoreDefaults
  276. *
  277. * PURPOSE: Restores the default (canned) settings of all trace tags.
  278. *
  279. * PARAMETERS:
  280. * WORD wNotifyCode :
  281. * WORD wID :
  282. * HWND hWndCtl :
  283. * BOOL& bHandled :
  284. *
  285. * RETURNS:
  286. * LRESULT
  287. *
  288. *+-------------------------------------------------------------------------*/
  289. LRESULT
  290. CTraceDialog::OnRestoreDefaults(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  291. {
  292. CTraceTags::iterator iter;
  293. CTraceTags * pTraceTags = GetTraceTags();
  294. if(NULL == pTraceTags)
  295. goto Error;
  296. for(iter = pTraceTags->begin(); iter != pTraceTags->end(); iter++)
  297. {
  298. (*iter)->RestoreDefaults();
  299. }
  300. RecalcCheckboxes();
  301. Cleanup:
  302. return 0;
  303. Error:
  304. goto Cleanup;
  305. }
  306. /*+-------------------------------------------------------------------------*
  307. *
  308. * CTraceDialog::OnSelectAll
  309. *
  310. * PURPOSE: Selects all trace tags.
  311. *
  312. * PARAMETERS:
  313. * WORD wNotifyCode :
  314. * WORD wID :
  315. * HWND hWndCtl :
  316. * BOOL& bHandled :
  317. *
  318. * RETURNS:
  319. * LRESULT
  320. *
  321. *+-------------------------------------------------------------------------*/
  322. LRESULT
  323. CTraceDialog::OnSelectAll(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  324. {
  325. int cItems = m_listCtrl.GetItemCount();
  326. for(int i=0; i< cItems; i++)
  327. {
  328. m_listCtrl.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
  329. }
  330. RecalcCheckboxes();
  331. return 0;
  332. }
  333. /*+-------------------------------------------------------------------------*
  334. *
  335. * CTraceDialog::CompareItems
  336. *
  337. * PURPOSE: The callback routine to compare two items in the list control.
  338. *
  339. * PARAMETERS:
  340. * LPARAM lp1 :
  341. * LPARAM lp2 :
  342. * LPARAM lpSortData :
  343. *
  344. * RETURNS:
  345. * int CALLBACK
  346. *
  347. *+-------------------------------------------------------------------------*/
  348. int CALLBACK
  349. CTraceDialog::CompareItems(LPARAM lp1, LPARAM lp2, LPARAM lpSortData)
  350. {
  351. CTraceTag *pTag1 = reinterpret_cast<CTraceTag *>(lp1);
  352. CTraceTag *pTag2 = reinterpret_cast<CTraceTag *>(lp2);
  353. if(!pTag1 && !pTag2)
  354. {
  355. ASSERT(0 && "Should not come here.");
  356. return 0;
  357. }
  358. switch(lpSortData)
  359. {
  360. default:
  361. ASSERT(0 && "Should not come here.");
  362. return 0;
  363. case COLUMN_CATEGORY:
  364. return _tcscmp(pTag1->GetCategory(), pTag2->GetCategory());
  365. break;
  366. case COLUMN_NAME:
  367. return _tcscmp(pTag1->GetName(), pTag2->GetName());
  368. break;
  369. case COLUMN_ENABLED:
  370. {
  371. BOOL b1 = (pTag1->FAnyTemp()) ? 0 : 1;
  372. BOOL b2 = (pTag2->FAnyTemp()) ? 0 : 1;
  373. return b1 - b2;
  374. }
  375. break;
  376. }
  377. }
  378. /*+-------------------------------------------------------------------------*
  379. *
  380. * CTraceDialog::OnInitDialog
  381. *
  382. * PURPOSE: Initializes the dialog - adds columns, sets the file name
  383. * and inserts all rows.
  384. *
  385. * PARAMETERS:
  386. * UINT uMsg :
  387. * WPARAM wParam :
  388. * LPARAM lParam :
  389. * BOOL& bHandled :
  390. *
  391. * RETURNS:
  392. * LRESULT
  393. *
  394. *+-------------------------------------------------------------------------*/
  395. LRESULT
  396. CTraceDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  397. {
  398. m_listCtrl.Attach(GetDlgItem(IDC_TRACE_LIST));
  399. m_editStackLevels.Attach(GetDlgItem(IDC_TRACE_STACKLEVELS));
  400. m_editStackLevels.LimitText(1); // one character only.
  401. // insert the columns - no need to localize since debug only.
  402. m_listCtrl.InsertColumn(COLUMN_CATEGORY, TEXT("Category") ,LVCFMT_LEFT, 150, 0);
  403. m_listCtrl.InsertColumn(COLUMN_NAME, TEXT("Name" ) ,LVCFMT_LEFT, 150, 0);
  404. m_listCtrl.InsertColumn(COLUMN_ENABLED, TEXT("Enabled" ) ,LVCFMT_LEFT, 80, 0);
  405. // set the full row select style.
  406. m_listCtrl.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
  407. m_listCtrl.SortItems(CompareItems, COLUMN_CATEGORY); // the default sort.
  408. // Set the file name.
  409. SetDlgItemText(IDC_TRACE_FILENAME, CTraceTag::GetFilename());
  410. //Set the stack level
  411. SetDlgItemInt(IDC_TRACE_STACKLEVELS, CTraceTag::GetStackLevels());
  412. CTraceTags * pTraceTags = GetTraceTags();
  413. if(NULL == pTraceTags)
  414. return 0;
  415. int i = 0;
  416. for(CTraceTags::iterator iter = pTraceTags->begin(); iter != pTraceTags->end(); iter++, i++)
  417. {
  418. int iItem = m_listCtrl.InsertItem(LVIF_PARAM | LVIF_TEXT,
  419. i, (*iter)->GetCategory(), 0, 0, 0, (LPARAM) (*iter));
  420. m_listCtrl.SetItemText(iItem, COLUMN_NAME, (*iter)->GetName());
  421. m_listCtrl.SetItemText(iItem, COLUMN_ENABLED, (*iter)->FAny() ? TEXT("X") : TEXT(""));
  422. // set up the tag for a temporary change.
  423. (*iter)->SetTempState();
  424. }
  425. RecalcCheckboxes();
  426. return 0;
  427. }
  428. /*+-------------------------------------------------------------------------*
  429. *
  430. * CTraceDialog::OnCancel
  431. *
  432. * PURPOSE: Handles the Cancel button. Exits without committing changes.
  433. *
  434. * PARAMETERS:
  435. * WORD wNotifyCode :
  436. * WORD wID :
  437. * HWND hWndCtl :
  438. * BOOL& bHandled :
  439. *
  440. * RETURNS:
  441. * LRESULT
  442. *
  443. *+-------------------------------------------------------------------------*/
  444. LRESULT
  445. CTraceDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  446. {
  447. m_listCtrl.Detach();
  448. EndDialog (false);
  449. return 0;
  450. }
  451. /*+-------------------------------------------------------------------------*
  452. *
  453. * CTraceDialog::OnOK
  454. *
  455. * PURPOSE: Exits and commits changes.
  456. *
  457. * PARAMETERS:
  458. * WORD wNotifyCode :
  459. * WORD wID :
  460. * HWND hWndCtl :
  461. * BOOL& bHandled :
  462. *
  463. * RETURNS:
  464. * LRESULT
  465. *
  466. *+-------------------------------------------------------------------------*/
  467. LRESULT
  468. CTraceDialog::OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  469. {
  470. // Set the file name from the edit control
  471. TCHAR szFilename[OFS_MAXPATHNAME];
  472. GetDlgItemText(IDC_TRACE_FILENAME, (LPTSTR)szFilename, OFS_MAXPATHNAME);
  473. CTraceTag::GetFilename() = szFilename;
  474. // Set the stack levels
  475. TCHAR szStackLevels[2];
  476. GetDlgItemText(IDC_TRACE_STACKLEVELS, (LPTSTR)szStackLevels, 2);
  477. int nLevels = szStackLevels[0] - TEXT('0'); // convert to integer.
  478. CTraceTag::GetStackLevels() = nLevels;
  479. CTraceTags::iterator iter;
  480. CTraceTags * pTraceTags = GetTraceTags();
  481. if(NULL == pTraceTags)
  482. goto Error;
  483. // save all the trace tags out to the .ini file
  484. for(iter = pTraceTags->begin(); iter != pTraceTags->end(); iter++)
  485. {
  486. CStr str;
  487. CTraceTag *pTag = *iter;
  488. if(!pTag)
  489. goto Error;
  490. pTag->Commit();
  491. // write out the trace tag ONLY if the setting is not the same as the default. Avoids clutter.
  492. str.Format(TEXT("%d"), pTag->GetAll());
  493. ::WritePrivateProfileString(pTag->GetCategory(), pTag->GetName(), (LPCTSTR)str, szTraceIniFile);
  494. }
  495. m_listCtrl.Detach();
  496. // write out the values into the ini file.
  497. ::WritePrivateProfileString(TEXT("Trace File"), TEXT("Trace File"), (LPCTSTR)szFilename, szTraceIniFile);
  498. ::WritePrivateProfileString(TEXT("Stack Levels"), TEXT("Stack Levels"), (LPCTSTR)szStackLevels, szTraceIniFile);
  499. Cleanup:
  500. EndDialog (true);
  501. return 1;
  502. Error:
  503. goto Cleanup;
  504. }
  505. /*+-------------------------------------------------------------------------*
  506. *
  507. * DoDebugTraceDialog
  508. *
  509. * PURPOSE: Exported routine (DEBUG build only) to bring up the trace dialog.
  510. *
  511. * RETURNS:
  512. * MMCBASE_API void
  513. *
  514. *+-------------------------------------------------------------------------*/
  515. MMCBASE_API void DoDebugTraceDialog()
  516. {
  517. CTraceDialog dlg;
  518. dlg.DoModal();
  519. }
  520. #endif // DBG