none
ツリビューのエクスプローラ表示とリストビューからのファイル取得について RRS feed

  • 質問

  •  

    似たスレが直前にありますが…
    人様のスレッドに質問を投げかけるのも失礼かと思い、
    新しくスレッドを立てました。

    環境はC++/CLIです
    ツリービューで例えばCドライブの中身のファイルとサブディレクトリ
    を表示させようと思い、以下のプログラムを書いたのですが…


    String^ drive;
    DirectoryInfo^ di;
    TreeNode^ tn;
    int nindex;


    drive = "c:\\";
    tn = gcnew TreeNode(drive);
    treeView1->Nodes->Add(tn);

    nindex = treeView1->Nodes->IndexOf(tn);
    di = gcnew FileSystemInfo(drive);

    for each(FileSystemInfo^ dir in di->GetFileSystemInfo())
    {
     tn = gcnew TreeNode(dir->Name);
     treeView1->Nodes[nindex]->Nodes->Add(tn);
    }

    この場合ですとエラーが出てしまいます。
    GetFileSystemInfoメソッドを使えばフォルダのファイルやディクレトリ
    が取得出来るところまで理解しているのですが、

    うまく取り出すことが出来ずに困っています。
    演算子か何かの宣言がおかしいのでしょうか?

    2007年1月25日 12:36

回答

  • とりあえず、まともな件名をつけてください。

    >di = gcnew FileSystemInfo(drive);
    DirectoryInfo^の変数にFileSystemInfoのインスタンスを入れようとしていますが
    これであっていますか?

    di = gcnew DirectoryInfo(drive);

    なのでは?


    >GetFileSystemInfo
    ではなくGetFileSystemInfosでは?
    http://msdn2.microsoft.com/ja-jp/library/806sc8c5(VS.80).aspx

    2007年1月25日 15:01
  • ちなみに、DiectoryInfoクラスはFileSystemInfoクラスの派生クラス
    であるので、

    FileSystemInfo^ fsi = gcnew DiectoryInfo(L"C:\\");

    というのは出来ます。
    しかしながら、DiectoryInfoのメソッドを使うにはダウンキャストしなければ
    いけません。
    2007年1月26日 0:04
  • 蒼の洞窟さん貴重なアドバイスありがとうございます。

    返信が大変遅くなりましたことをお詫び申し上げます。

    あれから自分でいろいろ試して
    treeviewでフォルダを選択し、その選択されたフォルダのファイル一覧を
    listviewまで載せることができました。

    その後textboxを配置し、ファイル一覧が表示されてるlistviewの項目(Item)を
    ダブルクリックすることでtextboxに表示させるために以下のコードを記述しました。


     String^ Path;
     String^ ss;
     String^ txtss;
     String^ s1;
     String^ s2;
     String^ s3;


     if(treeView1->SelectedNode->FullPath->Length <=3)
     {
       s1 = treeView1->SelectedNode->FullPath->Substring(0,3);
       s2 = treeView1->SelectedNode->FullPath->Substring(3,(treeView1->SelectedNode->FullPath->Length - 3));
     }
     else
     {
      s1 = treeView1->SelectedNode->FullPath->Substring(0,3);
      s2 = treeView1->SelectedNode->FullPath->Substring(4,(treeView1->SelectedNode->FullPath->Length - 4));

     }
     s3 = listView1->SelectedItems[0]->Text;


     Path = s1 + s2 + s3;
     
     try{
       FileStream^ fs = gcnew FileStream(Path,FileMode::Open);

       StreamReader^ sr = gcnew StreamReader(fs,System::Text::Encoding::GetEncoding("Shift-JIS"));
       txtss = "";
      while(1){
         ss = sr->ReadLine();
         if( ss= nullptr)break;
         txtss = String::Concat(txtss, ss);
         txtss = String::Concat(txtss, "\r\n");
      }
      sr->Close();
      textBox1->Text = txtss;

     }
     catch(System::Exception^ e){
      MessageBox::Show(e->ToString());
     }

    これでエラーが出ることなく一応コンパイルは出来るのですが、
    項目をダブルクリックしてもtextboxに表示されず固まった状態になります

    どこか間違えているのでしょうか?

    2007年2月4日 12:17

