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.

775 lines
21 KiB

  1. //
  2. // Driver Verifier UI
  3. // Copyright (c) Microsoft Corporation, 1999
  4. //
  5. //
  6. // module: CrtSPage.cxx
  7. // author: DMihai
  8. // created: 01/04/99
  9. //
  10. // Description:
  11. //
  12. // Current settings PropertyPage.
  13. #include "stdafx.h"
  14. #include "drvvctrl.hxx"
  15. #include "CrtSPage.hxx"
  16. #include "DrvCSht.hxx"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. #define MIN_MEM_SIZE_TO_DISABLE_WARNING 0x80000000 // 2 Gb
  23. #define MIN_ALLOCATIONS_SIGNIFICANT 100
  24. #define MIN_PERCENTAGE_AVOID_WARNING 95
  25. //
  26. // timer ID
  27. //
  28. #define REFRESH_TIMER_ID 0x1234
  29. //
  30. // manual, high, normal, low speed
  31. //
  32. #define REFRESH_SPEED_VARS 4
  33. //
  34. // timer intervals in millisec for manual, high, normal, low speed
  35. //
  36. static UINT uTimerIntervals[ REFRESH_SPEED_VARS ] =
  37. {
  38. 0, // Manual
  39. 1000, // High Speed
  40. 5000, // Normal Speed
  41. 10000 // Low Speed
  42. };
  43. //
  44. // help IDs
  45. //
  46. static DWORD MyHelpIds[] =
  47. {
  48. IDC_CRTSTAT_DRIVERS_LIST, IDH_DV_VolatileTab_driver_details,
  49. IDC_CRTSTAT_IRQLCHCK_EDIT, IDH_DV_StatusTab_flag_irql,
  50. IDC_CRTSTAT_FAULTINJ_EDIT, IDH_DV_StatusTab_flag_resource,
  51. IDC_CRTSTAT_POOLT_EDIT, IDH_DV_StatusTab_flag_tracking,
  52. IDC_CRTSTAT_IOVERIF_EDIT, IDH_DV_StatusTab_flag_io,
  53. IDC_CRTSTAT_SPECPOOL_EDIT, IDH_DV_StatusTab_flag_pool,
  54. IDC_CRTSTAT_REFRESH_BUTTON, IDH_DV_common_refresh_nowbutton,
  55. IDC_CRTSTAT_MANUAL_RADIO, IDH_DV_common_refresh_manual,
  56. IDC_CRTSTAT_HSPEED_RADIO, IDH_DV_common_refresh_high,
  57. IDC_CRTSTAT_NORM_RADIO, IDH_DV_common_refresh_normal,
  58. IDC_CRTSTAT_LOW_RADIO, IDH_DV_common_refresh_low,
  59. 0, 0
  60. };
  61. /////////////////////////////////////////////////////////////
  62. static void GetEnabledStringFromBool( BOOL bEnabled, CString &strValue )
  63. {
  64. if( bEnabled )
  65. VERIFY( strValue.LoadString( IDS_ENABLED ) );
  66. else
  67. VERIFY( strValue.LoadString( IDS_DISABLED ) );
  68. }
  69. /////////////////////////////////////////////////////////////
  70. // CCrtSettPage property page
  71. IMPLEMENT_DYNCREATE(CCrtSettPage, CPropertyPage)
  72. CCrtSettPage::CCrtSettPage() : CPropertyPage(CCrtSettPage::IDD)
  73. {
  74. //{{AFX_DATA_INIT(CCrtSettPage)
  75. m_strSpecPool = _T("");
  76. m_strIrqLevelCheckEdit = _T("");
  77. m_strFaultInjEdit = _T("");
  78. m_strPoolTrackEdit = _T("");
  79. m_strIoVerifEdit = _T("");
  80. m_strWarnMsg = _T("");
  81. m_nUpdateIntervalIndex = 2;
  82. //}}AFX_DATA_INIT
  83. m_bAscendDrvNameSort = FALSE;
  84. m_bAscendDrvStatusSort = FALSE;
  85. m_uTimerHandler = 0;
  86. m_nSortColumnIndex = 0;
  87. }
  88. CCrtSettPage::~CCrtSettPage()
  89. {
  90. }
  91. void CCrtSettPage::DoDataExchange(CDataExchange* pDX)
  92. {
  93. if( ! pDX->m_bSaveAndValidate )
  94. {
  95. // query the kernel
  96. if( KrnGetSystemVerifierState( &m_KrnVerifState ) &&
  97. m_KrnVerifState.DriverCount > 0 )
  98. {
  99. // SpecialPool
  100. GetEnabledStringFromBool( m_KrnVerifState.SpecialPool, m_strSpecPool );
  101. // IrqlChecking
  102. GetEnabledStringFromBool( m_KrnVerifState.IrqlChecking, m_strIrqLevelCheckEdit );
  103. // FaultInjection
  104. GetEnabledStringFromBool( m_KrnVerifState.FaultInjection, m_strFaultInjEdit );
  105. // PoolTrack
  106. GetEnabledStringFromBool( m_KrnVerifState.PoolTrack, m_strPoolTrackEdit );
  107. // IoVerif
  108. GetEnabledStringFromBool( m_KrnVerifState.IoVerif, m_strIoVerifEdit );
  109. // warning message
  110. GetPoolCoverageWarnMessage();
  111. }
  112. else
  113. {
  114. // SpecialPool
  115. VERIFY( m_strSpecPool.LoadString( IDS_DISABLED ) );
  116. // IrqlChecking
  117. VERIFY( m_strIrqLevelCheckEdit.LoadString( IDS_DISABLED ) );
  118. // FaultInjection
  119. VERIFY( m_strFaultInjEdit.LoadString( IDS_DISABLED ) );
  120. // PoolTrack
  121. VERIFY( m_strPoolTrackEdit.LoadString( IDS_DISABLED ) );
  122. //IoVerif
  123. VERIFY( m_strIoVerifEdit.LoadString( IDS_DISABLED ) );
  124. // warning message
  125. m_strWarnMsg.Empty();
  126. }
  127. }
  128. CPropertyPage::DoDataExchange(pDX);
  129. //{{AFX_DATA_MAP(CCrtSettPage)
  130. DDX_Control(pDX, IDC_CRTSTAT_DRIVERS_LIST, m_DriversList);
  131. DDX_Text(pDX, IDC_CRTSTAT_SPECPOOL_EDIT, m_strSpecPool);
  132. DDX_Text(pDX, IDC_CRTSTAT_IRQLCHCK_EDIT, m_strIrqLevelCheckEdit);
  133. DDX_Text(pDX, IDC_CRTSTAT_FAULTINJ_EDIT, m_strFaultInjEdit);
  134. DDX_Text(pDX,IDC_CRTSTAT_POOLT_EDIT, m_strPoolTrackEdit);
  135. DDX_Text(pDX,IDC_CRTSTAT_IOVERIF_EDIT, m_strIoVerifEdit);
  136. DDX_Text(pDX,IDC_CRTSTAT_WARN_MSG, m_strWarnMsg);
  137. DDX_Radio(pDX, IDC_CRTSTAT_MANUAL_RADIO, m_nUpdateIntervalIndex);
  138. //}}AFX_DATA_MAP
  139. }
  140. BEGIN_MESSAGE_MAP(CCrtSettPage, CPropertyPage)
  141. //{{AFX_MSG_MAP(CCrtSettPage)
  142. ON_BN_CLICKED(IDC_CRTSTAT_REFRESH_BUTTON, OnCrtstatRefreshButton)
  143. ON_NOTIFY(LVN_COLUMNCLICK, IDC_CRTSTAT_DRIVERS_LIST, OnColumnclickCrtstatDriversList)
  144. ON_WM_TIMER()
  145. ON_BN_CLICKED(IDC_CRTSTAT_HSPEED_RADIO, OnCrtstatHspeedRadio)
  146. ON_BN_CLICKED(IDC_CRTSTAT_LOW_RADIO, OnCrtstatLowRadio)
  147. ON_BN_CLICKED(IDC_CRTSTAT_MANUAL_RADIO, OnCrtstatManualRadio)
  148. ON_BN_CLICKED(IDC_CRTSTAT_NORM_RADIO, OnCrtstatNormRadio)
  149. ON_MESSAGE( WM_HELP, OnHelp )
  150. ON_MESSAGE( WM_CONTEXTMENU, OnContextMenu )
  151. //}}AFX_MSG_MAP
  152. END_MESSAGE_MAP()
  153. /////////////////////////////////////////////////////////////
  154. void CCrtSettPage::SetupListHeader()
  155. {
  156. CString strDrivers, strStatus;
  157. VERIFY( strDrivers.LoadString( IDS_DRIVERS ) );
  158. VERIFY( strStatus.LoadString( IDS_STATUS ) );
  159. // list's regtangle
  160. CRect rectWnd;
  161. m_DriversList.GetClientRect( &rectWnd );
  162. LVCOLUMN lvColumn;
  163. // column 0
  164. memset( &lvColumn, 0, sizeof( lvColumn ) );
  165. lvColumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  166. lvColumn.fmt = LVCFMT_LEFT;
  167. lvColumn.iSubItem = 0;
  168. lvColumn.pszText = strDrivers.GetBuffer( strDrivers.GetLength() + 1 );
  169. lvColumn.cx = (int)( rectWnd.Width() * 0.47 );
  170. VERIFY( m_DriversList.InsertColumn( 0, &lvColumn ) != -1 );
  171. strDrivers.ReleaseBuffer();
  172. // column 1
  173. lvColumn.iSubItem = 1;
  174. lvColumn.pszText = strStatus.GetBuffer( strStatus.GetLength() + 1 );
  175. lvColumn.cx = (int)( rectWnd.Width() * 0.47 );
  176. VERIFY( m_DriversList.InsertColumn( 1, &lvColumn ) != -1 );
  177. strStatus.ReleaseBuffer();
  178. }
  179. /////////////////////////////////////////////////////////////
  180. void CCrtSettPage::FillTheList()
  181. {
  182. LVITEM lvItem;
  183. int nActualIndex;
  184. BOOL *pbAlreadyInList;
  185. ULONG uCrtVerifiedDriver;
  186. int nItemCount;
  187. int nCrtListItem;
  188. TCHAR strDriverName[ _MAX_PATH ];
  189. BOOL bResult;
  190. if( m_KrnVerifState.DriverCount == 0 )
  191. {
  192. //
  193. // clear the list
  194. //
  195. VERIFY( m_DriversList.DeleteAllItems() );
  196. }
  197. else
  198. {
  199. //
  200. // there are some drivers currently verified
  201. //
  202. pbAlreadyInList = new BOOL[ m_KrnVerifState.DriverCount ];
  203. if( pbAlreadyInList == NULL )
  204. {
  205. return;
  206. }
  207. for( uCrtVerifiedDriver = 0; uCrtVerifiedDriver < m_KrnVerifState.DriverCount; uCrtVerifiedDriver++)
  208. {
  209. pbAlreadyInList[ uCrtVerifiedDriver ] = FALSE;
  210. }
  211. //
  212. // parse all the current list items
  213. //
  214. nItemCount = m_DriversList.GetItemCount();
  215. for( nCrtListItem = 0; nCrtListItem < nItemCount; nCrtListItem++ )
  216. {
  217. //
  218. // get the current driver's name from the list
  219. //
  220. ZeroMemory( &lvItem, sizeof( lvItem ) );
  221. lvItem.mask = LVIF_TEXT;
  222. lvItem.iItem = nCrtListItem;
  223. lvItem.iSubItem = 0;
  224. lvItem.pszText = strDriverName;
  225. lvItem.cchTextMax = sizeof( strDriverName ) / sizeof( strDriverName[0] );
  226. bResult = m_DriversList.GetItem( &lvItem );
  227. if( bResult == FALSE )
  228. {
  229. //
  230. // could not get the current item's attributes?
  231. //
  232. ASSERT( FALSE );
  233. //
  234. // remove this item from the list
  235. //
  236. VERIFY( m_DriversList.DeleteItem( nCrtListItem ) );
  237. nCrtListItem--;
  238. nItemCount--;
  239. }
  240. else
  241. {
  242. //
  243. // see is the current driver is still in m_KrnVerifState
  244. //
  245. for( uCrtVerifiedDriver = 0; uCrtVerifiedDriver < m_KrnVerifState.DriverCount; uCrtVerifiedDriver++)
  246. {
  247. if( _tcsicmp( strDriverName,
  248. m_KrnVerifState.DriverInfo[ uCrtVerifiedDriver ].Name ) == 0 )
  249. {
  250. //
  251. // update the item's data with the current index in the array
  252. //
  253. lvItem.mask = LVIF_PARAM;
  254. lvItem.lParam = uCrtVerifiedDriver;
  255. VERIFY( m_DriversList.SetItem( &lvItem ) != -1 );
  256. //
  257. // update the second column
  258. //
  259. UpdateStatusColumn( nCrtListItem, uCrtVerifiedDriver );
  260. //
  261. // mark the current driver as updated
  262. //
  263. pbAlreadyInList[ uCrtVerifiedDriver ] = TRUE;
  264. break;
  265. }
  266. }
  267. //
  268. // If the driver is no longer verified, remove it from the list
  269. //
  270. if( uCrtVerifiedDriver >= m_KrnVerifState.DriverCount )
  271. {
  272. VERIFY( m_DriversList.DeleteItem( nCrtListItem ) );
  273. nCrtListItem--;
  274. nItemCount--;
  275. }
  276. }
  277. }
  278. //
  279. // add the drivers that were not in the list before this update
  280. //
  281. for( uCrtVerifiedDriver = 0; uCrtVerifiedDriver < m_KrnVerifState.DriverCount; uCrtVerifiedDriver++)
  282. {
  283. if( ! pbAlreadyInList[ uCrtVerifiedDriver ] )
  284. {
  285. //
  286. // add a new item for this
  287. //
  288. ZeroMemory( &lvItem, sizeof( lvItem ) );
  289. //
  290. // sub-item 0
  291. //
  292. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  293. lvItem.lParam = uCrtVerifiedDriver;
  294. lvItem.iItem = m_DriversList.GetItemCount();
  295. lvItem.iSubItem = 0;
  296. lvItem.pszText = m_KrnVerifState.DriverInfo[ uCrtVerifiedDriver ].Name;
  297. nActualIndex = m_DriversList.InsertItem( &lvItem );
  298. VERIFY( nActualIndex != -1 );
  299. //
  300. // sub-item 1
  301. //
  302. UpdateStatusColumn( nActualIndex, uCrtVerifiedDriver );
  303. }
  304. }
  305. delete pbAlreadyInList;
  306. }
  307. }
  308. /////////////////////////////////////////////////////////////
  309. void CCrtSettPage::UpdateStatusColumn( int nItemIndex, ULONG uCrtDriver )
  310. {
  311. LVITEM lvItem;
  312. CString strStatus;
  313. ASSERT( nItemIndex >= 0 &&
  314. (UINT)nItemIndex < m_KrnVerifState.DriverCount &&
  315. nItemIndex < m_DriversList.GetItemCount() &&
  316. uCrtDriver >= 0 &&
  317. uCrtDriver < m_KrnVerifState.DriverCount &&
  318. uCrtDriver < (ULONG)m_DriversList.GetItemCount() );
  319. // determine what's the appropriate value for the second column
  320. if( ! m_KrnVerifState.DriverInfo[ uCrtDriver ].Loads )
  321. {
  322. VERIFY( strStatus.LoadString( IDS_NEVER_LOADED ) );
  323. }
  324. else
  325. {
  326. if( m_KrnVerifState.DriverInfo[ uCrtDriver ].Loads ==
  327. m_KrnVerifState.DriverInfo[ uCrtDriver ].Unloads )
  328. {
  329. VERIFY( strStatus.LoadString( IDS_UNLOADED ) );
  330. }
  331. else
  332. {
  333. if( m_KrnVerifState.DriverInfo[ uCrtDriver ].Loads >
  334. m_KrnVerifState.DriverInfo[ uCrtDriver ].Unloads )
  335. {
  336. VERIFY( strStatus.LoadString( IDS_LOADED ) );
  337. }
  338. else
  339. {
  340. ASSERT( FALSE );
  341. VERIFY( strStatus.LoadString( IDS_UNKNOWN ) );
  342. }
  343. }
  344. }
  345. // update the list item
  346. memset( &lvItem, 0, sizeof( lvItem ) );
  347. lvItem.mask = LVIF_TEXT;
  348. lvItem.iItem = nItemIndex;
  349. lvItem.iSubItem = 1;
  350. lvItem.pszText = strStatus.GetBuffer( strStatus.GetLength() + 1 );
  351. VERIFY( m_DriversList.SetItem( &lvItem ) != -1 );
  352. strStatus.ReleaseBuffer();
  353. }
  354. /////////////////////////////////////////////////////////////
  355. int CALLBACK CCrtSettPage::DrvStatusCmpFunc(
  356. LPARAM lParam1,
  357. LPARAM lParam2,
  358. LPARAM lParamSort)
  359. {
  360. UINT uIndex1 = (UINT)lParam1;
  361. UINT uIndex2 = (UINT)lParam2;
  362. CCrtSettPage *pThis = (CCrtSettPage *)lParamSort;
  363. ASSERT_VALID( pThis );
  364. int nCmpRez = 0;
  365. // sanity check
  366. if( uIndex1 > pThis->m_KrnVerifState.DriverCount ||
  367. uIndex2 > pThis->m_KrnVerifState.DriverCount )
  368. {
  369. ASSERT( FALSE );
  370. return 0;
  371. }
  372. // difference between loads and unloads #
  373. LONG lLoadDiff1 = (LONG)pThis->m_KrnVerifState.DriverInfo[ uIndex1 ].Loads -
  374. (LONG)pThis->m_KrnVerifState.DriverInfo[ uIndex1 ].Unloads;
  375. LONG lLoadDiff2 = (LONG)pThis->m_KrnVerifState.DriverInfo[ uIndex2 ].Loads -
  376. (LONG)pThis->m_KrnVerifState.DriverInfo[ uIndex2 ].Unloads;
  377. if( lLoadDiff1 == lLoadDiff2 )
  378. {
  379. nCmpRez = 0;
  380. }
  381. else
  382. {
  383. if( lLoadDiff1 > lLoadDiff2 )
  384. nCmpRez = 1;
  385. else
  386. nCmpRez = -1;
  387. }
  388. if( pThis->m_bAscendDrvStatusSort )
  389. nCmpRez *= -1;
  390. return nCmpRez;
  391. }
  392. /////////////////////////////////////////////////////////////
  393. int CALLBACK CCrtSettPage::DrvNameCmpFunc(
  394. LPARAM lParam1,
  395. LPARAM lParam2,
  396. LPARAM lParamSort)
  397. {
  398. UINT uIndex1 = (UINT)lParam1;
  399. UINT uIndex2 = (UINT)lParam2;
  400. CCrtSettPage *pThis = (CCrtSettPage *)lParamSort;
  401. ASSERT_VALID( pThis );
  402. int nCmpRez = 0;
  403. // sanity check
  404. if( uIndex1 > pThis->m_KrnVerifState.DriverCount ||
  405. uIndex2 > pThis->m_KrnVerifState.DriverCount )
  406. {
  407. ASSERT( FALSE );
  408. return 0;
  409. }
  410. nCmpRez = _tcsicmp( pThis->m_KrnVerifState.DriverInfo[ uIndex1 ].Name,
  411. pThis->m_KrnVerifState.DriverInfo[ uIndex2 ].Name );
  412. if( ! nCmpRez )
  413. {
  414. // same name ???
  415. nCmpRez = 0;
  416. }
  417. else
  418. {
  419. if( pThis->m_bAscendDrvNameSort )
  420. nCmpRez *= -1;
  421. }
  422. return nCmpRez;
  423. }
  424. /////////////////////////////////////////////////////////////
  425. void CCrtSettPage::OnRefreshTimerChanged()
  426. {
  427. UINT uTimerElapse = 0;
  428. // kill the pending timer
  429. if( m_uTimerHandler != 0 )
  430. {
  431. VERIFY( KillTimer( REFRESH_TIMER_ID ) );
  432. }
  433. // sanity check
  434. if( m_nUpdateIntervalIndex < 0 ||
  435. m_nUpdateIntervalIndex >= REFRESH_SPEED_VARS )
  436. {
  437. m_nUpdateIntervalIndex = 0;
  438. CheckRadioButton( IDC_CRTSTAT_MANUAL_RADIO, IDC_CRTSTAT_LOW_RADIO,
  439. IDC_CRTSTAT_MANUAL_RADIO );
  440. }
  441. // new timer interval
  442. uTimerElapse = uTimerIntervals[ m_nUpdateIntervalIndex ];
  443. if( uTimerElapse > 0 )
  444. {
  445. VERIFY( m_uTimerHandler = SetTimer( REFRESH_TIMER_ID,
  446. uTimerElapse, NULL ) );
  447. }
  448. }
  449. /////////////////////////////////////////////////////////////
  450. void CCrtSettPage::SortTheList()
  451. {
  452. if( m_nSortColumnIndex )
  453. {
  454. m_DriversList.SortItems( DrvStatusCmpFunc, (LPARAM)this );
  455. }
  456. else
  457. {
  458. m_DriversList.SortItems( DrvNameCmpFunc, (LPARAM)this );
  459. }
  460. }
  461. /////////////////////////////////////////////////////////////
  462. void CCrtSettPage::GetPoolCoverageWarnMessage()
  463. {
  464. ULONGLONG ullPercentageCoverage;
  465. CString strMsgFormat;
  466. if( m_KrnVerifState.SpecialPool &&
  467. m_KrnVerifState.AllocationsSucceeded > MIN_ALLOCATIONS_SIGNIFICANT )
  468. {
  469. //
  470. // special pool verification is enabled
  471. // there is a significant number of allocations
  472. //
  473. ASSERT( m_KrnVerifState.AllocationsSucceeded >= m_KrnVerifState.AllocationsSucceededSpecialPool );
  474. //
  475. // the coverage percentage
  476. //
  477. ullPercentageCoverage =
  478. ( (ULONGLONG)m_KrnVerifState.AllocationsSucceededSpecialPool * (ULONGLONG) 100 ) /
  479. (ULONGLONG)m_KrnVerifState.AllocationsSucceeded;
  480. ASSERT( ullPercentageCoverage <= 100 );
  481. if( ullPercentageCoverage < MIN_PERCENTAGE_AVOID_WARNING )
  482. {
  483. //
  484. // warn the user
  485. //
  486. if( strMsgFormat.LoadString( IDS_COVERAGE_WARNING_FORMAT ) )
  487. {
  488. TCHAR *strMessage = m_strWarnMsg.GetBuffer( strMsgFormat.GetLength() + 32 );
  489. if( strMessage != NULL )
  490. {
  491. _stprintf( strMessage, (LPCTSTR)strMsgFormat, ullPercentageCoverage );
  492. m_strWarnMsg.ReleaseBuffer();
  493. return;
  494. }
  495. }
  496. else
  497. {
  498. ASSERT( FALSE );
  499. }
  500. }
  501. }
  502. //
  503. // no warning message
  504. //
  505. m_strWarnMsg.Empty();
  506. }
  507. /////////////////////////////////////////////////////////////
  508. // CCrtSettPage message handlers
  509. BOOL CCrtSettPage::OnInitDialog()
  510. {
  511. CPropertyPage::OnInitDialog();
  512. SetupListHeader();
  513. FillTheList();
  514. SortTheList();
  515. OnRefreshTimerChanged();
  516. return TRUE; // return TRUE unless you set the focus to a control
  517. // EXCEPTION: OCX Property Pages should return FALSE
  518. }
  519. /////////////////////////////////////////////////////////////
  520. void CCrtSettPage::OnCrtstatRefreshButton()
  521. {
  522. if( UpdateData( FALSE ) )
  523. {
  524. FillTheList();
  525. SortTheList();
  526. }
  527. }
  528. /////////////////////////////////////////////////////////////
  529. void CCrtSettPage::OnColumnclickCrtstatDriversList(NMHDR* pNMHDR,
  530. LRESULT* pResult)
  531. {
  532. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  533. if( pNMListView->iSubItem )
  534. {
  535. if( m_nSortColumnIndex == pNMListView->iSubItem )
  536. {
  537. // change the current ascend/descend order for this column
  538. m_bAscendDrvStatusSort = !m_bAscendDrvStatusSort;
  539. }
  540. }
  541. else
  542. {
  543. if( m_nSortColumnIndex == pNMListView->iSubItem )
  544. {
  545. // change the current ascend/descend order for this column
  546. m_bAscendDrvNameSort = !m_bAscendDrvNameSort;
  547. }
  548. }
  549. m_nSortColumnIndex = pNMListView->iSubItem;
  550. SortTheList();
  551. *pResult = 0;
  552. }
  553. /////////////////////////////////////////////////////////////
  554. void CCrtSettPage::OnTimer(UINT nIDEvent)
  555. {
  556. if( nIDEvent == REFRESH_TIMER_ID )
  557. {
  558. CDrvChkSheet *pParentSheet = (CDrvChkSheet *)GetParent();
  559. if( pParentSheet != NULL )
  560. {
  561. ASSERT_VALID( pParentSheet );
  562. if( pParentSheet->GetActivePage() == this )
  563. {
  564. // refresh the displayed data
  565. OnCrtstatRefreshButton();
  566. }
  567. }
  568. }
  569. CPropertyPage::OnTimer(nIDEvent);
  570. }
  571. /////////////////////////////////////////////////////////////
  572. BOOL CCrtSettPage::OnQueryCancel()
  573. {
  574. // give parent PropertySheet a chance to refuse the Cancel if needed
  575. CDrvChkSheet *pParentSheet = (CDrvChkSheet *)GetParent();
  576. if( pParentSheet != NULL )
  577. {
  578. ASSERT_VALID( pParentSheet );
  579. if( ! pParentSheet->OnQueryCancel() )
  580. {
  581. return FALSE;
  582. }
  583. }
  584. return CPropertyPage::OnQueryCancel();
  585. }
  586. /////////////////////////////////////////////////////////////
  587. BOOL CCrtSettPage::OnApply()
  588. {
  589. // refuse to apply
  590. // (we don't use the standard PropertSheet buttons; Apply, OK)
  591. return FALSE;
  592. }
  593. /////////////////////////////////////////////////////////////
  594. void CCrtSettPage::OnCrtstatManualRadio()
  595. {
  596. // switch to manual refresh
  597. m_nUpdateIntervalIndex = 0;
  598. OnRefreshTimerChanged();
  599. }
  600. void CCrtSettPage::OnCrtstatHspeedRadio()
  601. {
  602. // switch to high speed refresh
  603. m_nUpdateIntervalIndex = 1;
  604. OnRefreshTimerChanged();
  605. }
  606. void CCrtSettPage::OnCrtstatNormRadio()
  607. {
  608. // switch to normal speed refresh
  609. m_nUpdateIntervalIndex = 2;
  610. OnRefreshTimerChanged();
  611. }
  612. void CCrtSettPage::OnCrtstatLowRadio()
  613. {
  614. // switch to low speed refresh
  615. m_nUpdateIntervalIndex = 3;
  616. OnRefreshTimerChanged();
  617. }
  618. /////////////////////////////////////////////////////////////
  619. LONG CCrtSettPage::OnHelp( WPARAM wParam, LPARAM lParam )
  620. {
  621. LONG lResult = 0;
  622. LPHELPINFO lpHelpInfo = (LPHELPINFO)lParam;
  623. ::WinHelp(
  624. (HWND) lpHelpInfo->hItemHandle,
  625. VERIFIER_HELP_FILE,
  626. HELP_WM_HELP,
  627. (DWORD_PTR) MyHelpIds );
  628. return lResult;
  629. }
  630. /////////////////////////////////////////////////////////////
  631. LONG CCrtSettPage::OnContextMenu( WPARAM wParam, LPARAM lParam )
  632. {
  633. LONG lResult = 0;
  634. ::WinHelp(
  635. (HWND) wParam,
  636. VERIFIER_HELP_FILE,
  637. HELP_CONTEXTMENU,
  638. (DWORD_PTR) MyHelpIds );
  639. return lResult;
  640. }