Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 6 088

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!
Здравствуйте, пишу мониторинг процессов в системе по технологии WMI. Столкнулся с проблемой обновления Items в ListView. Нашел статью о виртуальном ListView (на этом сайте), попробовал переделать свой код, но почему-то список вообще не обновляется, даже не выводит из масива данные в список (если это делать по таймеру). Если делать по событию form1.create то он один раз выводит, но мне это не подходит. В статье пишет про обновление Items через UpdateItems(n,m), но у меня это так-же не работает... пожалуйста подкоректируйте мой код или скажите что я делаю не так ? как заставить обновлять данные (как в диспетчере задач windows) ?

Приложение:
  1. unit Unit100000000000000;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, WbemScripting_TLB, ComCtrls, ExtCtrls,Math, Grids, StdCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. Timer1: TTimer;
  12. ListView1: TListView;
  13.  
  14.  
  15. type
  16.  
  17. TSimpleRec=record
  18. caption:string;
  19. data:integer;
  20. end;
  21.  
  22. TSimpleArr = array of TSimpleRec;
  23.  
  24.  
  25. procedure Timer1Timer(Sender: TObject);
  26. procedure ListView1Data(Sender: TObject; Item: TListItem);
  27. procedure FormCreate(Sender: TObject);
  28.  
  29. private
  30. arr:TSimpleArr;
  31. services : ISWbemServices;
  32. refresher : ISWbemRefresher;
  33. refresherItem : ISWbemRefreshableItem;
  34.  
  35. pObject : ISWbemObject;
  36.  
  37. pid,mem : cardinal;
  38. // pItem : TListItem;
  39. public
  40. { Public declarations }
  41. end;
  42. var
  43. Form1: TForm1;
  44.  
  45. implementation
  46.  
  47. {$R *.dfm}
  48.  
  49.  
  50. procedure TForm1.FormCreate(Sender: TObject);
  51. var locator : ISWbemLocator;
  52. i : cardinal;
  53.  
  54. lc:TListColumn;
  55. begin
  56.  
  57. locator := CoSWbemLocator.Create();
  58. services := locator.ConnectServer('.','root\cimv2','','','','',0,nil);
  59. refresher := CoSWbemRefresher.Create;
  60. refresherItem := refresher.AddEnum(services as ISWbemServicesEx,'Win32_PerfFormattedData_PerfProc_Process',0,nil);
  61.  
  62. timer1.Enabled := true;
  63. Refresher.Refresh(0);
  64. Listview1.OwnerData:=True;
  65.  
  66. ListView1.ViewStyle:=vsReport;
  67. lc:=ListView1.Columns.Add;
  68. lc.Caption:='PID';
  69. lc.Width:=150;
  70. lc:=ListView1.Columns.Add;
  71. lc.Caption:='Memory';
  72. lc.Width:=150;
  73.  
  74. ListView1.RowSelect:=true;
  75.  
  76.  
  77. SetLength(arr,refresherItem.ObjectSet.Count);
  78.  
  79. ListView1.Items.Count:=Length(arr);
  80.  
  81. Caption:=IntToStr(Length(arr));
  82.  
  83.  
  84. end;
  85.  
  86.  
  87.  
  88. procedure TForm1.Timer1Timer(Sender: TObject);
  89. var
  90. i : cardinal;
  91. pItem : TListItem;
  92. begin
  93. Refresher.Refresh(0);
  94.  
  95. SetLength(arr,refresherItem.ObjectSet.Count);
  96.  
  97. ListView1.Items.Count:=Length(arr);
  98.  
  99. Caption:=IntToStr(Length(arr));
  100.  
  101.  
  102.  
  103. for i:=0 to refresherItem.ObjectSet.Count-1 do
  104. begin
  105. pObject := refresherItem.ObjectSet.ItemIndex(i);
  106. pid := pObject.Properties_.Item('IdProcess',0).Get_Value;
  107. // name := pObject.Properties_.Item('Name',0).Get_Value;
  108. // usage:= pObject.Properties_.Item('PercentProcessorTime',0).Get_Value;
  109. mem:= pObject.Properties_.Item('WorkingSetPrivate',0).Get_Value;
  110.  
  111. arr[i].caption:=IntToStr(pid);
  112. arr[i].data:=mem;
  113.  
  114. pObject._Release;
  115.  
  116. end;
  117.  
  118.  
  119. end;
  120.  
  121. procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
  122.  
  123. begin
  124. item.Caption:=arr[item.Index].caption;
  125. item.SubItems.Add(IntToStr(arr[item.Index].data));
  126.  
  127. end;
  128.  
  129. end.


