0

C++ Builder XE8 を使用しています。Androidでは動かないので、TOpenDialog自作しようと思っています。私の論理は非常に単純です。「/storage」からファイルとフォルダーのチェックを開始し、上のすべてのアイテムを表示しTListViewます。フォルダー (名前) に触れると、そのフォルダーが開き、ファイルに触れると、ラベルに名前が表示されます。TListViewそこで、の OnItemClickイベントに関数を割り当てました。

ここにコードがあります。fpath は文字列、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;
   }
}

以下は、ファイルとフォルダーをスキャンして表示する関数のコードです。stringlist は 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()、既存の行に行を追加するだけです。初心者なのでどこが悪いのかわかりません。

4

3 に答える 3

0

Clear メソッドを Item Text の更新に置き換えてから、ListView1Change イベント内の ListView の未使用の最後の行を削除することで、エラーを回避する別の方法を試しました。

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();

/* */
}
于 2016-07-16T11:38:17.220 に答える
0

TListViewこれまでに見つけた最良の方法は、新しいアイテムを追加するたびに動的に作成および削除することです(またはshowfiles関数を呼び出します)。release既に作成されている小さな関数 (refresh という名前) を作成TListViewし、別の関数 ( 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;
}

間違いを見つけた場合、またはより効率的に行うことができる場合はコメントしてください。

于 2016-03-03T10:30:24.467 に答える