-
Задумался как перевести такой код с "Visual Basic" на "Delphi 7":
Private Sub Test() Dim objFileSystem As Scripting.FileSystemObject Dim SrcFolder As Scripting.Folder Dim SrcFile As Scripting.File Set objFileSystem = New Scripting.FileSystemObject With objFileSystem Set SrcFolder = .GetFolder("C:\") For Each SrcFile In SrcFolder.Files Call MsgBox(SrcFile.Name) Next SrcFile End With End Sub
Но в моей версии Делфи ещё нет "For Each" или "For In". Попробовал так, но не работает:
procedure Test(); var objFileSystem, SrcFolder, SrcFiles, SrcFile: OleVariant; Index: integer; begin objFileSystem := CreateOleObject('Scripting.FileSystemObject'); SrcFolder := objFileSystem.GetFolder('C:\'); SrcFiles := SrcFolder.Files; ShowMessage('SrcFiles.Count == '+IntToStr(SrcFiles.Count)); For Index := 1 To SrcFiles.Count do begin SrcFile := SrcFiles.Item[Index]; // вылетает тут ShowMessage(SrcFile.Name); end; end;
Выстреливает ошибку: raised exception class EOleException with message 'Параметр задан неверно'.
Так же пробовал всякие:
SrcFiles.Item(Index) SrcFiles.Items(Index) SrcFiles.Items.Item(Index) SrcFiles[Index]
Но бесполезно. Может кто-то подскажет что именно такое хитрое происходит в VB при использовании "For Each In" ? Ну или просто как правильно вытащить оттуда данные. Спасибо!
-
SrcFile := SrcFiles.item['pagefile.sys']; ShowMessage(SrcFile.Name);
а по индексу ты его и в нативном вбс не достанешь.
-
procedure TForm1.Button1Click(Sender: TObject); var i : integer; begin SendMessage(ListBox1.Handle, LB_DIR, 49207, Integer(PChar('C:\*.*'))); for i := 0 to pred(ListBox1.Count) do ShowMessage(ListBox1.Items[i]); end;
-
Другие способы получения списка файлов мне в данном случае не важны, я их большинство знаю, спасибо. Интересует что делает VB. Собственно мне не важно по индексу или нет - мне интересно что именно делает "For Each ... Next statement" и как это повторить на Делфи. Вот есть " Files Collection" - https://msdn.microsoft.com/en-us/library/aa242702(v=vs.60).aspx - как его "перебрать" от начала до конца, чтоб "низкоуровнево" было полностью аналогично VB?
-
Нагуглил вот этакую штуковину:
// for DelphiScript: procedure ListFiles; var fso, folder, enum, f; begin fso := Sys.OleObject('Scripting.FileSystemObject'); folder := fso.GetFolder('C:\'); enum := Utils.Enumerator(folder.Files); while not enum.AtEnd do begin f := enum.item; Log.Message(f.Name); enum.MoveNext; end; end;
В принципе некоторым образом похоже. Только что это за "Enumerator"? В Делфи7 не обнаружился.
-
а нафига вообще прикручивать к нормальному и самодостаточному vbs какое-то делфи?
-
Что? Есть OleObject. VB может с ним работать, а Делфи чего - не может? Просто хочу перевести код, в точности.
-
мало ли чего ты хочешь.
вот есть ком-объект xmlhttprequest у которого есть onReadyStateChange и который idispatch
и в js ты делаешь obj.onReadyStateChange = function_name и это работает
а в делфи что нельзя?!
Да. в делфи так нельзя, несмотря на то что это ком.
надо создавать экземпляр наследника реализующего idispatch с дефолтным методом (dispid = 0) который и будет обработчиком. И событию навешивается не обработчик, а объект с этим дефолтным методом.
Это к вопросу о повторе а точности.
-
Попробуй SrcFile := SrcFiles[Index]
-
думаешь если сделать много попыток, то компутер сжалится и даст тебе файл по индексу?
-
Я же такое проверял, вроде написано было.
Ну перефразируем так: как в Делфи перебирать содержимое полученного "Files Collection"?
-
https://theroadtodelphi.com/2011/11/04/implementing-a-delphi-for-in-loop-on-com-collections-and-variant-arrays/+( http://www.gunsmoker.ru/2011/05/9.html) type IEnumVariant = interface(IUnknown) ['{00020404-0000-0000-C000-000000000046}'] function Next(celt: LongWord; var rgvar : OleVariant; pceltFetched: PLongWord): HResult; stdcall; function Skip(celt: LongWord): HResult; stdcall; function Reset: HResult; stdcall; function Clone(out Enum: IEnumVariant): HResult; stdcall; end;
procedure Test(); var s : String; i, d, n : Integer;
iEnum : IEnumVariant; aFiles : array of OleVariant;
iFsObj, iFolder, iFiles, iFile : OleVariant;
begin iFsObj := CreateOleObject('Scripting.FileSystemObject'); iFolder := iFsObj.GetFolder('C:\'); iFiles := iFolder.Files;
iEnum := IUnknown(iFiles._NewEnum) as IEnumVariant; // !
while ( iEnum.Next(1, iFile, @d) = S_OK ) do s := iFile.Name;
iEnum := IUnknown(iFiles._NewEnum) as IEnumVariant; // 2. !
n := iFiles.Count; SetLength(aFiles, n);
if ( iEnum.Next(n, aFiles[0], @d) = S_OK ) then for i := Low(aFiles) to High(aFiles) do s := aFiles[i].Name; end;
-
Спасибо огромное! Работает! Просто интересно - именно так VB делает "под капотом"?
|