Конференция "Основная" » Ole, FileSystemObject, проблемы с перечислением файлов [D7, WinXP]
 
  • Д7 (26.08.16 17:20) [0]
    Задумался как перевести такой код с "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" ?
    Ну или просто как правильно вытащить оттуда данные. Спасибо!
  • iop © (26.08.16 17:52) [1]
    SrcFile := SrcFiles.item['pagefile.sys'];
     ShowMessage(SrcFile.Name);

    а по индексу ты его и в нативном вбс не достанешь.
  • iop © (26.08.16 18:15) [2]
    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;
  • Д7 (26.08.16 18:36) [3]
    Другие способы получения списка файлов мне в данном случае не важны, я их большинство знаю, спасибо. Интересует что делает VB.

    Собственно мне не важно по индексу или нет - мне интересно что именно делает "For Each ... Next statement" и как это повторить на Делфи.
    Вот есть "Files Collection" - https://msdn.microsoft.com/en-us/library/aa242702(v=vs.60).aspx - как его "перебрать" от начала до конца, чтоб "низкоуровнево" было полностью аналогично VB?
  • Д7 (26.08.16 18:40) [4]
    Нагуглил вот этакую штуковину:

    // 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 не обнаружился.
  • iop © (26.08.16 20:13) [5]
    а нафига вообще прикручивать к нормальному и самодостаточному vbs какое-то делфи?
  • Д7 (26.08.16 21:40) [6]
    Что?
    Есть OleObject. VB может с ним работать, а Делфи чего - не может?
    Просто хочу перевести код, в точности.
  • iop © (26.08.16 21:53) [7]
    мало ли чего ты хочешь.

    вот есть ком-объект xmlhttprequest у которого есть onReadyStateChange и который idispatch

    и в js ты делаешь obj.onReadyStateChange = function_name и это работает

    а в делфи что нельзя?!

    Да. в делфи так нельзя, несмотря на то что это ком.

    надо создавать экземпляр наследника реализующего idispatch с дефолтным методом  (dispid = 0) который и будет обработчиком.
    И событию навешивается не обработчик, а объект с этим дефолтным методом.

    Это к вопросу о повторе а точности.
  • Dimka Maslov © (26.08.16 23:19) [8]
    Попробуй
    SrcFile := SrcFiles[Index]
  • iop © (26.08.16 23:35) [9]
    думаешь если сделать много попыток, то компутер сжалится и даст тебе файл по индексу?
  • Д7 (27.08.16 15:16) [10]
    Я же такое проверял, вроде написано было.

    Ну перефразируем так: как в Делфи перебирать содержимое полученного "Files Collection"?
  • NoUser © (30.08.16 00:03) [11]
    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;
  • Д7 (30.08.16 21:30) [12]
    Спасибо огромное! Работает!
    Просто интересно - именно так VB делает "под капотом"?
 
Конференция "Основная" » Ole, FileSystemObject, проблемы с перечислением файлов [D7, WinXP]
Есть новые Нет новых   [120186   +29][b:0][p:0]