2016-02-15 4 views
0

Я использую C++ Builder XE8. Поскольку TOpenDialog не работает на Android, я сам пытаюсь это сделать. Моя логика очень проста. Он начнет проверять файлы и папки из «/ storage» и покажет все элементы на TListView. Если я коснусь папки (имя), она откроет эту папку, и если я коснусь файла, она должна показать имя на ярлыке. Поэтому я назначил функцию TListViewOnItemClick.Создание TOpenDialog вручную в C++ Builder XE 8 (firemonkey)

Вот код. fpath - String, Label1 показывает текущую папку, а Label2 показывает выбранный файл.

void __fastcall TForm1::lviewitemclck(TObject * const Sender, TListViewItem * const AItem) 
{ 
if (AItem->Text == "<< BACK") { 
     if (!fpath.LastDelimiter("/") == 0) { 
      fpath = fpath.SubString(0, fpath.LastDelimiter("/")); 

      Label1->Text = fpath; 
      Form1->showfiles(fpath); 
     } 
    } 
    else if (DirectoryExists(fpath+ AItem->Text)) { 
      fpath = fpath+ AItem->Text; 

      Label1->Text = fpath; 
      Form1->showfiles(fpath); 
    } 
    else if (FileExists(fpath+ AItem->Text)) { 
     Label2->Text ="File: "+ fpath+ AItem->Text; 
    } 
} 

Ниже приведен код функции для поиска файлов & папок и показать их. Строковый список - TStringList.

void __fastcall TForm1::showfiles (String path) 
{ 

TSearchRec sr; // for scaning files and folders 
TSearchRec fr; // to check whether the folder is accessible or not. 

if (FindFirst(path+"/*", faAnyFile, sr) == 0) 
    { 
     stringlist->Clear(); 
     stringlist->Add("<< BACK"); // being used to replace the ".." 

     do{ 
      if(sr.Name != "." && sr.Name != ".."){ 

        if (DirectoryExists(path+"/"+sr.Name)) { 
         if (FindFirst(path+"/"+sr.Name+"/*", faAnyFile, fr) == 0) { // to check if the folder is accessible 
          stringlist->Add("/"+ sr.Name); 
         } 
         FindClose(fr); 
        } 
        else{ 
         stringlist->Add("/"+ sr.Name); 
        } 

      } 
     } while (FindNext(sr) == 0); 
    } 
    FindClose(sr); 

    stringlist->Sort(); 

    Form1->Item->Free(); 

    Form1->ListView1->BeginUpdate(); 

    Form1->ListView1->ClearItems(); 

for(int i =0;i< stringlist->Count; i++){ 
    Form1->Item = Form1->ListView1->Items->Add(); 
    Form1->Item->Text = stringlist->Strings[i]; 
} 
Form1->ListView1->EndUpdate(); 

} 

Здесь проблема, если я использую ListView1->ClearItems() в TForm1 :: showfiles он показывает мне ошибку говоря «Нарушение прав доступа по адресу (случайный нет), доступ к адресу 00000009». И если я не использую ClearItems(), он просто добавит больше строк с уже существующими линиями. Я начинаю, поэтому я не знаю, где я ошибаюсь.

ответ

0

Вы должны использовать:

ListView1->Items->Clear 
+0

Я использовал его тоже .. @Nompa но имеющий ту же проблему. – Jit9

0

Лучшим способом я нашел до сих пор являюсь динамически создавать TListView и удалять его каждый раз, когда вы хотите добавить новые элементы (или вызывая функцию showfiles). Я написал небольшую функцию (называемую ее обновлением) до release уже созданной TListView и вызываю другую функцию (с именем it create_lview), которая может снова создать экземпляр, затем вызывает метод showfiles.

void __fastcall TForm1::refresh() 
{ 
if (!lview1->Released()) { 
    try{ 
    lview1->Release(); 
    Form1->create_lview(); 
    Form1->showfiles(fpath); 
} 
catch(...){ 
    Label2->Text = "error in cleaning"; 
    } 
    } 
} 

Вот код для создания TListView всякий раз, когда вы хотите.

void __fastcall TForm1::create_lview() 
{ 
    lview1 = new TListView(Form1); 
    lview1->Parent = Form1; 
    lview1->Height = 600; 
    lview1->Width = 400; 
    lview1->Position->X = 0; 
    lview1->Position->Y = 0; 
    lview1->Visible = true; 
    lview1->Enabled = true; 
    lview1->OnItemClick = lviewitemclck; 
    lview1->CanSwipeDelete = false; 
} 

Прокомментируйте, если вы обнаружили ошибку или можете сделать это более эффективно.

0

Я пробовал другой способ избежать ошибки, заменив метод Clear на обновление текстового элемента, а затем удаляет неиспользуемую последнюю строку ListView в событии ListView1Change.

void __fastcall TForm1::ListView1Change(TObject *Sender) 
{ 
    //Delete last item 
    while (ListView1->Items->Count>stringlist->Count){ 
    ListView1->Items->Delete(ListView1->Items->Count-1); 
    } 
} 

void __fastcall TForm1::showfiles (String path) 
{ 


TSearchRec sr; // for scaning files and folders 
TSearchRec fr; // to check whether the folder is accessible or not. 
      //path+PathDelim+ 

if (FindFirst(path+PathDelim+'*', faAnyFile, sr) == 0) 
    { 
     stringlist->Clear(); 
     stringlist->Add("<<--BACK"); // being used to replace the ".." 

     do{ 
      if(sr.Name != "." && sr.Name != ".."){ 

        if (DirectoryExists(path+PathDelim+sr.Name)) { 
         if (FindFirst(path+PathDelim+sr.Name+PathDelim+"*", faAnyFile, fr) == 0) { // to check if the folder is accessible 
          stringlist->Add(sr.Name); 

         } 
         FindClose(fr); 
        } 
        else{ 
         stringlist->Add(sr.Name); 
        } 

      } 
     } while (FindNext(sr) == 0); 
    } 
    FindClose(sr); 

    stringlist->Sort(); 

    for(int i =0;i< ListView1->Items->Count; i++){ 
    ListView1->Items->Item[i]->Text=""; 
    } 



ListView1->BeginUpdate(); 
try { 


     for(int i =0;i< stringlist->Count; i++) 
     { 
      if (ListView1->Items->Count-1<i) 
      { 
      TListViewItem* Item=ListView1->Items->Add(); 
      Item->Text=stringlist->Strings[i]; 
      } else 
      { 
      TListViewItem* Item=ListView1->Items->Item[i]; 
      Item->Text=stringlist->Strings[i]; 

      } 
     } 

    } 
catch (...) { 
      } 


ListView1->EndUpdate(); 

/* */ 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^