Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > VirtualListView


Автор: AndAnd 30.1.2007, 06:41
Привет всем! У меня проблема с ListView. Взял исходник из примеров Builder (в папке Examples\VirtualListView\...). Мне необходимо внести свои данные - это например, список папок и файлов на ФТП-сервере, которые система не может видеть как она это видит в примере. Как можно отобразить этот список с посмощью данного примера. Спасибо.

Автор: _hunter 30.1.2007, 11:44
Цитата(AndAnd @  30.1.2007,  06:41 Найти цитируемый пост)
Взял исходник из примеров Builder

ты считаеш что эти примеры должны быть у всех здесь присутствующих? ;)

Автор: Vyacheslav 30.1.2007, 11:50
OwnerData в true и используя  событие OnData . Там же в примере все прекрасно расписано. Все данные предварительно сохранеы FIDList и по требования на OnData из FIDList заполняется  конкретный TListItem

Добавлено @ 11:52 
Цитата(_hunter @  30.1.2007,  11:44 Найти цитируемый пост)
ты считаеш что эти примеры должны быть у всех здесь присутствующих? ;) 

Должны. Хотя бы для того, что бы научиться  с компонентами так, как это предполагили разработчики. К тому же он входят в поставку

Автор: AndAnd 1.2.2007, 09:09
Не получается отобразить все, вот ниже часть кода где я пытаюсь это сделать:

Код

//..........................
//....................
//В отдельной функции я получаю данные о файлах и директориях
//
void function()
{
PShellItem * ShellItem;
WIN32_FIND_DATA FindFileData;
AnsiString NameF="",time = "";

  Form1->FIDList1->Clear();
while (InternetFindNextFile(FtpFindFF, &FindFileData))
  {
//.......    
   if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
    NameF = FindFileData.cFileName ;//Получили имя директории
    FileTimeToLocalFileTime(&FindFileData.ftLastWriteTime,&FindFileData.ftLastWriteTime);
    FileTimeToSystemTime(&FindFileData.ftLastWriteTime,&sys_time);
    time = DateTimeToStr(SystemTimeToDateTime(sys_time)); //время последнего изменения
//в FIDList надо еще занести ТИП и АТРИБУТЫ, как???
    }
   else{
  //все тоже самое но для файла
    NameF = FindFileData.cFileName ;//Получили имя файла
    FileTimeToLocalFileTime(&FindFileData.ftLastWriteTime,&FindFileData.ftLastWriteTime);
    FileTimeToSystemTime(&FindFileData.ftLastWriteTime,&sys_time);
    time = DateTimeToStr(SystemTimeToDateTime(sys_time)); //время последнего изменения
//еще необходимо занести размер файла, его АТРИБУТЫ и ТИП
    
       }
             ShellItem = new PShellItem;
             ShellItem->DisplayName = Spisok;
             ShellItem->Size = (int)FindFileData.nFileSizeLow ;//если размер файла заносить так то он не работает,
                    //там по-моему надо этот размер еще преобразовать
             ShellItem->ModDate = time;
             ShellItem->Attributes = FindFileData.dwFileAttributes;// Тоже не отображаются
             ShellItem->Empty = true;
             Form1->FIDList1->Add(ShellItem);
             Form1->ListView1->Items->Count = Form1->FIDList1->Count;
             Form1->ListView1->OnData;
   };
    // в итоге получаем в ListView только имя файлов и директоий и их даты последнего изменения
}

Автор: _hunter 1.2.2007, 11:44
Цитата(AndAnd @  1.2.2007,  09:09 Найти цитируемый пост)
 Form1->ListView1->OnData

в чем смысл этой строки?
где сам обработчик (его реализация)?
зачем постить лишний код (while (InternetFindNextFile...)) -- чтобы запутать?..

Автор: Vyacheslav 1.2.2007, 13:34
А где код то обработчика, которые запускается на OnData ?
Вы в примере посмотрите  
Код

void __fastcall TfrmVirtualLView::lstvwVirtualListData(TObject *Sender,
      TListItem *Item)


В нем весь смысл.  Когда ListView нужно данные по выводимой строке, он(ListView, а не ВЫ) запускает обработчик события OnData. В этом обработчикеВы и должны заполнить параметр Item используя значения из FIDList и учитывая, то, что от Вас требуют строку под номером Item->Index


Автор: AndAnd 1.2.2007, 19:36
Извините за тупость, не могу понять. Я правильно заполняю FIDList? (см. выше код). А как ListView поймет что данные в FIDList заполнены и я хочу их вывести? 
Вот обработчик OnData

Код

