Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.117.154.41] |
|
Сообщ.
#1
,
|
|
|
function TRestoreViewer.GetRestorePoints: TRestorePoints; var ObjWMIService : OLEVariant; ColItems : OLEVariant; ColItem : OLEVariant; OEnum : IEnumvariant; // IValue : PLongint; CountOfRestorePoint : Integer; I: Integer; RestorePoint : TRestorePoint; begin ObjWMIService := GetWMIObject('winmgmts:\\localhost\root\default'); ColItems := objWMIService.ExecQuery('SELECT * FROM SystemRestore','WQL',0); OEnum := IUnknown(colItems._NewEnum) as IEnumVariant; if not VarIsNull(ColItems.Count) then CountOfRestorePoint := StrToInt(VarToStr(ColItems.Count)) else CountOfRestorePoint := 0; if (CountOfRestorePoint = 0) then Exit; // SetLength(Result, CountOfRestorePoint); I := 0; while OEnum.Next(1, colItem, nil {IValue}) = 0 do begin RestorePoint.Description := ColItem.Description; RestorePoint.EventType := EventTypeToStr(ColItem.EventType); RestorePoint.SequenceNumber := ColItem.SequenceNumber; RestorePoint.CreationTime := WMITimeToStr(ColItem.CreationTime); RestorePoint.RestorePointType := RestorePointTypeToStr(ColItem.RestorePointType); Result[i] := RestorePoint; Inc(i); end; end; |
Сообщ.
#2
,
|
|
|
SetLength нельзя заменить ничем, если оно применяется к переменным соответствующих типов.
А про тип мы не знаем, т.к. не телепаты. |
Сообщ.
#3
,
|
|
|
Сорри. Вот тип:
type TRestorePoint = record Description:string; EventType:string; SequenceNumber:string; CreationTime:string; RestorePointType:string; end; TRestorePoints = array [0..255]of TRestorePoint; |
Сообщ.
#4
,
|
|
|
getmem/freemem
|
Сообщ.
#5
,
|
|
|
В моем случае Result не Pointer. Так не компилится: Incompatible types
GetMem(Result, sizeOf(CountOfRestorePoint)); |
Сообщ.
#6
,
|
|
|
Массив статический, так что задавать длину ему не нужно, память под результат уже выделена компилятором.
При этом неизвестно, сколько реально элементов заполнено SetLength требуется для динамических массивов TRestorePoints = array of TRestorePoint; |
Сообщ.
#7
,
|
|
|
Это не помогает. ListView1 заполняется множеством пустых пунктов. Может, в заполнении ошибка:
procedure TForm1.Button1Click(Sender: TObject); var MyRestoreViewer:TRestoreViewer; AllRestorePoint:TRestorePoints; I: Integer; begin ListView1.Items.Clear; MyRestoreViewer := TRestoreViewer.Create; AllRestorePoint := MyRestoreViewer.GetRestorePoints; for I := 0 to High(AllRestorePoint) do with ListView1.Items.Add do begin Caption := AllRestorePoint[i].Description; SubItems.Add(AllRestorePoint[i].EventType); SubItems.Add(AllRestorePoint[i].SequenceNumber); SubItems.Add(AllRestorePoint[i].RestorePointType); SubItems.Add(AllRestorePoint[i].CreationTime); end; MyRestoreViewer.Free; end; |
Сообщ.
#8
,
|
|
|
А длина динамического массива установлена в соответствии с реальным содержанием? Если используется код из первого поста, то i после цикла содержит счётчик записей.
|
Сообщ.
#9
,
|
|
|
1) Поставь точку останова после заполнения массива и посмотри в отладчике, что туда записалось
2) (а) Возвращай кол-во заполненных элементов либо (б) выставляй флаг внутри записи, что она содержит данные, чтобы не рассматривать незаполненные элементы 3) Если выберешь вариант (б), обнуляй массив перед каждым заполнением. |
Сообщ.
#10
,
|
|
|
Сенкс! Нашел ошибку. Закрывайте тему.
|
Сообщ.
#11
,
|
|
|
Сам и закрывай)
|
Сообщ.
#12
,
|
|
|
navodri, используй динамический массив (см. выше строку кода от MBo) и используй с ним SetLength, High и пр.
Это гораздо лучше, чем забивать стек массивом и потом копировать его с одного места на другое. К тому же, SetLength обнуляет выделенные элементы массива – ещё один плюс. А если ты создаёшь динамический массив как локальную переменную в вызывающей процедуре: procedure Example; var RestorePoints: TRestorePoints; begin . . . RestorePoints := TRestoreViewer.GetRestorePoints; . . . end; |