darkziman Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: darkziman (статус: Посетитель)
Вопрос отправлен: 18 апреля 2012, 22:55
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 9; последнее сообщение — 2 мая 2012, 02:03; участников в обсуждении: 3.
Вадим К

Вадим К (статус: Академик), 18 апреля 2012, 23:35 [#1]:

Ну, и где же Вы вызываете UpdateItems ? Как минимум один вызов нужен сразу перед окончанием процедуры для таймера.
ListView1.UpdateItems(0, length(arr)-1);
С другой стороны - промежуточный массив Вам абсолютно не нужен. Данные можно брать напрямую.
Галочка "подтверждения прочтения" - вселенское зло.
darkziman

darkziman (статус: Посетитель), 18 апреля 2012, 23:51 [#2]:

на строчку, что Вы написали программа никак не реагирует. При запуске у меня первая колонка пустая, а вторая забита нолями (так-как там должны вписыватся данные типа integer).

Я пробовал сделать обновление с помощью сравнения итема PID (уникального номера) и значения PID, которое должно получить от WMI .. но тоже ничего не работало...
min@y™

min@y™ (статус: Доктор наук), 19 апреля 2012, 08:17 [#3]:

Ну, раз не получается с UpdateItems(), попробуй в конце обработчика таймера грубо ввалить ListView1.Invalidate(). Если и это не поможет, то ставь точку останова и тыкай в отладчике по шагам, просматривая, что же происходит там на самом деле.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Вадим К

Вадим К (статус: Академик), 19 апреля 2012, 11:55 [#4]:

Программа может не реагировать по одной простой причине - в массиве arr ничего не заполнялось. Либо Refresher начинает работать в отдельном потоке (и получается, что он к примеру в этот момент может быть чистым).

Самое первое, что рекомендую - в конце процедуры таймера вывести его содержимое в файл или мемо и посмотреть, а что же там.
Галочка "подтверждения прочтения" - вселенское зло.
darkziman

darkziman (статус: Посетитель), 19 апреля 2012, 23:22 [#5]:

проверил, в массиве arr идет заполнение и обновление данных (вывел в цикле в memo).

строчка Caption:=IntToStr(Length(arr)); в названии формы обновляется (показывает число запущеных процессов)...

Listview меняет количество итемов каждую секунду (в зависимости от количества процессов),но все итемы пустые ... подскажите почему ?!
min@y™

min@y™ (статус: Доктор наук), 20 апреля 2012, 08:11 [#6]:

Поставь бряк в обработчик события OnData, может быть у тебя туда исполнение не доходит?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
darkziman

darkziman (статус: Посетитель), 20 апреля 2012, 08:51 [#7]:

да, действительно, процедура procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem); не работает, он до нее не доходит, после записи всех процессов в массив оно начинает делать это сначала =( ... как заставить её работать ?!...
min@y™

min@y™ (статус: Доктор наук), 20 апреля 2012, 09:01 [#8]:

Цитата (darkziman):

как заставить её работать ?!.

Ну, для начала надо присвоить событию обработчик. В Object Inspector'e или вручную. А затем в конце обработчика таймера - ListView1.Refresh().
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
darkziman

darkziman (статус: Посетитель), 2 мая 2012, 02:03 [#9]:

работает, спасибо !

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:45
Выполнено за 0.03 сек.