Klasa CPerfStats

Autor: Krzysztof Kuczek

Klasa ta pierwotnie była opublikowana na www.codeguru.com dokładnie na http://codeguru.earthweb.com/system/perfstate.shtml i to jest szybkie tłumaczenie tegoż artykułu.

Klasa ta umożliwia zbieranie statystyk dotyczących wydajności systemu Windows 9x, takich jak zajęcie procesora, ilość pamięci, słowem tego wszystkiego co może pokazać System Monitor (sysmon.exe).

Aby jej użyć musisz stworzyć własną klasę która będzie dziedziczyć po CPerfStats.

class MyPerfStats : public CPerfStats  
{
public:
 MyPerfStats();
 virtual ~MyPerfStats();
 void OnHitCategory( CATEGORY_STRUCT * pCategory );
 void OnHitElement( ELEMENT_STRUCT * pElement );
}
W swojej klasie powinieneś zdefiniować dwie funcie: OnHitCategory() i OnHitElement().

Następnie możesz utworzyć obiekt twojej klasy i wywołać metodę EnumCategories().

MyPerfStats perf;
perf.EnumCategories();
W funkcji OnHitCategory() otrzymujesz wszystkie kategorie.
void MyPerfStats::OnHitCategory(CATEGORY_STRUCT*pCategory)
{
 pCategoryList->SetItemData( pCategoryList->AddString(
 pCategory->Name), (DWORD)pCategory ) ;
}
pCategoryList jest wskaźnikiem na ListBox'a, pCategory->Name jest nazwą kategorii, np. "Jądro" lub "System plików". Powinieneś zapamiętać pCategory po to aby później mieć dostęp do elementów kategori..

Teraz możesz przeglądać elementy danej kategorii.

void CPerfTestDlg::OnSelchangeListCategories()
{
 m_ElementsList.ResetContent();
 perf.EnumElements( (CATEGORY_STRUCT *)
 m_CategoriesList.GetItemData(
                   m_CategoriesList.GetCurSel()));
}
W funkcji OnHitElement() otrzymujesz wszystkie elementy danej kategorii.
void MyPerfStats::OnHitElement( ELEMENT_STRUCT * pElement )
{
 pElementList->SetItemData( pElementList->AddString(
                    pElement->Name), (DWORD)pElement );
}
pElementList jest wskaźnikiem na ListBox'a. pElement->Name jest nazwą elementu, np. "Wątki". Powinieneś zapamiętać pElement aby potem odczytać jego wartość.

Możesz pobrać opis danego elementu.

void CPerfTestDlg::OnSelchangeListElements()
{
 ELEMENT_STRUCT * pElement = (ELEMENT_STRUCT *)
 m_ElementsList.GetItemData(m_ElementsList.GetCurSel() );
 SetDlgItemText(IDC_STATIC_DESCRIPTION,
                pElement->Description);
}
oraz jego wartość
void CPerfTestDlg::OnTimer(UINT nIDEvent) 
{
 if ( m_ElementsList.GetCurSel() !=  LB_ERR )
 {
  ELEMENT_STRUCT * pElement = (ELEMENT_STRUCT *)
  m_ElementsList.GetItemData(m_ElementsList.GetCurSel() );
  DWORD value = perf.GetValue(pElement);
  if ( pElement->Differentiate   == FALSE )
  {
   SetDlgItemInt(IDC_STATIC_VALUE, value);
  }else
  {
   SetDlgItemInt(IDC_STATIC_VALUE,
                 (value - LastValue) / 1);
                 // 1 couse interval = 1000 ms = 1 s
   LastValue = value;
  }
 }else
 {
  SetDlgItemText(IDC_STATIC_VALUE, "");
 }
 CDialog::OnTimer(nIDEvent);
}
Co oznacza pElement->Differentiate?

Flaga ta mówi o tym, czy dana statystyka jest skumulowana czy nie. Jeżeli flaga ma wartość TRUE, wtedy statystyka jest cały czas zwiększana, i wartość o którą nam chodzi należy interpretować jako różnice pomiędzy kolejnymi odczytanymi wartościami podzieloną przez okres pomiędzy odczytami. Jeżeli wartość flagi jest FALSE, wtedy nie musimy przeprowadzać żadnych operacji.

Klasa zostala napisana pod MSVC

Źródło: perfstate_src.zip

Przykład wykorzystania: perfstate_demo.zip