Windows NT 4.0 source code leak
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.

669 lines
20 KiB

4 years ago
  1. //==========================================================================//
  2. // Includes //
  3. //==========================================================================//
  4. #include "perfmon.h" // basic defns, windows.h
  5. #include "logoptns.h" // external declarations for this file
  6. #include "dlgs.h" // common dialog control IDs
  7. #include "log.h" // for StartLog, SetLogTimer, CloseLog
  8. #include "fileutil.h" // file utilities
  9. #include "utils.h" // various utilities
  10. #include "playback.h" // for PlayingBackLog
  11. #include "pmhelpid.h" // Help IDs
  12. //==========================================================================//
  13. // Local Data //
  14. //==========================================================================//
  15. DWORD iIntervalMSecs ;
  16. BOOL bNeedToRelogData ;
  17. BOOL bNeedToStartLog ;
  18. BOOL bNeedToSetTimer ;
  19. extern BOOL LocalManualRefresh ;
  20. static BOOL bStopButtonClicked ;
  21. extern HWND hWndLogEntries ;
  22. #if WINVER >= 0x0400
  23. // the win4.0 common dialogs are organized a little differently
  24. // the hDlg passed in not the Master dialog, but only the window
  25. // with the extended controls. This buffer is to save the extended
  26. // controls in.
  27. static HDLG hWndDlg = NULL;
  28. #endif
  29. // This is a counter that is init. to 0. It is incremened by 1
  30. // when the user click the cancel button.
  31. // It is set to -1 when we sent the cancell msg internally.
  32. int bCancelled ;
  33. TCHAR szmsgFILEOK[] = FILEOKSTRING ;
  34. DWORD msgFILEOK ;
  35. //==========================================================================//
  36. // Macros //
  37. //==========================================================================//
  38. #define LogOptionsOFNStyle \
  39. (OFN_ENABLETEMPLATE | OFN_HIDEREADONLY | \
  40. OFN_ENABLEHOOK | OFN_EXPLORER)
  41. // OFN_SHOWHELP | OFN_ENABLEHOOK)
  42. //==========================================================================//
  43. // Local Functions //
  44. //==========================================================================//
  45. void EnableFileControls (HDLG hDlg, BOOL bEnable)
  46. {
  47. DialogEnable (hDlg, stc3, bEnable) ;
  48. DialogEnable (hDlg, lst1, bEnable) ;
  49. DialogEnable (hDlg, stc1, bEnable) ;
  50. DialogEnable (hDlg, lst2, bEnable) ;
  51. DialogEnable (hDlg, stc2, bEnable) ;
  52. DialogEnable (hDlg, cmb1, bEnable) ;
  53. DialogEnable (hDlg, stc4, bEnable) ;
  54. DialogEnable (hDlg, cmb2, bEnable) ;
  55. DialogEnable (hDlg, edt1, bEnable) ;
  56. }
  57. //==========================================================================//
  58. // Message Handlers //
  59. //==========================================================================//
  60. void static OnInitDialog (HDLG hDlg)
  61. {
  62. PLOG pLog ;
  63. int i ;
  64. BOOL DisplayManualRefresh ;
  65. pLog = LogData (hWndLog) ;
  66. if (msgFILEOK == 0)
  67. {
  68. msgFILEOK = RegisterWindowMessage(szmsgFILEOK);
  69. }
  70. bCancelled = 0 ;
  71. switch (pLog->iStatus)
  72. { // switch
  73. case iPMStatusClosed:
  74. // DialogEnable (hDlg, IDD_LOGOPTPAUSE, FALSE) ;
  75. break ;
  76. case iPMStatusPaused:
  77. EnableFileControls (hDlg, FALSE) ;
  78. DialogSetText (hDlg, IDD_LOGOPTSTART, IDS_STOP) ;
  79. // DialogSetText (hDlg, IDD_LOGOPTPAUSE, IDS_RESUME) ;
  80. break ;
  81. case iPMStatusCollecting:
  82. EnableFileControls (hDlg, FALSE) ;
  83. DialogSetText (hDlg, IDD_LOGOPTSTART, IDS_STOP) ;
  84. break ;
  85. } // switch
  86. for (i = 0 ;
  87. i < NumIntervals ;
  88. i++)
  89. CBAddInt (DialogControl (hDlg, IDD_LOGOPTINTERVAL), aiIntervals [i]) ;
  90. DialogSetInterval (hDlg, IDD_LOGOPTINTERVAL, pLog->iIntervalMSecs) ;
  91. iIntervalMSecs = pLog->iIntervalMSecs ;
  92. LocalManualRefresh = pLog->bManualRefresh ;
  93. DisplayManualRefresh = TRUE ;
  94. if (PlayingBackLog ())
  95. {
  96. DialogSetText (hDlg, IDD_LOGOPTSTART, IDS_CREATELOGFILE) ;
  97. DisplayManualRefresh = FALSE ;
  98. }
  99. if (LBNumItems (hWndLogEntries) == 0)
  100. {
  101. DialogEnable (hDlg, IDD_LOGOPTSTART, FALSE) ;
  102. // DialogEnable (hDlg, IDD_LOGOPTPAUSE, FALSE) ;
  103. }
  104. if (DisplayManualRefresh)
  105. {
  106. if (LocalManualRefresh)
  107. {
  108. DialogEnable (hDlg, IDD_LOGOPTINTERVAL, FALSE) ;
  109. DialogEnable (hDlg, IDD_LOGOPTINTERVALTEXT, FALSE) ;
  110. }
  111. CheckRadioButton (hDlg,
  112. IDD_LOGOPTIONSMANUALREFRESH,
  113. IDD_LOGOPTIONSPERIODIC,
  114. LocalManualRefresh ? IDD_LOGOPTIONSMANUALREFRESH :
  115. IDD_LOGOPTIONSPERIODIC) ;
  116. }
  117. else
  118. {
  119. DialogEnable (hDlg, IDD_LOGOPTIONSMANUALREFRESH, FALSE) ;
  120. CheckRadioButton (hDlg,
  121. IDD_LOGOPTIONSMANUALREFRESH,
  122. IDD_LOGOPTIONSPERIODIC,
  123. IDD_LOGOPTIONSPERIODIC) ;
  124. }
  125. dwCurrentDlgID = HC_PM_idDlgOptionLog ;
  126. WindowCenter (hDlg) ;
  127. } // OnInitDialog
  128. void OnStart (HDLG hDlg)
  129. /*
  130. Effect: Handle any actions necessary when the user clicks on
  131. the "Start/Stop" button.
  132. Note: This button could be displaying start or stop, depending
  133. on the situation.
  134. */
  135. {
  136. PLOG pLog ;
  137. pLog = LogData (hDlg) ;
  138. bStopButtonClicked = FALSE ;
  139. switch (pLog->iStatus)
  140. { // switch
  141. case iPMStatusClosed:
  142. if (PlayingBackLog ())
  143. {
  144. bNeedToRelogData = TRUE ;
  145. }
  146. else
  147. {
  148. FLOAT eTimeInterval ;
  149. eTimeInterval = DialogFloat (hDlg, IDD_LOGOPTINTERVAL, NULL) ;
  150. if (eTimeInterval > MAX_INTERVALSEC ||
  151. eTimeInterval < MIN_INTERVALSEC)
  152. {
  153. DlgErrorBox (hDlg, ERR_BADTIMEINTERVAL) ;
  154. SetFocus (DialogControl (hDlg, IDD_LOGOPTINTERVAL)) ;
  155. EditSetTextEndPos (hDlg, IDD_LOGOPTINTERVAL) ;
  156. return ;
  157. break ;
  158. }
  159. eTimeInterval = eTimeInterval * (FLOAT) 1000.0 + (FLOAT) 0.5 ;
  160. pLog->iIntervalMSecs = (DWORD) eTimeInterval ;
  161. iIntervalMSecs = pLog->iIntervalMSecs ;
  162. bNeedToStartLog = TRUE ;
  163. }
  164. break ;
  165. case iPMStatusCollecting:
  166. case iPMStatusPaused:
  167. CloseLog (hWndLog, pLog) ;
  168. bStopButtonClicked = TRUE ;
  169. break ;
  170. } // switch
  171. #if WINVER < 0x0400
  172. SimulateButtonPush (hDlg, IDD_OK) ;
  173. #else
  174. SimulateButtonPush (hWndDlg, IDOK) ;
  175. #endif
  176. }
  177. BOOL static OnOK (HDLG hDlg)
  178. /*
  179. Effect: Perform any hooked actions needed when the user selects
  180. OK in the log options dialog. In particular, if we are
  181. currently logging, record the need to relog and CANCEL
  182. the dialog, never letting the real dialog proc get the
  183. OK. Remember, this is actually a file open dialog that
  184. we have perverted. If we let the OK through, the common
  185. dialog manager will try to open it and it will inform
  186. the user that the file is locked. This way, we let the
  187. user click OK, but the dialog thinks we cancelled.
  188. Called By: LogOptionsHookProc only.
  189. Returns: Whether the message was handled by this function or not.
  190. */
  191. { // OnOK
  192. PLOG pLog ;
  193. pLog = LogData (hWndLog) ;
  194. if (pLog->iStatus == iPMStatusCollecting ||
  195. pLog->iStatus == iPMStatusPaused)
  196. {
  197. if (LocalManualRefresh != pLog->bManualRefresh)
  198. {
  199. if (!LocalManualRefresh)
  200. {
  201. FLOAT eTimeInterval ;
  202. eTimeInterval = DialogFloat (hDlg, IDD_LOGOPTINTERVAL, NULL) ;
  203. if (eTimeInterval > MAX_INTERVALSEC ||
  204. eTimeInterval < MIN_INTERVALSEC)
  205. {
  206. DlgErrorBox (hDlg, ERR_BADTIMEINTERVAL) ;
  207. SetFocus (DialogControl (hDlg, IDD_LOGOPTINTERVAL)) ;
  208. EditSetTextEndPos (hDlg, IDD_LOGOPTINTERVAL) ;
  209. return (FALSE) ;
  210. }
  211. eTimeInterval = eTimeInterval * (FLOAT) 1000.0 + (FLOAT) 0.5 ;
  212. pLog->iIntervalMSecs = (DWORD) eTimeInterval ;
  213. iIntervalMSecs = pLog->iIntervalMSecs ;
  214. UpdateLogDisplay (hWndLog) ;
  215. }
  216. ToggleLogRefresh (hWndLog) ;
  217. }
  218. else
  219. {
  220. bNeedToSetTimer = TRUE ;
  221. bCancelled = -1 ;
  222. }
  223. #if WINVER < 0x0400
  224. SimulateButtonPush (hDlg, IDD_CANCEL) ;
  225. #else
  226. SimulateButtonPush (hWndDlg, IDCANCEL) ;
  227. #endif
  228. return TRUE ;
  229. }
  230. else
  231. {
  232. if (!LocalManualRefresh)
  233. {
  234. FLOAT eTimeInterval ;
  235. eTimeInterval = DialogFloat (hDlg, IDD_LOGOPTINTERVAL, NULL) ;
  236. if (eTimeInterval > MAX_INTERVALSEC ||
  237. eTimeInterval < MIN_INTERVALSEC)
  238. {
  239. DlgErrorBox (hDlg, ERR_BADTIMEINTERVAL) ;
  240. SetFocus (DialogControl (hDlg, IDD_LOGOPTINTERVAL)) ;
  241. EditSetTextEndPos (hDlg, IDD_LOGOPTINTERVAL) ;
  242. return (TRUE) ;
  243. }
  244. }
  245. }
  246. return FALSE ;
  247. } // OnOK
  248. void OnPause (HDLG hDlg)
  249. {
  250. }
  251. BOOL APIENTRY LogOptionsHookProc (HWND hDlg,
  252. UINT iMessage,
  253. WPARAM wParam,
  254. LPARAM lParam)
  255. {
  256. BOOL bHandled ;
  257. bHandled = TRUE ;
  258. if (iMessage == msgFILEOK)
  259. {
  260. bHandled = OnOK (hDlg) ;
  261. return (bHandled) ;
  262. }
  263. switch (iMessage)
  264. {
  265. case WM_INITDIALOG:
  266. OnInitDialog (hDlg) ;
  267. break ;
  268. #if WINVER >= 0x0400
  269. case WM_NOTIFY:
  270. {
  271. LPOFNOTIFY pOfn;
  272. pOfn = (LPOFNOTIFY)lParam;
  273. switch (pOfn->hdr.code) {
  274. case CDN_INITDONE:
  275. hWndDlg = pOfn->hdr.hwndFrom;
  276. OnInitDialog (hWndDlg);
  277. break;
  278. case CDN_FILEOK:
  279. {
  280. int iFileIndex ;
  281. HWND hWndCBox;
  282. hWndCBox = GetDlgItem (pOfn->hdr.hwndFrom, cmb1); // Type combo box
  283. iFileIndex = CBSelection (hWndCBox) ;
  284. // the order of the entries in the combo box depends on
  285. // the current delimiter character
  286. if (pDelimiter == TabStr) {
  287. pDelimiter = iFileIndex == 0 ? // 0 = TSV, 1=CSV
  288. TabStr : CommasStr;
  289. } else {
  290. pDelimiter = iFileIndex == 0 ? // 0 = TSV, 1=CSV
  291. CommasStr : TabStr;
  292. }
  293. }
  294. break;
  295. default:
  296. break;
  297. }
  298. }
  299. break;
  300. case WM_HELP:
  301. {
  302. LPHELPINFO pInfo;
  303. PLOG pLog ;
  304. int iHelpId;
  305. pInfo = (LPHELPINFO)lParam;
  306. pLog = LogData (hDlg) ;
  307. if (pInfo->iContextType == HELPINFO_WINDOW) {
  308. // display perfmon help if a "perfmon" control is selected
  309. switch (pInfo->iCtrlId) {
  310. case IDD_LOGOPTSTART:
  311. case IDD_LOGOPTPAUSE:
  312. // call winhelp to display text
  313. // decide if start or stop button is pressed
  314. switch (pLog->iStatus) {
  315. case iPMStatusCollecting:
  316. case iPMStatusPaused:
  317. // then it's a stop button
  318. iHelpId = IDD_LOGOPTPAUSE;
  319. break;
  320. case iPMStatusClosed:
  321. default:
  322. // then it's a start button
  323. iHelpId = IDD_LOGOPTSTART;
  324. break;
  325. }
  326. bHandled = WinHelp (
  327. hDlg,
  328. pszHelpFile,
  329. HELP_CONTEXTPOPUP,
  330. iHelpId);
  331. break;
  332. case IDD_LOGOPTINTERVAL:
  333. case IDD_LOGOPTIONSPERIODIC:
  334. case IDD_LOGOPTIONSMANUALREFRESH:
  335. // call winhelp to display text
  336. bHandled = WinHelp (
  337. hDlg,
  338. pszHelpFile,
  339. HELP_CONTEXTPOPUP,
  340. pInfo->iCtrlId);
  341. break;
  342. default:
  343. bHandled = FALSE;
  344. break;
  345. }
  346. } else {
  347. bHandled = FALSE;
  348. }
  349. }
  350. break;
  351. #endif
  352. case WM_DESTROY:
  353. {
  354. FLOAT eTimeInterval ;
  355. if (!bCancelled)
  356. {
  357. eTimeInterval = DialogFloat (hDlg, IDD_LOGOPTINTERVAL, NULL) ;
  358. if (eTimeInterval > MAX_INTERVALSEC ||
  359. eTimeInterval < MIN_INTERVALSEC)
  360. {
  361. DlgErrorBox (hDlg, ERR_BADTIMEINTERVAL) ;
  362. }
  363. else
  364. {
  365. eTimeInterval = eTimeInterval * (FLOAT) 1000.0 + (FLOAT) 0.5 ;
  366. iIntervalMSecs = (DWORD) eTimeInterval ;
  367. }
  368. }
  369. #if WINVER >= 0x0400
  370. hWndDlg = NULL;
  371. #endif
  372. dwCurrentDlgID = 0 ;
  373. bHandled = FALSE ;
  374. }
  375. break ;
  376. case WM_COMMAND:
  377. switch (wParam)
  378. { // switch
  379. case IDD_LOGOPTSTART:
  380. OnStart (hDlg) ;
  381. break ;
  382. case IDD_LOGOPTPAUSE:
  383. OnPause (hDlg) ;
  384. break ;
  385. case IDD_OK:
  386. bHandled = OnOK (hDlg) ;
  387. break ;
  388. case IDD_CANCEL:
  389. bCancelled += 1 ;
  390. bHandled = FALSE ;
  391. break ;
  392. case IDD_LOGOPTIONSPERIODIC:
  393. if (PlayingBackLog())
  394. {
  395. break ;
  396. }
  397. // else fall thru to the following case...
  398. case IDD_LOGOPTIONSMANUALREFRESH:
  399. // check if the Manual refresh is currently checked.
  400. // Then toggle the ManualRefresh button
  401. LocalManualRefresh =
  402. (wParam == IDD_LOGOPTIONSMANUALREFRESH) ;
  403. CheckRadioButton (hDlg,
  404. IDD_LOGOPTIONSMANUALREFRESH,
  405. IDD_LOGOPTIONSPERIODIC,
  406. LocalManualRefresh ? IDD_LOGOPTIONSMANUALREFRESH :
  407. IDD_LOGOPTIONSPERIODIC) ;
  408. DialogEnable (hDlg, IDD_LOGOPTINTERVAL, !LocalManualRefresh) ;
  409. DialogEnable (hDlg, IDD_LOGOPTINTERVALTEXT, !LocalManualRefresh) ;
  410. break ;
  411. case ID_HELP:
  412. CallWinHelp (dwCurrentDlgID) ;
  413. break ;
  414. default:
  415. bHandled = FALSE ;
  416. break ;
  417. } // switch
  418. break;
  419. default:
  420. bHandled = FALSE ;
  421. break;
  422. } // switch
  423. return (bHandled) ;
  424. } // LogOptionsHookProc
  425. BOOL DisplayLogOptions (HWND hWndParent,
  426. HWND hWndLog)
  427. { // DisplayLogOptions
  428. TCHAR szFilePath [FilePathLen + 1] ;
  429. TCHAR szFileTitle [FilePathLen + 1] ;
  430. TCHAR szFileDirectory [FilePathLen + 1] ;
  431. TCHAR szCaption [WindowCaptionLen + 1] ;
  432. OPENFILENAME ofn ;
  433. PLOG pLog ;
  434. int RetCode ;
  435. int PrevLogSize ;
  436. BOOL bSameFile ;
  437. TCHAR szFilter[LongTextLen] ;
  438. int StringLength ;
  439. StringLoad (IDS_SAVELOGFILE, szFilter) ;
  440. StringLength = lstrlen (szFilter) + 1 ;
  441. LoadString (hInstance, IDS_SAVELOGFILEEXT,
  442. &szFilter[StringLength], sizeof(szFilter)-StringLength) ;
  443. StringLength += lstrlen (&szFilter[StringLength]) ;
  444. szFilter[StringLength+1] = szFilter[StringLength+2] = TEXT('\0') ;
  445. // This dialog is used to change attributes for an existing log file,
  446. // and to select the name of a log file to open. Therefore we have
  447. // different options in these cases.
  448. pLog = LogData (hWndLog) ;
  449. if (!strempty (pLog->szFilePath))
  450. {
  451. FileNameExtension (pLog->szFilePath, szFileTitle) ;
  452. FileDriveDirectory (pLog->szFilePath, szFileDirectory) ;
  453. lstrcpy (szFilePath, szFileTitle) ;
  454. }
  455. else
  456. {
  457. szFileTitle[0] = szFileDirectory[0] = TEXT('\0') ;
  458. StringLoad (IDS_SAVELOGFILEEXT, szFilePath) ;
  459. }
  460. StringLoad (IDS_LOGOPTIONS, szCaption) ;
  461. ofn.lStructSize = sizeof(OPENFILENAME) ;
  462. ofn.hwndOwner = hWndParent ;
  463. ofn.hInstance = hInstance ;
  464. ofn.lpstrFilter = szFilter;
  465. ofn.lpstrCustomFilter = (LPTSTR) NULL;
  466. ofn.nMaxCustFilter = 0L;
  467. ofn.nFilterIndex = 1L;
  468. ofn.lpstrFile = szFilePath ;
  469. ofn.nMaxFile = FilePathLen ;
  470. ofn.lpstrFileTitle = szFileTitle ;
  471. ofn.nMaxFileTitle = FilePathLen ;
  472. ofn.lpstrInitialDir = szFileDirectory ;
  473. ofn.lpstrTitle = (LPTSTR) szCaption ;
  474. ofn.Flags = LogOptionsOFNStyle ;
  475. ofn.nFileOffset = 0;
  476. ofn.nFileExtension = 0;
  477. ofn.lpstrDefExt = (LPTSTR) NULL;
  478. ofn.lpfnHook = (LPOFNHOOKPROC) LogOptionsHookProc ;
  479. ofn.lpTemplateName = idDlgLogOptions ;
  480. bNeedToRelogData = FALSE;
  481. bNeedToStartLog = FALSE ;
  482. bNeedToSetTimer = FALSE ;
  483. bStopButtonClicked = FALSE ;
  484. if (GetSaveFileName(&ofn) && !bStopButtonClicked)
  485. {
  486. pLog = LogData (hWndLog) ;
  487. // save previous log file name & size
  488. // so we can reset if error
  489. PrevLogSize = pLog->lFileSize ;
  490. lstrcpy (szFileTitle, pLog->szFilePath) ;
  491. bSameFile = pstrsamei (pLog->szFilePath, ofn.lpstrFile) ;
  492. if (!bSameFile)
  493. {
  494. lstrcpy (pLog->szFilePath, ofn.lpstrFile) ;
  495. }
  496. pLog->iIntervalMSecs = iIntervalMSecs ;
  497. if (bNeedToStartLog)
  498. {
  499. pLog->bManualRefresh = LocalManualRefresh ;
  500. StartLog (hWndLog, pLog, bSameFile) ;
  501. }
  502. else if (bNeedToRelogData)
  503. {
  504. bNeedToRelogData = FALSE ;
  505. SetHourglassCursor() ;
  506. ReLog (hWndLog, bSameFile) ;
  507. SetArrowCursor() ;
  508. }
  509. else if (LocalManualRefresh != pLog->bManualRefresh)
  510. {
  511. ToggleLogRefresh (hWndLog) ;
  512. }
  513. if (!pLog->hFile)
  514. {
  515. if (bNeedToStartLog)
  516. {
  517. // if we get here, that means StartLog has detected
  518. // problem, just restore the old stuff..
  519. pLog->lFileSize = PrevLogSize ;
  520. lstrcpy (pLog->szFilePath, szFileTitle) ;
  521. }
  522. // verify if this is a good log file and setup the file size
  523. else if ((RetCode = CreateLogFile (pLog, FALSE, bSameFile)) != 0)
  524. {
  525. DlgErrorBox (hWndLog, RetCode, pLog->szFilePath);
  526. pLog->lFileSize = PrevLogSize ;
  527. lstrcpy (pLog->szFilePath, szFileTitle) ;
  528. }
  529. else
  530. {
  531. // unfortunately, we have to close this file.
  532. // Otherwise, when we do StartLog, the common dialog
  533. // will complain that this file is already in-used.
  534. CloseHandle (pLog->hFile) ;
  535. }
  536. pLog->hFile = 0 ;
  537. }
  538. // UpdateLogDisplay (hWndLog) ;
  539. }
  540. // Remember, we faked out GetSaveFileName to return FALSE. See OnOK doc.
  541. if (bNeedToSetTimer)
  542. {
  543. SetLogTimer (hWndLog, iIntervalMSecs) ;
  544. // UpdateLogDisplay (hWndLog) ;
  545. }
  546. UpdateLogDisplay (hWndLog) ;
  547. return (TRUE) ;
  548. } // DisplayLogOptions