【问题标题】:Creating TOpenDialog manually in C++ Builder XE 8 (firemonkey)在 C++ Builder XE 8 (firemonkey) 中手动创建 TOpenDialog
【发布时间】:2016-02-15 17:34:19
【问题描述】:

我正在使用 C++ Builder XE8。由于TOpenDialog 不适用于Android,我正在尝试自己制作这样的东西。我的逻辑很简单。它将开始检查“/storage”中的文件和文件夹,并显示TListView 上的所有项目。如果我触摸一个文件夹(名称),它将打开该文件夹,如果我触摸一个文件,它应该在标签上显示名称。所以我给TListViewOnItemClick事件分配了一个函数。

这里是代码。 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();

}

这里的问题是,如果我在 TForm1::showfiles 中使用ListView1-&gt;ClearItems(),它会显示一条错误消息“地址访问冲突(随机否),访问地址 00000009”。如果我不使用ClearItems(),它只需添加更多已存在行的行。我是初学者,所以我不知道我做错了什么。

【问题讨论】:

    标签: android firemonkey tlistview c++builder-xe8


    【解决方案1】:

    你应该使用:

    ListView1->Items->Clear
    

    【讨论】:

    • 我也用过.. @Nompa 但有同样的问题。
    【解决方案2】:

    到目前为止,我发现的最好方法是动态创建 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;
    }
    

    如果您发现任何错误,请发表评论,或者您可以更有效地做到这一点。

    【讨论】:

      【解决方案3】:

      我尝试了另一种避免错误的方法,方法是用更新项目文本替换 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();
      
      /* */
      }
      

      【讨论】:

        猜你喜欢
        • 2011-05-08
        • 1970-01-01
        • 2016-06-22
        • 2023-04-07
        • 1970-01-01
        • 2014-08-22
        • 1970-01-01
        • 2012-05-24
        • 1970-01-01
        相关资源
        最近更新 更多