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.

772 lines
23 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999
  5. //
  6. // File: StatusDialog.cxx
  7. //
  8. // Contents: Implementation of the StatusDialog class
  9. //
  10. // Written by Joe Porkka
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "headers.hxx"
  14. #include "StatusDialog.h"
  15. #include "RegSettingsIO.h"
  16. #include <stdio.h>
  17. #include <time.h>
  18. #define REFRESH_DELAY 500
  19. #define MAX_DBMSG_LENGTH 256
  20. #define MAX_SCRIPT_NAME_LENGTH 512
  21. DeclareTag(tagStat, "Stat", "status events");
  22. CCustomListBox::CCustomListBox()
  23. {
  24. _hwnd = 0;
  25. }
  26. CCustomListBox::~CCustomListBox()
  27. {
  28. _hwnd = 0;
  29. ResetContent();
  30. }
  31. void CCustomListBox::Init(HWND dlg, UINT idCtrl)
  32. {
  33. _nExtent = 0;
  34. _hwnd = GetDlgItem(dlg, idCtrl);
  35. SetWindowLong(_hwnd, GWL_USERDATA, (LONG) this);
  36. SendMessage(LB_SETCOUNT, _Messages.Size(), 0);
  37. }
  38. const TCHAR *CCustomListBox::GetString(int index)
  39. {
  40. if (index >= 0 && index < _Messages.Size())
  41. {
  42. return _Messages[index];
  43. }
  44. return 0;
  45. }
  46. void CCustomListBox::ResetContent()
  47. {
  48. SetEnd(0);
  49. }
  50. void CCustomListBox::SetEnd(int nItems)
  51. {
  52. if (nItems < _Messages.Size())
  53. {
  54. for(int i = nItems; i < _Messages.Size(); ++i)
  55. {
  56. delete [] _Messages[i];
  57. _Messages[i] = 0;
  58. }
  59. _Messages.SetSize(nItems);
  60. }
  61. if (_hwnd)
  62. {
  63. int cTopIndex = SendMessage(LB_GETTOPINDEX, 0, 0);
  64. int nSelCount = SendMessage(LB_GETSELCOUNT, 0, 0);
  65. if (nItems != SendMessage(LB_GETCOUNT, 0, 0) )
  66. {
  67. SendMessage(WM_SETREDRAW, FALSE, 0);
  68. long *pSelItems = 0;
  69. if (nSelCount > 0)
  70. {
  71. pSelItems = new long[nSelCount];
  72. if (pSelItems)
  73. SendMessage(LB_GETSELITEMS, nSelCount, (LPARAM) pSelItems);
  74. MemSetName(pSelItems, "StatusDialog selcount: %d", nSelCount);
  75. }
  76. SendMessage(LB_SETCOUNT, _Messages.Size(), 0);
  77. if (nSelCount != 0)
  78. {
  79. // If there is a selection (or LB_ERR in the single select listbox case), maintain current scroll position
  80. SendMessage(LB_SETTOPINDEX, cTopIndex, 0);
  81. }
  82. else if (nItems > 0)
  83. SendMessage(LB_SETTOPINDEX, nItems - 1, 0);
  84. if (pSelItems)
  85. {
  86. for(int i = 0; i < nSelCount; ++i)
  87. {
  88. SendMessage( LB_SELITEMRANGE,
  89. TRUE,
  90. MAKELONG(pSelItems[i], pSelItems[i]));
  91. }
  92. delete [] pSelItems;
  93. }
  94. SendMessage( WM_SETREDRAW, TRUE, 0);
  95. }
  96. }
  97. }
  98. void CCustomListBox::AppendString(const TCHAR *sz)
  99. {
  100. SetString(_Messages.Size(), sz);
  101. SetEnd(_Messages.Size());
  102. }
  103. void CCustomListBox::SetString(int nItem, const TCHAR *sz)
  104. {
  105. if (nItem >= _Messages.Size())
  106. { // CImplAry oughta do this for us!
  107. if (nItem >= _nAllocatedMessageLength)
  108. { // Grow allocation by power of 2
  109. int newsize = _Messages.Size() * 2;
  110. if (newsize == 0)
  111. newsize = 1;
  112. while (newsize < nItem + 1)
  113. newsize *= 2;
  114. if (_Messages.EnsureSize(newsize) == S_OK)
  115. {
  116. _nAllocatedMessageLength = newsize;
  117. for(int i = _Messages.Size(); i < newsize; ++i)
  118. _Messages[i] = NULL;
  119. _Messages.SetSize(nItem + 1);
  120. }
  121. }
  122. else
  123. {
  124. _Messages.SetSize(nItem + 1);
  125. _Messages[nItem] = NULL;
  126. }
  127. }
  128. if (nItem < _Messages.Size())
  129. {
  130. delete [] _Messages[nItem];
  131. int len = _tcslen(sz);
  132. _Messages[nItem] = new TCHAR[len + 1];
  133. if (_Messages[nItem])
  134. {
  135. MemSetName(_Messages[nItem], "StatusDialog line #%d", nItem);
  136. _tcscpy(_Messages[nItem], sz);
  137. }
  138. }
  139. // Limit the maximum number of messages so we don't eat up memory. We
  140. // let it grow to 10 messages over our limit, then we delete down to 10
  141. // under.
  142. if (_Messages.Size() > MAX_STATUS_MESSAGES + 10)
  143. {
  144. int cPurge = _Messages.Size() - (MAX_STATUS_MESSAGES - 10);
  145. int i;
  146. for (i = 0; i < cPurge; i++)
  147. {
  148. delete [] _Messages[i];
  149. }
  150. // if cPurge is 1, then we will delete only the first element. Using
  151. // DeleteMultiple is dramatically more efficient than deleting
  152. // one element at a time.
  153. _Messages.DeleteMultiple(0, cPurge - 1);
  154. Refresh();
  155. }
  156. }
  157. void CCustomListBox::MeasureItem(MEASUREITEMSTRUCT *pmis)
  158. {
  159. if (_hwnd)
  160. {
  161. HDC hdc = GetDC(_hwnd);
  162. TEXTMETRIC tm;
  163. GetTextMetrics(hdc, &tm);
  164. ReleaseDC(_hwnd, hdc);
  165. pmis->itemHeight = tm.tmHeight;
  166. }
  167. else
  168. pmis->itemHeight = 20;
  169. }
  170. void CCustomListBox::DrawItem(DRAWITEMSTRUCT *pdis)
  171. {
  172. TCHAR *szText = 0;
  173. if (pdis->itemID < unsigned(_Messages.Size()))
  174. szText = _Messages[pdis->itemID];
  175. if (!szText)
  176. szText = L"";
  177. switch (pdis->itemAction)
  178. {
  179. case ODA_SELECT:
  180. case ODA_DRAWENTIRE:
  181. // Display the text associated with the item.
  182. {
  183. COLORREF savetext = 0;
  184. COLORREF savebk = 0;
  185. if (pdis->itemState & ODS_SELECTED)
  186. {
  187. savetext = SetTextColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  188. savebk = SetBkColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
  189. }
  190. DrawTextEx(pdis->hDC,
  191. szText,
  192. -1,
  193. &pdis->rcItem,
  194. DT_EXPANDTABS | DT_NOPREFIX | DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_EXTERNALLEADING,
  195. 0);
  196. RECT extRect = pdis->rcItem;
  197. DrawTextEx(pdis->hDC,
  198. szText,
  199. -1,
  200. &extRect,
  201. DT_CALCRECT | DT_EXPANDTABS | DT_NOPREFIX | DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_EXTERNALLEADING,
  202. 0);
  203. if (pdis->itemState & ODS_SELECTED)
  204. {
  205. SetTextColor(pdis->hDC, savetext );
  206. SetBkColor(pdis->hDC, savebk);
  207. }
  208. if (extRect.right > _nExtent)
  209. {
  210. _nExtent = extRect.right ;
  211. SendMessage( LB_SETHORIZONTALEXTENT, _nExtent, 0);
  212. }
  213. }
  214. break;
  215. case ODA_FOCUS:
  216. // Do not process focus changes. The focus caret
  217. // (outline rectangle) indicates the selection.
  218. // The IDOK button indicates the final
  219. // selection.
  220. break;
  221. }
  222. }
  223. CStatusDialog::CStatusDialog(HWND parent, CMTScript *pMTScript)
  224. : _parent(parent), _pMTScript(pMTScript), _fLogToFile(FALSE)
  225. {
  226. _hwnd = 0;
  227. Assert(pMTScript);
  228. // _cstrLogFileName.Set(L"\\\\jporkka10\\log\\MT%COMPUTERNAME%.log");
  229. _cstrLogFileName.Set(L"%TEMP%\\%COMPUTERNAME%_MTDbg.log");
  230. UpdateOptionSettings(false);
  231. if (_fStatusOpen)
  232. Show();
  233. }
  234. CStatusDialog::~CStatusDialog()
  235. {
  236. if (_hwnd)
  237. DestroyWindow(_hwnd);
  238. ClearOutput();
  239. }
  240. CCustomListBox *CStatusDialog::CtrlIDToListBox(UINT CtrlID)
  241. {
  242. switch(CtrlID)
  243. {
  244. case IDC_SCRIPTLIST:
  245. return &_CScriptListBox;
  246. case IDC_PROCESSLIST:
  247. return &_CProcessListBox;
  248. case IDC_SIGNALLIST:
  249. return &_CSignalListBox;
  250. case IDC_DEBUGOUTPUT:
  251. return &_COutputListBox;
  252. default:
  253. Assert(0);
  254. break;
  255. }
  256. return 0;
  257. }
  258. bool CStatusDialog::Show()
  259. {
  260. if (!_hwnd)
  261. {
  262. _hwnd = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_STATUSDIALOG), _parent, DlgProc, (LONG)this);
  263. if (!_hwnd)
  264. return false;
  265. _fStatusOpen = true;
  266. WINDOWPLACEMENT wp = { sizeof(WINDOWPLACEMENT) };
  267. GetWindowPlacement(_hwnd, &wp);
  268. if (!IsRectEmpty(&_WindowPlacement.rcNormalPosition))
  269. wp.rcNormalPosition = _WindowPlacement.rcNormalPosition;
  270. wp.ptMaxPosition = _WindowPlacement.ptMaxPosition;
  271. wp.flags = 0;
  272. if (_fMaximized)
  273. wp.showCmd = SW_SHOWMAXIMIZED;
  274. SetWindowPlacement(_hwnd, &wp);
  275. UpdateOptionSettings(true);
  276. }
  277. return true;
  278. }
  279. void CStatusDialog::InitDialog()
  280. {
  281. _CScriptListBox.Init(_hwnd, IDC_SCRIPTLIST);
  282. _CProcessListBox.Init(_hwnd, IDC_PROCESSLIST);
  283. _CSignalListBox.Init(_hwnd, IDC_SIGNALLIST);
  284. _COutputListBox.Init(_hwnd, IDC_DEBUGOUTPUT);
  285. SendDlgItemMessage(_hwnd, IDC_LOGGING, BM_SETCHECK, _fLogToFile ? BST_CHECKED : BST_UNCHECKED, 0);
  286. Refresh();
  287. RECT rect;
  288. GetWindowRect(_hwnd, &rect);
  289. _InitialSize.x = rect.right - rect.left;
  290. _InitialSize.y = rect.bottom - rect.top;
  291. static struct CResizeInfo rgResizeInfo[] =
  292. {
  293. { IDC_OUTPUTTEXT, CResizer::sf_HalfLeftWidth },
  294. { IDC_DEBUGOUTPUT, CResizer::sf_HalfLeftWidth | CResizer::sf_Height },
  295. { IDOK, CResizer::sf_Top | CResizer::sf_Left },
  296. { IDC_CLEAR, CResizer::sf_Top | CResizer::sf_Left },
  297. { IDC_EXIT, CResizer::sf_Top | CResizer::sf_Left },
  298. { IDC_SCRIPTLIST, CResizer::sf_HalfWidth },
  299. { IDC_PROCESSLIST, CResizer::sf_HalfWidth | CResizer::sf_Height },
  300. { IDC_SIGNALLIST, CResizer::sf_Top | CResizer::sf_HalfWidth },
  301. { IDC_SIGNALTEXT, CResizer::sf_Top },
  302. { IDC_LOGGING, CResizer::sf_Top },
  303. {0}
  304. };
  305. _Resizer.Init(_hwnd, rgResizeInfo);
  306. }
  307. void CStatusDialog::Destroy()
  308. {
  309. UpdateOptionSettings(true);
  310. _hwnd = 0;
  311. _CScriptListBox.Destroy();
  312. _CProcessListBox.Destroy();
  313. _CSignalListBox.Destroy();
  314. _COutputListBox.Destroy();
  315. #if DBG != 1
  316. _COutputListBox.ResetContent();
  317. #endif
  318. }
  319. BOOL CALLBACK CStatusDialog::DlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  320. {
  321. CStatusDialog *stats = (CStatusDialog *)GetWindowLong(hwnd, GWL_USERDATA);
  322. switch(uMsg)
  323. {
  324. case WM_INITDIALOG:
  325. {
  326. SetWindowLong(hwnd, GWL_USERDATA, lParam);
  327. stats = (CStatusDialog *)lParam;
  328. stats->_hwnd = hwnd;
  329. stats->InitDialog();
  330. if (!stats->_fPaused)
  331. SetTimer(hwnd, 1, REFRESH_DELAY, 0);
  332. break;
  333. }
  334. case WM_COMMAND:
  335. {
  336. switch (LOWORD(wParam))
  337. {
  338. case IDOK:
  339. case IDCANCEL:
  340. if (stats)
  341. stats->_fStatusOpen = false;
  342. DestroyWindow(hwnd);
  343. break;
  344. case IDC_EXIT:
  345. DestroyWindow(hwnd);
  346. PostQuitMessage(0);
  347. break;
  348. case IDC_CLEAR:
  349. if (stats)
  350. stats->ClearOutput();
  351. break;
  352. case IDC_SIGNALLIST:
  353. if (stats && HIWORD(wParam) == LBN_DBLCLK)
  354. {
  355. CCustomListBox *pListBox = stats->CtrlIDToListBox(LOWORD(wParam));
  356. if (pListBox == &stats->_CSignalListBox)
  357. {
  358. stats->ToggleSignal();
  359. }
  360. }
  361. break;
  362. case IDC_LOGGING:
  363. if (stats)
  364. stats->UpdateLogging();
  365. break;
  366. }
  367. break;
  368. }
  369. case WM_TIMER:
  370. if (stats)
  371. stats->Refresh();
  372. break;
  373. case WM_DESTROY:
  374. KillTimer(hwnd, 1);
  375. SetWindowLong(hwnd, GWL_USERDATA, 0);
  376. if (stats)
  377. stats->Destroy();
  378. break;
  379. case WM_GETMINMAXINFO:
  380. if (stats)
  381. stats->GetMinMaxInfo((MINMAXINFO *)lParam);
  382. break;
  383. case WM_MOVE:
  384. break;
  385. case WM_SIZE:
  386. if (stats)
  387. stats->Resize(LOWORD(lParam), HIWORD(lParam));
  388. break;
  389. case WM_EXITSIZEMOVE:
  390. if (stats)
  391. {
  392. stats->UpdateOptionSettings(true);
  393. }
  394. break;
  395. case WM_MEASUREITEM:
  396. if (stats)
  397. {
  398. CCustomListBox *pListBox = stats->CtrlIDToListBox(wParam);
  399. if (pListBox )
  400. pListBox->MeasureItem( (LPMEASUREITEMSTRUCT) lParam);
  401. }
  402. break;
  403. case WM_DRAWITEM:
  404. if (stats)
  405. {
  406. CCustomListBox *pListBox = stats->CtrlIDToListBox(wParam);
  407. if (pListBox )
  408. pListBox->DrawItem((DRAWITEMSTRUCT *) lParam);
  409. }
  410. break;
  411. default:
  412. return 0; // did not process the message;
  413. }
  414. return true;
  415. }
  416. BOOL CStatusDialog::IsDialogMessage(MSG *msg)
  417. {
  418. if (_hwnd)
  419. {
  420. return ::IsDialogMessage(_hwnd, msg);
  421. }
  422. return 0;
  423. }
  424. void CStatusDialog::PopulateScripts()
  425. {
  426. int i = 0;
  427. if (_hwnd)
  428. {
  429. TCHAR szBuffer[MAX_SCRIPT_NAME_LENGTH];
  430. long cBuffer = MAX_SCRIPT_NAME_LENGTH;
  431. _pMTScript->GetScriptNames(szBuffer, &cBuffer); // We don't really care if we do not get all of them..,
  432. TCHAR *ptr = szBuffer;
  433. while (*ptr && ptr < szBuffer + MAX_SCRIPT_NAME_LENGTH)
  434. {
  435. _CScriptListBox.SetString(i, ptr);
  436. ptr += _tcslen(ptr) + 1;
  437. ++i;
  438. }
  439. _CScriptListBox.SetEnd(i);
  440. _CScriptListBox.Refresh();
  441. }
  442. }
  443. void CStatusDialog::PopulateSignals()
  444. {
  445. int i = 0;
  446. HANDLE hEvent;
  447. CStr cstr;
  448. if (_hwnd)
  449. {
  450. for(i = 0; CScriptHost::GetSyncEventName(i, &cstr, &hEvent) == S_OK; ++i)
  451. {
  452. wchar_t szSignalText[256];
  453. bool signalled = (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0);
  454. wsprintf(szSignalText, L"%s:\t%.32s", signalled ? L"Set" : L"Clr", (LPTSTR)cstr);
  455. szSignalText[ARRAY_SIZE(szSignalText) - 1] = 0;
  456. _CSignalListBox.SetString(i, szSignalText);
  457. }
  458. _CSignalListBox.SetEnd(i);
  459. _CSignalListBox.Refresh();
  460. }
  461. }
  462. wchar_t *FormatFileTime(_int64 t, wchar_t szBuf[16])
  463. {
  464. wchar_t *szPrefix = L"";
  465. if (t < 0)
  466. {
  467. t = -t;
  468. szPrefix = L"-";
  469. }
  470. t /= 1000;
  471. long Sec = t % 60;
  472. long Min = (t / 60) % 60;
  473. long Hours = t / 3600;
  474. wsprintf(szBuf, L"%s%02.2d:%02.2d:%02.2d", szPrefix, Hours, Min, Sec);
  475. return szBuf;
  476. }
  477. void CStatusDialog::PopulateProcesses()
  478. {
  479. if (!_hwnd)
  480. return;
  481. int cProcesses = 0;
  482. for(int pass = 0; pass < 2; ++pass)
  483. {
  484. CProcessThread *pProcess;
  485. for(int i = 0; (pProcess = _pMTScript->GetProcess(i)) != 0; ++i)
  486. {
  487. const PROCESS_PARAMS *params = pProcess->GetParams();
  488. const TCHAR *ptr = _T("<invalid>");
  489. if (params->pszCommand)
  490. ptr = (LPTSTR)params->pszCommand;
  491. wchar_t szText[256];
  492. wchar_t szTimeBuf[16];
  493. DWORD dwExitCode = pProcess->GetExitCode();
  494. if (pass == 0 && dwExitCode == STILL_ACTIVE)
  495. {
  496. HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION,
  497. false,
  498. pProcess->ProcId());
  499. if (hProc)
  500. {
  501. _int64 i64CreationTime;
  502. _int64 i64ExitTime;
  503. _int64 i64KernelTime;
  504. _int64 i64UserTime;
  505. GetProcessTimes(hProc,
  506. (FILETIME*) &i64CreationTime,
  507. (FILETIME*) &i64ExitTime,
  508. (FILETIME*) &i64KernelTime,
  509. (FILETIME*) &i64UserTime);
  510. GetSystemTimeAsFileTime((FILETIME*)&i64ExitTime);
  511. CloseHandle(hProc);
  512. wsprintf(szText, L"%04d (R):\t%.128s (%s)",
  513. pProcess->ProcId(),
  514. ptr,
  515. FormatFileTime((i64ExitTime - i64CreationTime) / 10000, szTimeBuf));
  516. }
  517. else
  518. wsprintf(szText, L"%04d (R):\t%.128s", pProcess->ProcId(), ptr);
  519. szText[ARRAY_SIZE(szText) - 1] = 0;
  520. _CProcessListBox.SetString(cProcesses, szText);
  521. ++cProcesses;
  522. }
  523. else if (pass == 1 && dwExitCode != STILL_ACTIVE)
  524. {
  525. wsprintf(szText, L"%04d (%u):\t%.128s\t (-%s)",
  526. pProcess->ProcId(),
  527. dwExitCode,
  528. ptr, FormatFileTime(pProcess->GetDeadTime() , szTimeBuf));
  529. szText[ARRAY_SIZE(szText) - 1] = 0;
  530. _CProcessListBox.SetString(cProcesses, szText);
  531. ++cProcesses;
  532. }
  533. }
  534. }
  535. _CProcessListBox.SetEnd(cProcesses);
  536. _CProcessListBox.Refresh();
  537. }
  538. void CStatusDialog::Refresh()
  539. {
  540. PopulateScripts();
  541. PopulateProcesses();
  542. PopulateSignals();
  543. }
  544. bool Exists(const TCHAR *pszLogFileName)
  545. {
  546. WIN32_FIND_DATA fd;
  547. HANDLE hFind = FindFirstFile(pszLogFileName, &fd);
  548. if (hFind != INVALID_HANDLE_VALUE)
  549. {
  550. FindClose(hFind);
  551. return true;
  552. }
  553. return false;
  554. }
  555. void RenumberFile(const TCHAR *pszLogFileName)
  556. {
  557. if (Exists(pszLogFileName))
  558. {
  559. TCHAR achFileName[MAX_PATH + 32];
  560. const TCHAR *dot = wcsrchr(pszLogFileName, L'.');
  561. const TCHAR *slash = wcsrchr(pszLogFileName, L'\\');
  562. const TCHAR *colon = wcsrchr(pszLogFileName, L':');
  563. if (dot && dot > pszLogFileName && dot > slash && dot > colon)
  564. {
  565. for(int i = 1; i < 999; ++i)
  566. {
  567. swprintf(achFileName, L"%.*s_%.03d.%s", dot - pszLogFileName, pszLogFileName, i, dot + 1);
  568. if (!Exists(achFileName))
  569. {
  570. MoveFile(pszLogFileName, achFileName);
  571. break;
  572. }
  573. }
  574. }
  575. }
  576. }
  577. void CStatusDialog::OUTPUTDEBUGSTRING(LPWSTR pszMsg)
  578. {
  579. #if DBG != 1
  580. if (_hwnd)
  581. #endif
  582. {
  583. _COutputListBox.AppendString(pszMsg);
  584. _COutputListBox.Refresh();
  585. }
  586. if (_fLogToFile )
  587. {
  588. if (!_fCreatedLogFileName)
  589. {
  590. if (ExpandEnvironmentStrings(_cstrLogFileName, _achLogFileName, ARRAY_SIZE(_achLogFileName)))
  591. _fCreatedLogFileName = true;
  592. RenumberFile(_achLogFileName);
  593. _fAddedHeaderToFile = false;
  594. }
  595. FILE *f = _wfopen(_achLogFileName, L"a+");
  596. if (f)
  597. {
  598. if (!_fAddedHeaderToFile)
  599. {
  600. _fAddedHeaderToFile = true;
  601. time_t t = time(0);
  602. fprintf(f, "============================\nMTScript started %s", ctime(&t));
  603. }
  604. fputws(pszMsg, f);
  605. fputws(L"\n", f);
  606. fclose(f);
  607. }
  608. }
  609. }
  610. void CStatusDialog::ClearOutput()
  611. {
  612. _COutputListBox.ResetContent();
  613. _COutputListBox.Refresh();
  614. }
  615. void CStatusDialog::Resize(int width, int height)
  616. {
  617. _Resizer.NewSize();
  618. }
  619. void CStatusDialog::GetMinMaxInfo(MINMAXINFO *mmi)
  620. {
  621. mmi->ptMinTrackSize = _InitialSize;
  622. }
  623. void CStatusDialog::Pause()
  624. {
  625. if (_hwnd)
  626. {
  627. KillTimer(_hwnd, 1);
  628. }
  629. _fPaused = TRUE;
  630. }
  631. void CStatusDialog::Restart()
  632. {
  633. if (_hwnd && _fPaused)
  634. {
  635. SetTimer(_hwnd, 1, REFRESH_DELAY, 0);
  636. }
  637. _fPaused = FALSE;
  638. _fAddedHeaderToFile = false;
  639. }
  640. HRESULT CStatusDialog::UpdateOptionSettings(BOOL fSave)
  641. {
  642. static REGKEYINFORMATION aKeyValuesOptions[] =
  643. {
  644. { _T("Options"), RKI_KEY, 0 },
  645. { _T("StatusDialogOpen"), RKI_BOOL, offsetof(CStatusDialog, _fStatusOpen) },
  646. { _T("LogToFile"), RKI_BOOL, offsetof(CStatusDialog, _fLogToFile) } ,
  647. { _T("LogFileName"), RKI_STRING, offsetof(CStatusDialog, _cstrLogFileName) } ,
  648. { _T("StatusLeft"), RKI_DWORD, offsetof(CStatusDialog, _WindowPlacement.rcNormalPosition.left) },
  649. { _T("StatusTop"), RKI_DWORD, offsetof(CStatusDialog, _WindowPlacement.rcNormalPosition.top) },
  650. { _T("StatusRight"), RKI_DWORD, offsetof(CStatusDialog, _WindowPlacement.rcNormalPosition.right) },
  651. { _T("StatusBottom"), RKI_DWORD, offsetof(CStatusDialog, _WindowPlacement.rcNormalPosition.bottom) },
  652. { _T("StatusMaxLeft"), RKI_DWORD, offsetof(CStatusDialog, _WindowPlacement.ptMaxPosition.x) },
  653. { _T("StatusMaxTop"), RKI_DWORD, offsetof(CStatusDialog, _WindowPlacement.ptMaxPosition.y) },
  654. { _T("StatusMax"), RKI_BOOL, offsetof(CStatusDialog, _fMaximized) } ,
  655. };
  656. HRESULT hr;
  657. if (fSave)
  658. {
  659. if (_hwnd)
  660. {
  661. _WindowPlacement.length = sizeof(WINDOWPLACEMENT);
  662. GetWindowPlacement(_hwnd, &_WindowPlacement);
  663. if (_WindowPlacement.showCmd == SW_MAXIMIZE)
  664. _fMaximized = TRUE;
  665. else
  666. _fMaximized = FALSE;
  667. }
  668. }
  669. hr = RegSettingsIO(g_szRegistry, fSave, aKeyValuesOptions, ARRAY_SIZE(aKeyValuesOptions), (BYTE *)this);
  670. return hr;
  671. }
  672. void CStatusDialog::ToggleSignal()
  673. {
  674. int index = _CSignalListBox.SendMessage(LB_GETCARETINDEX, 0, 0);
  675. LPCTSTR pszName = _CSignalListBox.GetString(index);
  676. if (pszName)
  677. pszName = wcschr(pszName, L'\t');
  678. HANDLE hEvent;
  679. if (pszName && CScriptHost::GetSyncEvent(pszName + 1, &hEvent) == S_OK)
  680. {
  681. bool signalled = (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0);
  682. if (signalled)
  683. ResetEvent(hEvent);
  684. else
  685. SetEvent(hEvent);
  686. }
  687. }
  688. void CStatusDialog::UpdateLogging()
  689. {
  690. _fLogToFile = (SendDlgItemMessage(_hwnd, IDC_LOGGING, BM_GETCHECK, 0, 0) == BST_CHECKED);
  691. }