すべての返信

  • とりあえず、まともな件名をつけてください。

    >di = gcnew FileSystemInfo(drive);
    DirectoryInfo^の変数にFileSystemInfoのインスタンスを入れようとしていますが
    これであっていますか?

    di = gcnew DirectoryInfo(drive);

    なのでは?


    >GetFileSystemInfo
    ではなくGetFileSystemInfosでは?
    http://msdn2.microsoft.com/ja-jp/library/806sc8c5(VS.80).aspx

    2007年1月25日 15:01
  • ちなみに、DiectoryInfoクラスはFileSystemInfoクラスの派生クラス
    であるので、

    FileSystemInfo^ fsi = gcnew DiectoryInfo(L"C:\\");

    というのは出来ます。
    しかしながら、DiectoryInfoのメソッドを使うにはダウンキャストしなければ
    いけません。
    2007年1月26日 0:04
  • 蒼の洞窟さん貴重なアドバイスありがとうございます。

    返信が大変遅くなりましたことをお詫び申し上げます。

    あれから自分でいろいろ試して
    treeviewでフォルダを選択し、その選択されたフォルダのファイル一覧を
    listviewまで載せることができました。

    その後textboxを配置し、ファイル一覧が表示されてるlistviewの項目(Item)を
    ダブルクリックすることでtextboxに表示させるために以下のコードを記述しました。


     String^ Path;
     String^ ss;
     String^ txtss;
     String^ s1;
     String^ s2;
     String^ s3;


     if(treeView1->SelectedNode->FullPath->Length <=3)
     {
       s1 = treeView1->SelectedNode->FullPath->Substring(0,3);
       s2 = treeView1->SelectedNode->FullPath->Substring(3,(treeView1->SelectedNode->FullPath->Length - 3));
     }
     else
     {
      s1 = treeView1->SelectedNode->FullPath->Substring(0,3);
      s2 = treeView1->SelectedNode->FullPath->Substring(4,(treeView1->SelectedNode->FullPath->Length - 4));

     }
     s3 = listView1->SelectedItems[0]->Text;


     Path = s1 + s2 + s3;
     
     try{
       FileStream^ fs = gcnew FileStream(Path,FileMode::Open);

       StreamReader^ sr = gcnew StreamReader(fs,System::Text::Encoding::GetEncoding("Shift-JIS"));
       txtss = "";
      while(1){
         ss = sr->ReadLine();
         if( ss= nullptr)break;
         txtss = String::Concat(txtss, ss);
         txtss = String::Concat(txtss, "\r\n");
      }
      sr->Close();
      textBox1->Text = txtss;

     }
     catch(System::Exception^ e){
      MessageBox::Show(e->ToString());
     }

    これでエラーが出ることなく一応コンパイルは出来るのですが、
    項目をダブルクリックしてもtextboxに表示されず固まった状態になります

    どこか間違えているのでしょうか?

    2007年2月4日 12:17
  • とりあえず、デバッグして確認するようなことはやりましょう。質問はその後です。

    私ならば、StreamReader::ReadToEndで全部読み込んでしまうか、
    System::IO::StreamReader^ sr = nullptr;
    
    this->textBox1->Clear();
    try
    {
        sr = gcnew System::IO::StreamReader(Path,
                           System::Text::Encoding::GetEncoding(L"shift-jis"));
    
        this->textBox1->Text = sr->ReadToEnd();
        this->textBox1->SelectionStart = 0;
    }
    catch (System::Exception^ ex)
    {
        System::Windows::Forms::MessageBox::Show(ex->Message);
    }
    finally
    {
        if (sr != nullptr)
            sr->Close();
    }
    ループするならListを使ってLinesプロパティに入れる。
    System::IO::StreamReader^ sr = nullptr;
    
    this->textBox1->Clear();
    try
    {
        System::String^ buff;
        sr = gcnew System::IO::StreamReader(Path,
                           System::Text::Encoding::GetEncoding(L"shift-jis"));
    
        System::Collections::Generic::List<String^> lines;
        while ((buff = sr->ReadLine()) != nullptr)
        {
            lines.Add(buff);
        }
        this->textBox1->Lines = lines.ToArray();
        this->textBox1->SelectionStart = 0;
    }
    catch (System::Exception^ ex)
    {
        System::Windows::Forms::MessageBox::Show(ex->Message);
    }
    finally
    {
        if (sr != nullptr)
            sr->Close();
    }
    

    ただし、この方法はShift_JISコードのテキストファイルでなければ正しく表示できませんけど。
    (ファイル名だけで、文字コードが何なのか、テキストファイルなのか等、判定することはほぼ無理です。)

    2007年2月4日 14:00
  • 原因がわかった。

    if( ss= nullptr)break;

    これでは比較ではなく代入しています。(VBとは違うよ)
    (おそらく、常に偽になって無限ループしている。)

    if (ss == nullptr) break;

    でしょう。

    txtss = String::Concat(txtss, ss);

    にブレイクポイントを置いて、ssがどんな文字列になっているか確認してみると
    すぐにわかるはずです。

    2007年2月4日 14:35
  • 蒼の洞窟さん,アドバイス有難うございます。

    おかけで解決できました。
    自分のうっかりミスでした。

    もう少し注意して見直します。

    2007年2月6日 7:51