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.

942 lines
27 KiB

  1. //------------------------------------------------------------------------
  2. //
  3. // File: shell\themes\test\ctlperf\CtlPerfView.cpp
  4. //
  5. // Contents: Implementation of the CCtlPerfView class.
  6. //
  7. // Classes: CCtlPerfView
  8. //
  9. //------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "resource.h"
  12. #include "CtlPerfView.h"
  13. #include "Samples.h"
  14. #include <atlmisc.h>
  15. #include <shellapi.h>
  16. //** Local constants
  17. // Default log file name
  18. const TCHAR kszLogFileName[] = _T("CtlPerf.log");
  19. // Default number of loops
  20. const UINT kcLoops = 100;
  21. // Default numbers of controls in X
  22. const UINT kcxCtrl = 10;
  23. // Default numbers of controls in Y
  24. const UINT kcyCtrl = 10;
  25. // Default name for pass 1
  26. const TCHAR kszPass1[] = _T("Pass1");
  27. // Default name for pass 2
  28. const TCHAR kszPass2[] = _T("Pass2");
  29. // Default value for NumberOnly
  30. const TCHAR kszNumberOnly[] = _T("false");
  31. //+-----------------------------------------------------------------------
  32. //
  33. // Member: CCtlPerfView::CCtlPerfView
  34. //
  35. // Synopsis: Constructor
  36. //
  37. //------------------------------------------------------------------------
  38. CCtlPerfView::CCtlPerfView()
  39. {
  40. m_hWndStatusBar = NULL;
  41. m_rgWnds = NULL;
  42. m_rgzClasses = NULL;
  43. m_cClasses = 0;
  44. m_cxCtrl = kcxCtrl;
  45. m_cyCtrl = kcyCtrl;
  46. m_cX = 0;
  47. m_cY = 0;
  48. m_cLoops = kcLoops;
  49. m_bTwoPasses = false;
  50. m_bBatch = false;
  51. m_bSilent = false;
  52. _tcscpy(m_szLogFileName, kszLogFileName);
  53. _tcscpy(m_szPass1, kszPass1);
  54. _tcscpy(m_szPass2, kszPass2);
  55. _tcscpy(m_szNumberOnly, kszNumberOnly);
  56. ParseIniFile();
  57. }
  58. //+-----------------------------------------------------------------------
  59. //
  60. // Member: CCtlPerfView::~CCtlPerfView
  61. //
  62. // Synopsis: Destructor
  63. //
  64. //------------------------------------------------------------------------
  65. CCtlPerfView::~CCtlPerfView()
  66. {
  67. if (m_rgWnds)
  68. {
  69. free(m_rgWnds);
  70. }
  71. if (m_rgzClasses)
  72. {
  73. for(UINT i = 0; i < m_cClasses; i++)
  74. {
  75. if (m_rgzClasses[i])
  76. {
  77. free(m_rgzClasses[i]);
  78. }
  79. }
  80. free(m_rgzClasses);
  81. }
  82. }
  83. //+-----------------------------------------------------------------------
  84. //
  85. // Member: CCtlPerfView::SetStatusBar
  86. //
  87. // Synopsis: Receive status bar from parent
  88. //
  89. // Arguments: hWndStatusBar Status bar window handle
  90. //
  91. //------------------------------------------------------------------------
  92. void CCtlPerfView::SetStatusBar(HWND hWndStatusBar)
  93. {
  94. m_hWndStatusBar = hWndStatusBar;
  95. }
  96. //+-----------------------------------------------------------------------
  97. //
  98. // Member: CCtlPerfView::ParseIniFile
  99. //
  100. // Synopsis: Process INI file
  101. //
  102. //------------------------------------------------------------------------
  103. void CCtlPerfView::ParseIniFile()
  104. {
  105. FILE* flIniFile;
  106. flIniFile = ::_wfopen(_T("CtlPerf.ini"), _T("r"));
  107. if (flIniFile)
  108. {
  109. TCHAR szLine[1024];
  110. szLine[0] = _T('\0');
  111. #define STRIP_TRAILING_RETURN(s) \
  112. { \
  113. LPTSTR p = _tcschr(s, _T('\n')); \
  114. \
  115. if(p) \
  116. { \
  117. *p = _T('\0'); \
  118. } \
  119. }
  120. while (!feof(flIniFile))
  121. {
  122. // Read the [Classes] section
  123. ::fgetws(szLine, _countof(szLine), flIniFile);
  124. STRIP_TRAILING_RETURN(szLine);
  125. if (!_tcsicmp(szLine, _T("[Classes]")))
  126. {
  127. szLine[0] = _T('\0');
  128. ::fgetws(szLine, _countof(szLine), flIniFile);
  129. STRIP_TRAILING_RETURN(szLine);
  130. // Read each class
  131. while (szLine[0] != _T('\0') && szLine[0] != _T('['))
  132. {
  133. if (szLine[0] != _T(';'))
  134. {
  135. m_cClasses++;
  136. m_rgzClasses = (LPTSTR*) realloc(m_rgzClasses, m_cClasses * sizeof(LPTSTR));
  137. if (m_rgzClasses)
  138. {
  139. m_rgzClasses[m_cClasses - 1] = _tcsdup(szLine);
  140. }
  141. }
  142. szLine[0] = _T('\0');
  143. ::fgetws(szLine, _countof(szLine), flIniFile);
  144. STRIP_TRAILING_RETURN(szLine);
  145. }
  146. }
  147. // Read the Options section
  148. if (!_tcsicmp(szLine, _T("[Options]")))
  149. {
  150. UINT n;
  151. UINT n1;
  152. UINT n2;
  153. szLine[0] = _T('\0');
  154. ::fgetws(szLine, _countof(szLine), flIniFile);
  155. STRIP_TRAILING_RETURN(szLine);
  156. // Try each token, to time to do better
  157. while (szLine[0] != _T('\0') && szLine[0] != _T('['))
  158. {
  159. n = 0;
  160. swscanf(szLine, _T("XControls=%d"), &n);
  161. if (n)
  162. {
  163. m_cxCtrl = n;
  164. }
  165. else
  166. {
  167. swscanf(szLine, _T("YControls=%d"), &n);
  168. if (n)
  169. {
  170. m_cyCtrl = n;
  171. }
  172. else
  173. {
  174. swscanf(szLine, _T("NumLoops=%d"), &n);
  175. if (n)
  176. {
  177. m_cLoops = n;
  178. }
  179. else
  180. {
  181. n1 = n2 = 0;
  182. swscanf(szLine, _T("Resolution=%dx%d"), &n1, &n2);
  183. if (n1 && n2)
  184. {
  185. m_cX = n1;
  186. m_cY = n2;
  187. }
  188. else
  189. {
  190. LPTSTR p = _tcschr(szLine, _T('='));
  191. if(p && !_tcsnicmp(szLine, _T("Pass1"), _countof(_T("Pass1")) - 1))
  192. {
  193. _tcscpy(m_szPass1, p + 1);
  194. }
  195. else if(p && !_tcsnicmp(szLine, _T("Pass2"), _countof(_T("Pass2")) - 1))
  196. {
  197. _tcscpy(m_szPass2, p + 1);
  198. }
  199. else if(p && !_tcsnicmp(szLine, _T("LogFile"), _countof(_T("LogFile")) - 1))
  200. {
  201. _tcscpy(m_szLogFileName, p + 1);
  202. }
  203. else if(p && !_tcsnicmp(szLine, _T("Viewer"), _countof(_T("Viewer")) - 1))
  204. {
  205. _tcscpy(m_szViewer, p + 1);
  206. }
  207. else if(p && !_tcsnicmp(szLine, _T("NumberOnly"), _countof(_T("NumberOnly")) - 1))
  208. {
  209. _tcscpy(m_szNumberOnly, p + 1);
  210. }
  211. }
  212. }
  213. }
  214. }
  215. szLine[0] = _T('\0');
  216. ::fgetws(szLine, _countof(szLine), flIniFile);
  217. STRIP_TRAILING_RETURN(szLine);
  218. }
  219. }
  220. }
  221. fclose(flIniFile);
  222. }
  223. m_rgWnds = (HWND*) calloc(m_cxCtrl * m_cyCtrl, sizeof(HWND));
  224. }
  225. //+-----------------------------------------------------------------------
  226. //
  227. // Member: CCtlPerfView::TestControl
  228. //
  229. // Synopsis: Test a single control class
  230. //
  231. // Arguments: szClassName Name of window class to create
  232. //
  233. //------------------------------------------------------------------------
  234. void CCtlPerfView::TestControl(LPTSTR szClassName)
  235. {
  236. UINT nWidth;
  237. UINT nHeight;
  238. DWORD dwStyle = WS_BORDER;
  239. CRect rcWindow;
  240. ClearChildren();
  241. GetWindowRect(rcWindow);
  242. nWidth = rcWindow.Width() / (m_cxCtrl + 1);
  243. nHeight = rcWindow.Height() / (m_cyCtrl + 1);
  244. // Some controls need specials styles
  245. if (!_tcsicmp(szClassName, _T("ToolbarWindow32"))
  246. || !_tcsicmp(szClassName, _T("ReBarWindow32"))
  247. || !_tcsicmp(szClassName, _T("msctls_statusbar32")))
  248. {
  249. dwStyle |= CCS_NOPARENTALIGN | CCS_NORESIZE;
  250. }
  251. if (!_tcsicmp(szClassName, _T("SysTreeView32")))
  252. {
  253. dwStyle |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_CHECKBOXES;
  254. }
  255. // Some controls need an initialization routine to create data
  256. // See samples.*
  257. PFNINIT pf = NULL; // Routine to call after creation
  258. if (!_tcsicmp(szClassName, _T("SysTabControl32")))
  259. {
  260. pf = Pickers_Init;
  261. }
  262. if (!_tcsicmp(szClassName, _T("msctls_progress32")))
  263. {
  264. pf = Movers_Init;
  265. }
  266. if (!_tcsicmp(szClassName, _T("ListBox")))
  267. {
  268. pf = Lists_Init;
  269. }
  270. if (!_tcsicmp(szClassName, _T("ComboBox")))
  271. {
  272. pf = Combo_Init;
  273. }
  274. if (!_tcsicmp(szClassName, _T("ComboBoxEx32")))
  275. {
  276. pf = ComboEx_Init;
  277. }
  278. if (!_tcsicmp(szClassName, _T("SysListView32")))
  279. {
  280. pf = ListView_Init;
  281. }
  282. if (!_tcsicmp(szClassName, _T("SysTreeView32")))
  283. {
  284. pf = TreeView_Init;
  285. }
  286. if (!_tcsicmp(szClassName, _T("msctls_statusbar32")))
  287. {
  288. pf = Status_Init;
  289. }
  290. if (!_tcsicmp(szClassName, _T("SysTabControl32")))
  291. {
  292. pf = Pickers_Init;
  293. }
  294. if (!_tcsicmp(szClassName, _T("ToolbarWindow32")))
  295. {
  296. pf = Toolbar_Init;
  297. }
  298. if (!_tcsicmp(szClassName, _T("ReBarWindow32")))
  299. {
  300. pf = Rebar_Init;
  301. }
  302. m_perfLog.OpenLoggingClass(szClassName);
  303. m_perfLog.StartCreate(m_cxCtrl * m_cyCtrl);
  304. // Create m_cLoops instances
  305. // They're initially visible for better perf realism, but set to non-visible while adding data (if any)
  306. for (UINT i = 0; i < m_cxCtrl; i++)
  307. {
  308. for (UINT j = 0; j < m_cyCtrl; j++)
  309. {
  310. m_rgWnds[i + m_cxCtrl * j] = ::CreateWindow(szClassName,
  311. szClassName,
  312. WS_CHILD | WS_VISIBLE | dwStyle,
  313. i * nWidth * (m_cxCtrl + 1) / m_cxCtrl,
  314. j * nHeight * (m_cyCtrl + 1) / m_cyCtrl,
  315. nWidth,
  316. nHeight,
  317. m_hWnd,
  318. NULL,
  319. _Module.GetModuleInstance(),
  320. NULL);
  321. ATLASSERT(m_rgWnds[i + m_cxCtrl * j]);
  322. if (!m_rgWnds[i + m_cxCtrl * j])
  323. {
  324. if (!m_bBatch)
  325. {
  326. TCHAR szMessage[1024];
  327. wsprintf(szMessage, _T("Failed to create class %s, test aborted."), szClassName);
  328. MessageBox(szMessage, _T("CtlPerf"), MB_OK | MB_ICONERROR);
  329. }
  330. return;
  331. }
  332. if(pf != NULL)
  333. {
  334. DWORD dwOldStyle = ::GetWindowLong(m_rgWnds[i + m_cxCtrl * j], GWL_STYLE);
  335. ::SetWindowLong(m_rgWnds[i + m_cxCtrl * j], GWL_STYLE, dwOldStyle & ~WS_VISIBLE);
  336. pf(m_rgWnds[i + m_cxCtrl * j]);
  337. ::SetWindowLong(m_rgWnds[i + m_cxCtrl * j], GWL_STYLE, dwOldStyle);
  338. }
  339. // Handle escape key to abort
  340. if(::GetAsyncKeyState(VK_ESCAPE))
  341. {
  342. m_perfLog.StopLogging();
  343. return;
  344. }
  345. }
  346. }
  347. m_perfLog.StopCreate();
  348. m_perfLog.StartPaint(m_cLoops);
  349. for (i = 0; i < m_cLoops; i++)
  350. {
  351. RedrawWindow(NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW | RDW_ALLCHILDREN);
  352. // Handle escape key to abort
  353. if(::GetAsyncKeyState(VK_ESCAPE))
  354. {
  355. m_perfLog.StopLogging();
  356. return;
  357. }
  358. }
  359. m_perfLog.StopPaint();
  360. TimeResize();
  361. m_perfLog.CloseLoggingClass();
  362. }
  363. //+-----------------------------------------------------------------------
  364. //
  365. // Member: CCtlPerfView::OnFinalMessage
  366. //
  367. // Synopsis: Called after window destruction, do window cleanup
  368. //
  369. //------------------------------------------------------------------------
  370. void CCtlPerfView::OnFinalMessage(HWND /*hWnd*/)
  371. {
  372. m_perfLog.StopLogging();
  373. ClearChildren();
  374. }
  375. //+-----------------------------------------------------------------------
  376. //
  377. // Member: CCtlPerfView::ClearChildren
  378. //
  379. // Synopsis: Destroy all child windows
  380. //
  381. //------------------------------------------------------------------------
  382. void CCtlPerfView::ClearChildren()
  383. {
  384. for (UINT i = 0; i < m_cxCtrl; i++)
  385. {
  386. for (UINT j = 0; j < m_cyCtrl; j++)
  387. {
  388. if (::IsWindow(m_rgWnds[i + m_cxCtrl * j]))
  389. {
  390. ::DestroyWindow(m_rgWnds[i + m_cxCtrl * j]);
  391. }
  392. m_rgWnds[i + m_cxCtrl * j] = NULL;
  393. }
  394. }
  395. }
  396. //+-----------------------------------------------------------------------
  397. //
  398. // Member: CCtlPerfView::ResizeChildren
  399. //
  400. // Synopsis: Resize the controls inside the client area
  401. //
  402. //------------------------------------------------------------------------
  403. void CCtlPerfView::ResizeChildren()
  404. {
  405. CRect rcWindow;
  406. GetWindowRect(rcWindow);
  407. UINT nWidth = rcWindow.Width() / (m_cxCtrl + 1);
  408. UINT nHeight = rcWindow.Height() / (m_cyCtrl + 1);
  409. for (UINT i = 0; i < m_cxCtrl; i++)
  410. {
  411. for (UINT j = 0; j < m_cyCtrl; j++)
  412. {
  413. if (!::IsWindow(m_rgWnds[i + m_cxCtrl * j]))
  414. {
  415. continue;
  416. }
  417. ::SetWindowPos(m_rgWnds[i + m_cxCtrl * j],
  418. NULL,
  419. i * nWidth * (m_cxCtrl + 1) / m_cxCtrl,
  420. j * nHeight * (m_cyCtrl + 1) / m_cyCtrl,
  421. nWidth,
  422. nHeight,
  423. SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE);
  424. }
  425. }
  426. }
  427. //+-----------------------------------------------------------------------
  428. //
  429. // Member: CCtlPerfView::TimeResize
  430. //
  431. // Synopsis: Does the whole resizing timing
  432. //
  433. //------------------------------------------------------------------------
  434. void CCtlPerfView::TimeResize()
  435. {
  436. m_perfLog.StartResize(m_cLoops);
  437. CRect rcWindow;
  438. CWindow wnd(GetTopLevelParent());
  439. wnd.GetWindowRect(rcWindow);
  440. UINT nWidth = rcWindow.Width();
  441. UINT nHeight = rcWindow.Height();
  442. MSG msg;
  443. // First resize without repainting
  444. for (UINT i = 0; i < m_cLoops; i++)
  445. {
  446. nWidth -= 4;
  447. nHeight -= 3;
  448. wnd.SetWindowPos(NULL,
  449. 0,
  450. 0,
  451. nWidth,
  452. nHeight,
  453. SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
  454. // Leave the message loop breathe a little (else it locks)
  455. while (!::PeekMessage(&msg, wnd, NULL, NULL, PM_NOREMOVE));
  456. // Handle escape key to abort
  457. if(::GetAsyncKeyState(VK_ESCAPE))
  458. {
  459. m_perfLog.StopLogging();
  460. return;
  461. }
  462. }
  463. m_perfLog.StopResize();
  464. // Repaint once (not timed)
  465. wnd.SetWindowPos(NULL,
  466. 0,
  467. 0,
  468. rcWindow.Width(),
  469. rcWindow.Height(),
  470. SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
  471. m_perfLog.StartResizeAndPaint(m_cLoops);
  472. nWidth = rcWindow.Width();
  473. nHeight = rcWindow.Height();
  474. for (i = 0; i < m_cLoops; i++)
  475. {
  476. nWidth -= 4;
  477. nHeight -= 3;
  478. wnd.SetWindowPos(NULL,
  479. 0,
  480. 0,
  481. nWidth,
  482. nHeight,
  483. SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
  484. // This time we update each time
  485. UpdateWindow();
  486. // Leave the message loop breathe a little
  487. while (!::PeekMessage(&msg, wnd, NULL, NULL, PM_NOREMOVE));
  488. // Handle escape key to abort
  489. if(::GetAsyncKeyState(VK_ESCAPE))
  490. {
  491. m_perfLog.StopLogging();
  492. return;
  493. }
  494. }
  495. m_perfLog.StopResizeAndPaint();
  496. // Repaint once
  497. wnd.SetWindowPos(NULL,
  498. 0,
  499. 0,
  500. rcWindow.Width(),
  501. rcWindow.Height(),
  502. SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
  503. }
  504. //+-----------------------------------------------------------------------
  505. //
  506. // Member: CCtlPerfView::OnCreate
  507. //
  508. // Synopsis: WM_CREATE handler
  509. //
  510. //------------------------------------------------------------------------
  511. LRESULT CCtlPerfView::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  512. {
  513. // Create a menu with all the classes
  514. if (m_cClasses > 0)
  515. {
  516. CMenu menu(::GetMenu(GetParent()));
  517. if(menu != NULL)
  518. {
  519. CMenuItemInfo mii;
  520. mii.fMask = MIIM_SUBMENU;
  521. menu.GetSubMenu(0).GetMenuItemInfo(2, TRUE, &mii); // Hard-coded position!!
  522. for (UINT i = 0; i < m_cClasses; i++)
  523. ::AppendMenu(mii.hSubMenu, MF_STRING, IDM_CONTROL + i, m_rgzClasses[i]);
  524. }
  525. }
  526. bHandled = FALSE;
  527. return 0;
  528. }
  529. //+-----------------------------------------------------------------------
  530. //
  531. // Member: CCtlPerfView::OnSize
  532. //
  533. // Synopsis: WM_SIZE handler
  534. //
  535. //------------------------------------------------------------------------
  536. LRESULT CCtlPerfView::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
  537. {
  538. bHandled = FALSE;
  539. ResizeChildren();
  540. return 0;
  541. }
  542. //+-----------------------------------------------------------------------
  543. //
  544. // Member: CCtlPerfView::OnGetMinMaxInfo
  545. //
  546. // Synopsis: WM_GETMINMAXINFO handler, forwarded by the parent
  547. //
  548. //------------------------------------------------------------------------
  549. LRESULT CCtlPerfView::OnGetMinMaxInfo(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
  550. {
  551. if(m_cX == 0 || m_cY == 0)
  552. {
  553. bHandled = FALSE;
  554. return 1;
  555. }
  556. LPMINMAXINFO pMMI = (LPMINMAXINFO) lParam;
  557. if(pMMI)
  558. {
  559. pMMI->ptMaxSize = CPoint(m_cX, m_cY);
  560. }
  561. return 0;
  562. }
  563. //+-----------------------------------------------------------------------
  564. //
  565. // Member: CCtlPerfView::OnControl
  566. //
  567. // Synopsis: IDM_CONTROL handler
  568. //
  569. //------------------------------------------------------------------------
  570. LRESULT CCtlPerfView::OnControl(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled)
  571. {
  572. if (wID < IDM_CONTROL || wID > IDM_CONTROL + 99)
  573. {
  574. bHandled = 0;
  575. return 0;
  576. }
  577. LPTSTR pszClassName = m_rgzClasses[wID - IDM_CONTROL];
  578. // Time a single control class
  579. m_perfLog.StartLoggingOnePass(m_szLogFileName, m_hWndStatusBar, m_szPass1);
  580. TestControl(pszClassName);
  581. m_perfLog.CloseLoggingClass();
  582. m_perfLog.StopLogging();
  583. return 0;
  584. }
  585. //+-----------------------------------------------------------------------
  586. //
  587. // Member: CCtlPerfView::OnFrame
  588. //
  589. // Synopsis: IDM_FRAME handler
  590. //
  591. //------------------------------------------------------------------------
  592. LRESULT CCtlPerfView::OnFrame(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  593. {
  594. ClearChildren();
  595. m_perfLog.StartLoggingOnePass(m_szLogFileName, m_hWndStatusBar, m_szPass1);
  596. // Time the frame window
  597. m_perfLog.OpenLoggingClass(kszFrameWnd);
  598. m_perfLog.StartPaint(m_cLoops);
  599. for (UINT i = 0; i < m_cLoops; i++)
  600. RedrawWindow(NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW | RDW_ALLCHILDREN);
  601. m_perfLog.StopPaint();
  602. TimeResize();
  603. m_perfLog.CloseLoggingClass();
  604. m_perfLog.StopLogging();
  605. return 0;
  606. }
  607. //+-----------------------------------------------------------------------
  608. //
  609. // Member: CCtlPerfView::RunSuite
  610. //
  611. // Synopsis: Call TestControl() for every control class
  612. //
  613. //------------------------------------------------------------------------
  614. void CCtlPerfView::RunSuite()
  615. {
  616. // determine output type and set value in perflog
  617. m_perfLog.SetOutputType(m_szNumberOnly);
  618. // First do the frame
  619. m_perfLog.OpenLoggingClass(kszFrameWnd);
  620. m_perfLog.StartPaint(m_cLoops);
  621. for (UINT i = 0; i < m_cLoops; i++)
  622. RedrawWindow(NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_INTERNALPAINT | RDW_UPDATENOW | RDW_ALLCHILDREN);
  623. m_perfLog.StopPaint();
  624. TimeResize();
  625. m_perfLog.CloseLoggingClass();
  626. // Then each control
  627. for (i = 0; i < m_cClasses; i++)
  628. {
  629. if (m_rgzClasses[i])
  630. {
  631. TestControl(m_rgzClasses[i]);
  632. // Handle escape key to abort
  633. if(::GetAsyncKeyState(VK_ESCAPE))
  634. {
  635. m_perfLog.StopLogging();
  636. break;
  637. }
  638. }
  639. }
  640. }
  641. //+-----------------------------------------------------------------------
  642. //
  643. // Member: CCtlPerfView::OnSuite1
  644. //
  645. // Synopsis: IDM_SUITE1 handler: create and run one pass
  646. //
  647. //------------------------------------------------------------------------
  648. LRESULT CCtlPerfView::OnSuite1(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  649. {
  650. m_bTwoPasses = false;
  651. if (!m_bBatch)
  652. {
  653. COptionsDialog dlg(this);
  654. INT_PTR nRes = dlg.DoModal();
  655. if (nRes == IDCANCEL)
  656. return 0;
  657. // Reset the WS_MAXIMIZE style to set the parent to the new size, via WM_GETMINMAXINFO
  658. ::SetWindowLong(GetParent(), GWL_STYLE, ::GetWindowLong(GetParent(), GWL_STYLE) & ~WS_MAXIMIZE);
  659. ::ShowWindow(GetParent(), SW_MAXIMIZE);
  660. }
  661. m_perfLog.StartLoggingOnePass(m_szLogFileName, m_hWndStatusBar, m_szPass1);
  662. RunSuite();
  663. m_perfLog.StopLogging();
  664. // Run the viewer app with the results
  665. TCHAR szCurDir[_MAX_PATH + 1];
  666. ::GetCurrentDirectory(_countof(szCurDir), szCurDir);
  667. ::ShellExecute(GetDesktopWindow(), NULL, m_szViewer, m_szLogFileName, szCurDir, SW_SHOWMAXIMIZED);
  668. ClearChildren();
  669. return 0;
  670. }
  671. //+-----------------------------------------------------------------------
  672. //
  673. // Member: CCtlPerfView::OnSuite2
  674. //
  675. // Synopsis: IDM_SUITE2 handler: create and run two passes
  676. //
  677. //------------------------------------------------------------------------
  678. LRESULT CCtlPerfView::OnSuite2(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
  679. {
  680. m_bTwoPasses = true;
  681. if (!m_bBatch)
  682. {
  683. COptionsDialog dlg(this);
  684. INT_PTR nRes = dlg.DoModal();
  685. if (nRes == IDCANCEL)
  686. return 0;
  687. // Reset the WS_MAXIMIZE style to set the parent to the new size, via WM_GETMINMAXINFO
  688. ::SetWindowLong(GetParent(), GWL_STYLE, ::GetWindowLong(GetParent(), GWL_STYLE) & ~WS_MAXIMIZE);
  689. ::ShowWindow(GetParent(), SW_MAXIMIZE);
  690. }
  691. m_perfLog.StartLoggingTwoPasses(m_szLogFileName, m_hWndStatusBar, m_szPass1, m_szPass2);
  692. RunSuite();
  693. m_perfLog.StopLoggingPass1();
  694. ClearChildren();
  695. if (m_bSilent
  696. || (IDOK == ::MessageBox(GetParent(),
  697. _T("Ready to run pass 2, press OK after changing Theme settings."),
  698. _T("CtlPerf"),
  699. MB_OKCANCEL)))
  700. {
  701. m_perfLog.StartLoggingPass2();
  702. RunSuite();
  703. m_perfLog.StopLoggingPass2();
  704. if (m_bSilent)
  705. {
  706. ::PostMessage(GetParent(), WM_CLOSE, 0, 0);
  707. }
  708. }
  709. m_perfLog.StopLogging();
  710. // Run the viewer app with the results
  711. TCHAR szCurDir[_MAX_PATH + 1];
  712. ::GetCurrentDirectory(_countof(szCurDir), szCurDir);
  713. ::ShellExecute(GetDesktopWindow(), NULL, m_szViewer, m_szLogFileName, szCurDir, SW_SHOWMAXIMIZED);
  714. ClearChildren();
  715. return 0;
  716. }
  717. //+-----------------------------------------------------------------------
  718. //
  719. // Member: CCtlPerfView::OnBatch1
  720. //
  721. // Synopsis: IDM_BATCH1 handler: create and run one pass in non-interactive mode
  722. //
  723. //------------------------------------------------------------------------
  724. LRESULT CCtlPerfView::OnBatch1(WORD /*wNotifyCode*/, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/)
  725. {
  726. m_bBatch = true;
  727. // Override the log file name
  728. if((LPTSTR) hWndCtl)
  729. _tcscpy(m_szLogFileName, (LPTSTR) hWndCtl);
  730. // Simulate a menu selection, but with m_bBatch to true, and exit
  731. PostMessage(WM_COMMAND, IDM_SUITE1, 0);
  732. ::PostMessage(GetParent(), WM_CLOSE, 0, 0);
  733. return 0;
  734. }
  735. //+-----------------------------------------------------------------------
  736. //
  737. // Member: CCtlPerfView::OnBatch2
  738. //
  739. // Synopsis: IDM_BATCH2 handler: create and run two passes in non-interactive mode
  740. //
  741. //------------------------------------------------------------------------
  742. LRESULT CCtlPerfView::OnBatch2(WORD /*wNotifyCode*/, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/)
  743. {
  744. m_bBatch = true;
  745. m_bSilent = false;
  746. // Override the log file name
  747. if((LPTSTR) hWndCtl)
  748. _tcscpy(m_szLogFileName, (LPTSTR) hWndCtl);
  749. PostMessage(WM_COMMAND, IDM_SUITE2, 0);
  750. // We'll let the pause message box post the WM_CLOSE
  751. return 0;
  752. }
  753. //+-----------------------------------------------------------------------
  754. //
  755. // Member: CCtlPerfView::OnBatch3
  756. //
  757. // Synopsis: IDM_BATCH3 handler: create and run two passes in non-interactive mode,
  758. // without pause
  759. //
  760. //------------------------------------------------------------------------
  761. LRESULT CCtlPerfView::OnBatch3(WORD /*wNotifyCode*/, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/)
  762. {
  763. m_bBatch = true;
  764. m_bSilent = true;
  765. // Override the log file name
  766. if((LPTSTR) hWndCtl)
  767. _tcscpy(m_szLogFileName, (LPTSTR) hWndCtl);
  768. PostMessage(WM_COMMAND, IDM_SUITE2, 0);
  769. ::PostMessage(GetParent(), WM_CLOSE, 0, 0);
  770. return 0;
  771. }
  772. ////////////////////////////////////////////////////////////////////////////
  773. // CCtlPerfView::COptionsDialog
  774. //+-----------------------------------------------------------------------
  775. //
  776. // Member: CCtlPerfView::COptionsDialog::COptionsDialog
  777. //
  778. // Synopsis: Constructor
  779. //
  780. //------------------------------------------------------------------------
  781. CCtlPerfView::COptionsDialog::COptionsDialog(CCtlPerfView *pView)
  782. {
  783. m_pView = pView;
  784. }
  785. //+-----------------------------------------------------------------------
  786. //
  787. // Member: CCtlPerfView::COptionsDialog::OnInitDialog
  788. //
  789. // Synopsis: Pre-dialog
  790. //
  791. //------------------------------------------------------------------------
  792. LRESULT CCtlPerfView::COptionsDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  793. {
  794. DoDataExchange();
  795. // Call the base class to center
  796. thisClass::OnInitDialog(uMsg, wParam, lParam, bHandled);
  797. if(!m_pView->m_bTwoPasses)
  798. ::EnableWindow(GetDlgItem(IDC_EDIT_PASS2), FALSE);
  799. else
  800. ::EnableWindow(GetDlgItem(IDC_EDIT_PASS2), TRUE);
  801. ::SetFocus(GetDlgItem(IDC_EDIT_PASS1));
  802. return 0;
  803. }
  804. //+-----------------------------------------------------------------------
  805. //
  806. // Member: CCtlPerfView::COptionsDialog::OnInitDialog
  807. //
  808. // Synopsis: Post-dialog
  809. //
  810. //------------------------------------------------------------------------
  811. LRESULT CCtlPerfView::COptionsDialog::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled)
  812. {
  813. if(wID == IDOK)
  814. DoDataExchange(DDX_SAVE);
  815. bHandled = FALSE;
  816. return 0;
  817. }