NNN7
Интересующийся
Offline
|
|
« : 06-05-2014 21:21 » |
|
Здравствуйте . Нужно определить значение основных счётчиков продуктивности . Это у меня получилось ( использовал PDH) . При выборе имени счётчика его значение заносится в ListBox. Возник такой вопрос :а как сделать , чтобы выводимые значения обновлялись как-то ? сами или по нажатию кнопки .. Думаю,думаю..никак не могу сообразить . Пробовал установить таймер : #include <Windows.h> #include "resource.h" #include <string.h> #include <pdh.h> #include <pdhmsg.h> #include <iostream> #include <stdio.h> using namespace std; #pragma comment(lib, "pdh.lib") HWND CB,LB; wchar_t str [51]; //буфер TCHAR buf[20] = {0}; //для вывода TCHAR buf2 [20] ={0}; PDH_STATUS Status; PDH_STATUS Status2; HQUERY Query2=NULL; HQUERY Query = NULL; HCOUNTER Counter; DWORD CounterType; PDH_FMT_COUNTERVALUE DisplayValue; HCOUNTER Counter2; DWORD CounterType2; PDH_FMT_COUNTERVALUE DisplayValue2;
BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM );
//главня функция int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow) { //создание диалогового окна главным окном int db; db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc); } BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar ) { switch (uMsg) { case WM_COMMAND: //Если нажата кнопка Quit, тозакрываем окно if (LOWORD(wpar)==QUIT) { EndDialog(hwnd,NULL); KillTimer(hwnd,1); return TRUE; }
if(LOWORD(wpar)==SELECT) { GetDlgItemText(hwnd,COMBO,(LPSTR)str,51); if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0) { sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf); }
if(lstrcmp((LPCSTR)str,"% User time") == 0) { sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2); } } break;
case WM_TIMER: //проделываем :
if(LOWORD(wpar)==SELECT) { GetDlgItemText(hwnd,COMBO,(LPSTR)str,51); if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0) { sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf); }
if(lstrcmp((LPCSTR)str,"% User time") == 0) { sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2); } }
break;
case WM_INITDIALOG:
/*Создание таймера!*/ SetTimer(hwnd,1,3000,NULL); //таймер на каждые 3 секунды
//Создаём список счётчиков производительности CB=GetDlgItem(hwnd,COMBO); //Заносим возможные варианты счётчиков SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time"); SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time"); SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time"); //Создаём список для вывода значения счётчиков LB=GetDlgItem(hwnd,LIST); //Создать запрос Status = PdhOpenQueryW(NULL, 0, &Query); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query){PdhCloseQuery(Query);}
//НОВЫЙ ЗАПРОС!!! Status2 = PdhOpenQueryW(NULL, 0, &Query2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query2){PdhCloseQuery(Query2);} } return 0; } Установил SetTimer(), а в WM_TIME проделывал действия . При выходе — убиваем таймер . Но что-то оно не то . Подскажите , пожалуйста , как это доделать ? Заранее спасибо за помощь .
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #1 : 06-05-2014 22:05 » |
|
Но что-то оно не то Как выглядит "не то" и как должно выглядеть "то"? Насколько я понял, счётчики тут вообще к проблеме ListBox не относятся. Ты хочешь некий "обновляемый" ListBox. Вот и опиши подробно, как он должен выглядеть.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
NNN7
Интересующийся
Offline
|
|
« Ответ #2 : 07-05-2014 06:05 » |
|
Да, извините , что неполно всё описал . У меня всё выглядит так : создаётся комбобокс с вариантами счётчиков , при выборе одного из вариантов его значение заносится в листбокс . Вот код без таймера: #include <Windows.h> #include "resource.h" #include <string.h> #include <pdh.h> #include <pdhmsg.h> #include <iostream> #include <stdio.h> using namespace std; #pragma comment(lib, "pdh.lib") HWND CB,LB; wchar_t str [51]; //буфер TCHAR buf[20] = {0}; //для вывода TCHAR buf2 [20] ={0}; PDH_STATUS Status; PDH_STATUS Status2; HQUERY Query2=NULL; HQUERY Query = NULL; HCOUNTER Counter; DWORD CounterType; PDH_FMT_COUNTERVALUE DisplayValue; HCOUNTER Counter2; DWORD CounterType2; PDH_FMT_COUNTERVALUE DisplayValue2;
BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM );
//главня функция int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow) { //создание диалогового окна главным окном int db; db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc); } BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar ) { switch (uMsg) { case WM_COMMAND: //Если нажата кнопка Quit, тозакрываем окно if (LOWORD(wpar)==QUIT) { EndDialog(hwnd,NULL); return TRUE; }
if(LOWORD(wpar)==SELECT) { GetDlgItemText(hwnd,COMBO,(LPSTR)str,51); if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0) { sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf); }
if(lstrcmp((LPCSTR)str,"% User time") == 0) { sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2); } } break;
case WM_INITDIALOG:
//Создаём список счётчиков производительности CB=GetDlgItem(hwnd,COMBO); //Заносим возможные варианты счётчиков SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time"); SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time"); SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time"); //Создаём список для вывода значения счётчиков LB=GetDlgItem(hwnd,LIST); //Создать запрос Status = PdhOpenQueryW(NULL, 0, &Query); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query){PdhCloseQuery(Query);}
//НОВЫЙ ЗАПРОС!!! Status2 = PdhOpenQueryW(NULL, 0, &Query2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query2){PdhCloseQuery(Query2);} } return 0; } Но так как значение счётчиков обновляется постоянно- нужно выводить новые значения в листбокс , например , каждые 3 секунды . Для этого пробовал установить таймер , но ничего абсолютно не поменялось . Помогите , пожалуйста , что в этом случае делать ?
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #3 : 07-05-2014 08:54 » |
|
NNN7, ну тут два варианта: - удалить из ListBox старые элементы и добавить новые; - сделать такие элементы, ссылки на которые ты где-то хранишь, и рассматривать их как буфера, куда записывать новые строчки.
Первый способ проще и безопаснее. Потому что есть хитрости с копированием строк в момент добавления, и для подключения собственных буферов нужна особая инициализация.
Как ты используешь LB_ADDSTRING, так не сложно использовать и LB_DELETESTRING...
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
NNN7
Интересующийся
Offline
|
|
« Ответ #4 : 07-05-2014 16:11 » |
|
Спасибо за ответ . Попробовал 1-ый вариант . Создал функцию func() , в которой очищаю листбокс и снова нахожу значения счётчиков ( просто вставил текст с WM_INITDIALOG). А в WM_TIMER вызвал эту функцию . Но неправильно сделал , не пойму , почему . Можете , пожалуйста , помочь , как это правильно сделать ? Вот код мой : #include <Windows.h> #include "resource.h" #include <string.h> #include <pdh.h> #include <pdhmsg.h> #include <iostream> #include <stdio.h> using namespace std; #pragma comment(lib, "pdh.lib") HWND CB,LB; int func(HWND hwnd);
wchar_t str [51]; //буфер TCHAR buf[20] = {0}; //для вывода TCHAR buf2 [20] ={0}; PDH_STATUS Status; PDH_STATUS Status2; HQUERY Query2=NULL; HQUERY Query = NULL; HCOUNTER Counter; DWORD CounterType; PDH_FMT_COUNTERVALUE DisplayValue; HCOUNTER Counter2; DWORD CounterType2; PDH_FMT_COUNTERVALUE DisplayValue2;
BOOL WINAPI WndProc (HWND ,UINT ,WPARAM ,LPARAM );
//главня функция int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,LPSTR CmdLine,int CmdShow) { //создание диалогового окна главным окном int db; db=DialogBox (hInst,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),WndProc); } BOOL WINAPI WndProc (HWND hwnd,UINT uMsg,WPARAM wpar,LPARAM lpar ) { switch (uMsg) { case WM_COMMAND: //Если нажата кнопка Quit, тозакрываем окно if (LOWORD(wpar)==QUIT) { EndDialog(hwnd,NULL); KillTimer(hwnd,1); return TRUE; }
if(LOWORD(wpar)==SELECT) { GetDlgItemText(hwnd,COMBO,(LPSTR)str,51); if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0) { sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf); }
if(lstrcmp((LPCSTR)str,"% User time") == 0) { sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2); } } break;
case WM_TIMER: func(hwnd);
case WM_INITDIALOG: //установка таймера SetTimer(hwnd,1,1000,NULL); //Создаём список счётчиков производительности CB=GetDlgItem(hwnd,COMBO); //Заносим возможные варианты счётчиков SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% User time"); SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Processor time"); SendMessage(CB, CB_ADDSTRING, 0, (LPARAM)"% Privileged Time"); //Создаём список для вывода значения счётчиков LB=GetDlgItem(hwnd,LIST); //Создать запрос Status = PdhOpenQueryW(NULL, 0, &Query); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query){PdhCloseQuery(Query);}
//НОВЫЙ ЗАПРОС!!! Status2 = PdhOpenQueryW(NULL, 0, &Query2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query2){PdhCloseQuery(Query2);} } return 0; }
//функция int func(HWND hwnd) {
//Создаём LB=GetDlgItem(hwnd,LIST); //очищаем : SendMessage(LB, LB_RESETCONTENT, 0, 0); //Создать запрос Status = PdhOpenQueryW(NULL, 0, &Query); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query){PdhCloseQuery(Query);}
//НОВЫЙ ЗАПРОС!!! Status2 = PdhOpenQueryW(NULL, 0, &Query2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query2){PdhCloseQuery(Query2);}
}
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #5 : 07-05-2014 16:44 » |
|
NNN7, ну ты как-нибудь объясняй сразу, что именно ты считаешь неправильным. Лично меня смущает, что у тебя результаты записываются в переменные Status и Status2, последующие успешные счётчики затирают результаты предыдущих успешных, и, главное, всё это не преобразуется в строки и ни в какой ListBox не добавляется. Да ещё зачем-то всюду Sleep стоит, что внутри обработчика таймера явно неуместно.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
NNN7
Интересующийся
Offline
|
|
« Ответ #6 : 07-05-2014 16:56 » |
|
Да , Вы правы . Забыл добавить результаты в ListBox. Переписал функцию func(): //функция int func(HWND hwnd) { //Создаём LB=GetDlgItem(hwnd,LIST); //очищаем : SendMessage(LB, LB_RESETCONTENT, 0, 0); //Создать запрос Status = PdhOpenQueryW(NULL, 0, &Query); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status = PdhAddEnglishCounterW(Query, L"\\Processor(_Total)\\% Privileged Time", 0, &Counter); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status = PdhCollectQueryData(Query); if (Status != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status = PdhGetFormattedCounterValue(Counter,PDH_FMT_DOUBLE,&CounterType,&DisplayValue); if(Status!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query){PdhCloseQuery(Query);}
//НОВЫЙ ЗАПРОС!!! Status2 = PdhOpenQueryW(NULL, 0, &Query2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"open-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } //Добавить счётчик в запрос Status2 = PdhAddEnglishCounterW(Query2, L"\\Processor(_Total)\\% User Time", 0, &Counter2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"add-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Собирает текущее необработанное значение данных для всех счетчиков в указанном запросе и обновляет код состояния каждого счетчика*/ Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } Sleep(1000); Status2 = PdhCollectQueryData(Query2); if (Status2 != ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"collect-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*Вычислить отображаемое значение для указанного счетчика.*/ Status2 = PdhGetFormattedCounterValue(Counter2,PDH_FMT_DOUBLE,&CounterType2,&DisplayValue2); if(Status2!=ERROR_SUCCESS) { MessageBox(hwnd,(LPSTR)"formatted-NOT OK",(LPCSTR)"",MB_OK); EndDialog(hwnd,NULL); return TRUE; } /*закрываем запрос*/ if (Query2){PdhCloseQuery(Query2);}
GetDlgItemText(hwnd,COMBO,(LPSTR)str,51); if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0) { sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf); }
if(lstrcmp((LPCSTR)str,"% User time") == 0) { sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2); } } Уже немного похоже на правду , хоть новые значения появляются , но смущает , что если в первый раз заносятся 2 одинаковых значения ( а должно одно) , потом они меняются на другое и так далее и если выбрать какой-то другой счётчик , то результат 1-го счётчика стирается. Я же просто дописал в функцию func() : GetDlgItemText(hwnd,COMBO,(LPSTR)str,51); if(lstrcmp((LPCSTR)str,"% Privileged Time") == 0) { sprintf_s(buf, TEXT("%lf"), DisplayValue.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf); }
if(lstrcmp((LPCSTR)str,"% User time") == 0) { sprintf_s(buf2, TEXT("%lf"), DisplayValue2.doubleValue); SendMessage(LB, LB_ADDSTRING, 1, ( LPARAM)buf2); } А должно выглядеть всё это - по нажатию кнопки . И значение 1-го счётчика должно сохранятся в листбоксе Что не так сделал?
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #7 : 07-05-2014 17:34 » |
|
NNN7, не очень понятно, причём тут кнопка, когда ты функцию вызываешь на событие таймера.
Вообще по-хорошему разработка ведётся модульно или компонентно. Т.е. у тебя несколько разных задач:
1) Логика, при которой по выбору в комбо-боксе и нажатию кнопки в листбоксе обновляются данные.
2) Данные обновляются по таймеру.
3) Чтобы отображались именно счётчики.
Первые задачи могут изображать вовсе не счётчики, а тестовый текст или показания часов - это не важно. Но каждую задачу можно отработать отдельно, добившись, чтобы результат был правильным, и потом собирать вместе, как конструктор.
Я вот смотрю, что код ты пишешь на чистом WinAPI и не знаю, как у тебя дела обстоят со знанием объектно-ориентированного анализа и дизайна. Потому что саму эту задачу удобнее решать методами объектно-ориентированного подхода и архитектуры с разделением модели данных и пользовательского интерфейса. Но что удобнее мне, не факт, что удобнее тебе.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
NNN7
Интересующийся
Offline
|
|
« Ответ #8 : 07-05-2014 19:15 » |
|
NNN7, не очень понятно, причём тут кнопка, когда ты функцию вызываешь на событие таймера.
Вообще по-хорошему разработка ведётся модульно или компонентно. Т.е. у тебя несколько разных задач:
1) Логика, при которой по выбору в комбо-боксе и нажатию кнопки в листбоксе обновляются данные.
2) Данные обновляются по таймеру.
3) Чтобы отображались именно счётчики.
Первые задачи могут изображать вовсе не счётчики, а тестовый текст или показания часов - это не важно. Но каждую задачу можно отработать отдельно, добившись, чтобы результат был правильным, и потом собирать вместе, как конструктор.
Я вот смотрю, что код ты пишешь на чистом WinAPI и не знаю, как у тебя дела обстоят со знанием объектно-ориентированного анализа и дизайна. Потому что саму эту задачу удобнее решать методами объектно-ориентированного подхода и архитектуры с разделением модели данных и пользовательского интерфейса. Но что удобнее мне, не факт, что удобнее тебе.
Да , в ООП я не силён. Так как написать , чтобы значение счётчика , который выбрали в 1-ый раз не стиралось после выбора 2-го счётчика?
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #9 : 07-05-2014 21:11 » |
|
NNN7, нужно проанализировать объекты и события. К сожалению, я понятия не имею, как выглядит твой диалог, могу лишь предполагать. Объекты: 1) Есть полный перечень всех доступных счётчиков. Он должен отображаться в ComboBox. 2) Когда пользователь выбирает в ComboBox строчку, он может нажать некий Button, чтобы счётчик оказался выбранным пользователем. 3) Есть перечень выбранных пользователем счётчиков (по процедуре 2). Он должен отображаться в ListBox. 4) Помимо названий счётчиков в ListBox должны отображаться значения, и периодически обновляться. События: 1) Инициализация всего хозяйства. 2) Выбор счётчика пользователем. 3) Сигнал таймера. Разумно было бы придумать какую-то очистку выбранных значений или сброс. Как это можно запрограммировать. Да ещё и без классов и прочих ООП на чистом C. Во-первых, нужно придумать, что такое полный перечень счётчиков. Я так понимаю, он у тебя конечный. Каждый счётчик должен получить свой уникальной код (в пределах твоей программы) и константу, этот код выражающую. Что-то типа: #define PRC_PRIV_TIME 0 #define PRC_USR_TIME 1 /* и т.д. */ /* Количество всех счётчиков - для удобства перебора в цикле. */ #define СNTR_QTY 2 Дальше нужно разработать перечень операций, которые тебя интересуют применительно к любому счётчику. Например, получение названия счётчика в виде строки для показа на экране и получение значения счётчика. /*По коду счётчика возвращает строчку названия */ char *counter_getName(int id);
/* По коду счётчика записывает текущее значение счётчика в память, куда указывает value, возвращает 0 в случае успеха или разные иные коды в случае разных ошибок. */ int counter_getValue(int id, double *value); Соответственно, внутри каждой функции написать switch по кодам счётчиков. Что-то типа: char *counter_getName(int id) { switch(id) { case PRC_PRIV_TIME: return "Processor Privileged Time %"; case PRC_USR_TIME: return "Processor User Time %"; default: return NULL; } } Аналогично для значений: int counter_getValue(int id, double *value) { PDH_STATUS status; HQUERY query; char *counterName; HCOUNTER counter; DWORD counterType; PDH_FMT_COUNTERVALUE displayValue;
if(value == NULL) { return 1; } switch(id) { case PRC_PRIV_TIME: counterName = "\\Processor(_Total)\\% Privileged Time"; break; case PRC_USR_TIME: counterName = "\\Processor(_Total)\\% User Time"; break; default: return 2; } status = PdhOpenQuery(NULL, 0, &query); if(status != ERROR_SUCCES) { return -1; } status = PdhAddEnglishCounter(query, counterName, 0, &counter); if(status != ERROR_SUCCES) { PdhCloseQuery(query); return -2; } status = PdhCollectQueryData(query); if(status != ERROR_SUCCES) { PdhCloseQuery(query); return -3; } status = PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, &counterType, &displayValue); if(status != ERROR_SUCCES) { PdhCloseQuery(query); return -4; } PdhCloseQuery(query); *value = displayValue.doubleValue; return 0; } Теперь достаточно вызвать эти функции хоть отдельно для каждого счётчика, хоть в цикле, хоть имя и значение раздельно, хоть вместе. Дальше надо разобраться с выбором. Нужно где-то помнить, какие из счётчиков выбраны, а какие нет. Самый простой способ - хранить массив из выбранных счётчиков. Поскольку перечень меняется по размерам, либо массив будет динамическим (много возни), либо статическим. Если статическим, то его размер будет равен количеству всех счётчиков. Тогда в массиве целесообразно хранить не номера счётчиков (добавлять и удалять их, проверять отсутствие повторов муторно), а просто логические флажки включен/выключен, тогда индекс в массиве будет соответствовать коду счётчика. Нужно определиться с тем, будет ли этот массив глобальным в программе или локальным для какого-нибудь диалога. Второе больше соответствует идеям модульного подхода. Опять же, следует разработать перечень операций над такой структурой данных: struct CntrSt { int enbl[CNTR_QTY]; };
/* Подготовка структуры к работе. */ int counter_initialize(struct CntrSt *state) { int i; if(state == NULL) { return 1; } /* Все счётчики выключены. */ for(i = 0; i < CNTR_QTY; ++i) { state->enbl[i] = 0; } return 0; }
/* Выбор/включение счётчика */ int counter_select(struct CntrSt *state, int id) { if(state == NULL) { return 1; } if(id < 0 || id >= CNTR_QTY) { return 2; } state->enbl[id] = -1; return 0; }
/* Освобождение/отключение счётчика */ int counter_free(struct CntrSt *state, int id) { if(state == NULL) { return 1; } if(id < 0 || id >= CNTR_QTY) { return 2; } state->enbl[id] = 0; return 0; }
/* Возврат текущего статуса счётчика: выбран/включен или не выбран/выключен. */ int counter_getSelected(struct CntrSt *state, int id, int *selected) { if(state == NULL) { return 1; } if(id < 0 || id >= CNTR_QTY) { return 2; } if(selected == NULL) { return 3; } *selected = state->enbl[id]; return 0; } Собственно, структуру и функции писать необязательно, но удобно на тот случай, если алгоритм и структура данных для выбора поменяются в будущем - в целях расширения логики. Тогда изменятся лишь содержимое этих функций и содержимое структуры, все остальные части программы никаких изменений не потребуют. Здесь важно, что при использовании всего этого не нужно "залезать" внутрь структуры - всё делать только через специально для этой структуры написанные функции: struct CntrSt counterStates; /* глобальная переменная */
void inititializeDialog() /* обработка события инициализации */ { counter_initialize(&counterStates); /* другие инициализирующие действия */ }
void buttonClick() /* обработка события нажатия кнопки */ { int id; /* написать код получения кода счётчика в зависимости от выбранной строки в combobox */ counter_select(&counterStates, id); /* включение счётчика в список выбранных */ }
void timerTick() /* обработка события таймера */ { int i, selected; char *name; double value; char screenString[255]; /* написать код очистки listbox */ for(i = 0; i < CNTR_QTY; ++i) { /* Проходим по всем счётчикам. */ counter_getSelected(&counterStates, i, &selected); if(selected) { /* Обрабатываем только выбранные счётчики. */ name = counter_getName(i); counter_getValue(i, &value); sprintf(screenString, "%s = %lf", name, value); /* формируем строчку для ListBox */ /* написать код добавления screenString в listbox */ } } } Ну вот, собственно, основная схема решения. Т.е. всякий раз думай: 1) Какие у тебя есть сущности - они в программе выражаются разными структурами данных (собственно структурами, массивами, списками, перечнями констант и т.п.) 2) Какие над каждой сущность могут выполняться операции - для каждой операции описывай отдельную функцию. 3) Собирай из них как из лего-конструктора решение. 4) Никогда не используй элементы пользовательского интерфейса для хранения информации и для управления логикой программы. Они нужны лишь для показа информации на экране пользователю и для ввода пользователя. В данном случае как решается твоя проблема: 1) Вывод в ListBox происходит только по таймеру, и только в этот момент опрашиваются счётчики, и только в соответствии с управляющей структурой данных. 2) Управление тем, какие счётчики выбраны, все эти комбо-боксы и кнопки вообще никак не работают напрямую со счётчиком. Итогом их работы является лишь установка/снятие логического флажка в подходящей структуре данных (в данном случае массиве). 3) Структура данных является связующим звеном между двумя алгоритмами, решающими каждый свою задачу.
|
|
« Последнее редактирование: 07-05-2014 21:17 от Dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
|