简体   繁体   English

在C ++ Builder XE 8(firemonkey)中手动创建TOpenDialog

[英]Creating TOpenDialog manually in C++ Builder XE 8 (firemonkey)

I am using C++ Builder XE8. 我正在使用C ++ Builder XE8。 As the TOpenDialog doesn't work on Android, I am trying to make such thing myself. 由于TOpenDialog在Android上不起作用,因此我尝试自己制作此类东西。 My logic is very simple. 我的逻辑很简单。 It'll start to check file and folders from "/storage" and show all items on TListView . 它将开始从“ / storage”检查文件和文件夹,并在TListView上显示所有项目。 If I touch a folder (name) it'll open that folder and if I touch a file, it should show the name on a label. 如果我触摸一个文件夹(名称),它将打开该文件夹;如果我触摸一个文件,它将在标签上显示该名称。 So I assigned a function to TListView 's OnItemClick event. 因此,我为TListViewOnItemClick事件分配了一个函数。

Here is code. 这是代码。 fpath is String, Label1 is showing current folder and Label2 is showing selected file. 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;
   }
}

Below is the code of function to scan for files & folders and show them. 以下是扫描文件和文件夹并显示它们的功能代码。 stringlist is TStringList. 字符串列表是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();

}

Here the problem is, if I use ListView1->ClearItems() in TForm1::showfiles it shows me an error saying "Access violation at address (random no), accessing address 00000009". 这里的问题是,如果我在TForm1 :: showfiles中使用ListView1->ClearItems() ,它将显示一个错误,提示“地址访问冲突(随机数),访问地址00000009”。 And if I dont use ClearItems() it just add more lines with already existed lines. 而且,如果我不使用ClearItems()那么只需添加更多已存在的行即可。 I am a beginer, so I dont know where I am doing wrong. 我是一个初学者,所以我不知道我在哪里做错了。

您应该使用:

ListView1->Items->Clear

The best way I have found so far is to dynamically create TListView and delete it each time you want to add new items( or calling showfiles function). 到目前为止,我发现的最好方法是动态创建TListView并在每次要添加新项(或调用showfiles函数)时将其删除。 I have written a small function (named it refresh) to release already created TListView and call another function(named it create_lview ) which can create an instance again then it calls the showfiles method. 我编写了一个小函数(命名为refresh)以release已经创建的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";
    }
  }
}

Here is the code to create the TListView whenever you want. 这是在需要时创建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;
}

Please comment if you find any mistake or you can do it more efficiently. 如果发现任何错误或可以更有效地进行处理,请发表评论。

I have tried another way to avoid the error by replacing the Clear method with updating the Item Text, then deletes the unused last row of the ListView within the ListView1Change event. 我尝试了另一种方法来避免错误,方法是使用更新项文本替换Clear方法,然后删除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();

/* */
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM