|
Вопрос # 6 088/ вопрос открыт / |
|
Доброго времени суток, уважаемые эксперты!
Здравствуйте, пишу мониторинг процессов в системе по технологии WMI. Столкнулся с проблемой обновления Items в ListView. Нашел статью о виртуальном ListView (на этом сайте), попробовал переделать свой код, но почему-то список вообще не обновляется, даже не выводит из масива данные в список (если это делать по таймеру). Если делать по событию form1.create то он один раз выводит, но мне это не подходит. В статье пишет про обновление Items через UpdateItems(n,m), но у меня это так-же не работает... пожалуйста подкоректируйте мой код или скажите что я делаю не так ? как заставить обновлять данные (как в диспетчере задач windows) ?
Приложение: Переключить в обычный режим- unit Unit100000000000000;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, WbemScripting_TLB, ComCtrls, ExtCtrls,Math, Grids, StdCtrls;
-
- type
- TForm1 = class(TForm)
- Timer1: TTimer;
- ListView1: TListView;
-
-
- type
-
- TSimpleRec=record
- caption:string;
- data:integer;
- end;
-
- TSimpleArr = array of TSimpleRec;
-
-
- procedure Timer1Timer(Sender: TObject);
- procedure ListView1Data(Sender: TObject; Item: TListItem);
- procedure FormCreate(Sender: TObject);
-
- private
- arr:TSimpleArr;
- services : ISWbemServices;
- refresher : ISWbemRefresher;
- refresherItem : ISWbemRefreshableItem;
-
- pObject : ISWbemObject;
-
- pid,mem : cardinal;
- // pItem : TListItem;
- public
- { Public declarations }
- end;
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
-
- procedure TForm1.FormCreate(Sender: TObject);
- var locator : ISWbemLocator;
- i : cardinal;
-
- lc:TListColumn;
- begin
-
- locator := CoSWbemLocator.Create();
- services := locator.ConnectServer('.','root\cimv2','','','','',0,nil);
- refresher := CoSWbemRefresher.Create;
- refresherItem := refresher.AddEnum(services as
ISWbemServicesEx,'Win32_PerfFormattedData_PerfProc_Process',0,nil);
-
- timer1.Enabled := true;
- Refresher.Refresh(0);
- Listview1.OwnerData:=True;
-
- ListView1.ViewStyle:=vsReport;
- lc:=ListView1.Columns.Add;
- lc.Caption:='PID';
- lc.Width:=150;
- lc:=ListView1.Columns.Add;
- lc.Caption:='Memory';
- lc.Width:=150;
-
- ListView1.RowSelect:=true;
-
-
- SetLength(arr,refresherItem.ObjectSet.Count);
-
- ListView1.Items.Count:=Length(arr);
-
- Caption:=IntToStr(Length(arr));
-
-
- end;
-
-
-
- procedure TForm1.Timer1Timer(Sender: TObject);
- var
- i : cardinal;
- pItem : TListItem;
- begin
- Refresher.Refresh(0);
-
- SetLength(arr,refresherItem.ObjectSet.Count);
-
- ListView1.Items.Count:=Length(arr);
-
- Caption:=IntToStr(Length(arr));
-
-
-
- for i:=0 to refresherItem.ObjectSet.Count-1 do
- begin
- pObject := refresherItem.ObjectSet.ItemIndex(i);
- pid := pObject.Properties_.Item('IdProcess',0).Get_Value;
- // name := pObject.Properties_.Item('Name',0).Get_Value;
- // usage:= pObject.Properties_.Item('PercentProcessorTime',0).Get_Value;
- mem:= pObject.Properties_.Item('WorkingSetPrivate',0).Get_Value;
-
- arr[i].caption:=IntToStr(pid);
- arr[i].data:=mem;
-
- pObject._Release;
-
- end;
-
-
- end;
-
- procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
-
- begin
- item.Caption:=arr[item.Index].caption;
- item.SubItems.Add(IntToStr(arr[item.Index].data));
-
- end;
-
- end.
 |
Вопрос задал: 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 (статус: Посетитель), 18 апреля 2012, 23:51 [#2]:
на строчку, что Вы написали программа никак не реагирует. При запуске у меня первая колонка пустая, а вторая забита нолями (так-как там должны вписыватся данные типа integer).
Я пробовал сделать обновление с помощью сравнения итема PID (уникального номера) и значения PID, которое должно получить от WMI .. но тоже ничего не работало...
|
|
min@y™ (статус: Доктор наук), 19 апреля 2012, 08:17 [#3]:
Ну, раз не получается с UpdateItems(), попробуй в конце обработчика таймера грубо ввалить ListView1.Invalidate(). Если и это не поможет, то ставь точку останова и тыкай в отладчике по шагам, просматривая, что же происходит там на самом деле.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Вадим К (статус: Академик), 19 апреля 2012, 11:55 [#4]:
Программа может не реагировать по одной простой причине - в массиве arr ничего не заполнялось. Либо Refresher начинает работать в отдельном потоке (и получается, что он к примеру в этот момент может быть чистым).
Самое первое, что рекомендую - в конце процедуры таймера вывести его содержимое в файл или мемо и посмотреть, а что же там.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
darkziman (статус: Посетитель), 19 апреля 2012, 23:22 [#5]:
проверил, в массиве arr идет заполнение и обновление данных (вывел в цикле в memo).
строчка Caption:=IntToStr(Length(arr)); в названии формы обновляется (показывает число запущеных процессов)...
Listview меняет количество итемов каждую секунду (в зависимости от количества процессов),но все итемы пустые ... подскажите почему ?!
|
|
min@y™ (статус: Доктор наук), 20 апреля 2012, 08:11 [#6]:
Поставь бряк в обработчик события OnData, может быть у тебя туда исполнение не доходит?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
darkziman (статус: Посетитель), 20 апреля 2012, 08:51 [#7]:
да, действительно, процедура procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem); не работает, он до нее не доходит, после записи всех процессов в массив оно начинает делать это сначала =( ... как заставить её работать ?!...
|
|
min@y™ (статус: Доктор наук), 20 апреля 2012, 09:01 [#8]:
Цитата (darkziman):
как заставить её работать ?!.
Ну, для начала надо присвоить событию обработчик. В Object Inspector'e или вручную. А затем в конце обработчика таймера - ListView1.Refresh().
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
darkziman (статус: Посетитель), 2 мая 2012, 02:03 [#9]:
работает, спасибо !
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|