void __fastcall TForm1::ListView1Data(TObject *Sender, TListItem *Item)
{
        AnsiString Attrs;
        PShellItem * ShellItem;
        //OnData gets called once for each item for which the ListView needs
        //data. If the ListView is in Report View, be sure to add the subitems.
        //Item is a "dummy" item whose only valid data is it's index which
        //is used to index into the underlying data.
        if ((Item->Index < FIDList1->Count))
        {

                ShellItem = GetShellItem(Item->Index,1);//где взять этот Item->Index?
                Item->Caption = ShellItem->DisplayName;
                Item->ImageIndex = ShellItem->ImageIndex;

                if (Form1->ListView1->ViewStyle == vsReport)
                {
                        if (!(IsFolder1(FIShellFolder1, ShellItem->ID)))
                                Item->SubItems->Add(Format("%dKB", ARRAYOFCONST((ShellItem->Size))));
                        else
                                Item->SubItems->Add("");

                        Item->SubItems->Add(ShellItem->TypeName);

                        Item->SubItems->Add(ShellItem->ModDate);

                        if (BOOL(ShellItem->Attributes & FILE_ATTRIBUTE_READONLY))
                                Attrs = Attrs + 'R';
                        if (BOOL(ShellItem->Attributes & FILE_ATTRIBUTE_HIDDEN))
                                Attrs = Attrs + 'H';
                        if (BOOL(ShellItem->Attributes & FILE_ATTRIBUTE_SYSTEM))
                                Attrs = Attrs + 'S';
                        if (BOOL(ShellItem->Attributes & FILE_ATTRIBUTE_ARCHIVE))
                                Attrs = Attrs + 'A';

                        Item->SubItems->Add(Attrs);
                }
        }
}

Автор: Vyacheslav 2.2.2007, 13:33
Цитата(AndAnd @  1.2.2007,  19:36 Найти цитируемый пост)
 как ListView поймет что данные в FIDList заполнены и я хочу их вывести? 

Когда поймет. Ну Вы же ему сказали
Код

Form1->ListView1->Items->Count = Form1->FIDList1->Count;

И тогда он начнет процесс вывода и  перед выводом  каждой  строки вызовет событие OnData  для того, чтобы Вы заполнили  данными Item. Для события, Вы определили обработчик  ListView1Data, который и должен заполнить Item из FIDList1.
  
Цитата(AndAnd @  1.2.2007,  19:36 Найти цитируемый пост)

где взять этот Item->Index?

А что его брать? Его брать не надо. Он и без Вас уже задан. ListView   последовательно вызовет обработчик ListView1Data   FIDList1->Count раз и при каждом вызове значение Item->Index будет увеличиваться на 1. Item->Index Вам дается как раз для того, что бы сообщить, содержимым какого элемента Вашего массива Вы должны заполнить Item.
Короче говоря, допустим у меня есть весктор строк.
Код

 vector<AnsiString> v; 


1.  должен установить OwnerData в true
2. задать обработчик 
Код

void __fastcall TForm1::ListView1Data(TObject *Sender, TListItem *Item)
{
       Item->Caption  = v[ Item->Index]
}
 

3 Сообщить ListView, что информация готова к выводу
Код

ListView1->Items->Count = v.size();

Последнее я должен сделать только тогда, когда вектор будет заполнен.
Для того, что бы запретить показывать содержимое(например мне нужно обновить вектор
Код

// запрещаем показ
ListView1->Items->Count = 0;
//обновляем данные в векторе
....
//разрешаем вывод
ListView1->Items->Count = v.size();







Автор: AndAnd 2.2.2007, 16:00
Теперь вроде понятно smile Спасибо за простой пример.

Автор: AndAnd 3.2.2007, 17:08
А интересно как лучше производить сортировку в ListView, подскажите лучший путь. У меня есть столбцы, довольно стандартные: Имя, Размер, Тип, ДатаПоследенего изменения. Есть ли функция ВИНАПИ? Метод пузырька не рассматривается. smile

Автор: AndAnd 9.2.2007, 11:13
как VirtualListview работает с файловой системой. Подскажите, пожалуйста,  как можно создать функцию, на вход которой подается имя диска, а в ListView отобразиться его содержимое? Используя функции из VirtualListView.

Автор: AndAnd 9.2.2007, 21:21
Цитата

как VirtualListview работает с файловой системой. Подскажите, пожалуйста,  как можно создать функцию, на вход которой подается имя диска, а в ListView отобразиться его содержимое? Используя функции из VirtualListView.


Заглянул я в пример и нашел там функцию SetPath(const AnsiString path), которая как раз и позволяет перейти непосредственно по требуемому пути. smile
Мораль басни: Чаще надо заглядывать в исходный пример, а не только своим пользоваться!!!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)