C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: listviewに表示されたフォルダ・ファイルの実行


(過去ログ 26 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■11305 / inTopicNo.1)  listviewに表示されたフォルダ・ファイルの実行
  
□投稿者/ mezon (1回)-(2007/12/12(Wed) 00:24:31)

分類:[C#] 

簡単なエクスプローラのようなものを作っています。

今、listview上に任意のフォルダ(マイドキュメント)を表示させるところまでできました。
この表示されたフォルダやファイルをダブルクリックしたら開くようにしたいです。

ソースコードです。

Form1.cs
*********************************************************************
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
using WinApi;

namespace Listview
{
	/// <summary>
	/// Form1 の概要の説明です。
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.ListView listView1;
		private System.Windows.Forms.ImageList imageList1;
		private System.Windows.Forms.ImageList imageList2;
		private System.ComponentModel.IContainer components;

		public Form1()
		{
			//
			// Windows フォーム デザイナ サポートに必要です。
			//
			InitializeComponent();

			//
			// TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
			//
		}

		/// <summary>
		/// 使用されているリソースに後処理を実行します。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
		/// コード エディタで変更しないでください。
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.listView1 = new System.Windows.Forms.ListView();
			this.imageList1 = new System.Windows.Forms.ImageList(this.components);
			this.imageList2 = new System.Windows.Forms.ImageList(this.components);
			this.SuspendLayout();
			// 
			// listView1
			// 
			this.listView1.Alignment = System.Windows.Forms.ListViewAlignment.Default;
			this.listView1.BackColor = System.Drawing.SystemColors.Window;
			this.listView1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
			this.listView1.Cursor = System.Windows.Forms.Cursors.Default;
			this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.listView1.Location = new System.Drawing.Point(0, 0);
			this.listView1.Name = "listView1";
			this.listView1.Scrollable = false;
			this.listView1.Size = new System.Drawing.Size(434, 344);
			this.listView1.TabIndex = 0;
			// 
			// imageList1
			// 
			this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
			this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// imageList2
			// 
			this.imageList2.ImageSize = new System.Drawing.Size(16, 16);
			this.imageList2.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// Form1
			// 
			this.AutoScale = false;
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
			this.BackColor = System.Drawing.SystemColors.HotTrack;
			this.ClientSize = new System.Drawing.Size(434, 344);
			this.ControlBox = false;
			this.Controls.Add(this.listView1);
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
			this.MaximizeBox = false;
			this.MinimizeBox = false;
			this.Name = "Form1";
			this.ShowInTaskbar = false;
			this.Text = "Icon ListView";
			this.TopMost = true;
			this.Load += new System.EventHandler(this.Form1_Load);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// アプリケーションのメイン エントリ ポイントです。
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		private IntPtr hImageSmall;
		private IntPtr hImageLarge;
		private int nIndex=0;

		private void GetFile()
		{
			nIndex  =0;
			foreach(string s in System.IO.Directory.GetFileSystemEntries(@"C:\Documents and Settings\Administrator\My Documents"))
			{
				Shell32.SHFILEINFO shfi=new Shell32.SHFILEINFO();
				FileInfo fi=new FileInfo(s);

				//32 x 32サイズのアイコンを取得
				hImageLarge=Shell32.SHGetFileInfo(s,0,ref shfi,(uint)Marshal.SizeOf(shfi),
					Shell32.SHGFI_ICON|Shell32.SHGFI_LARGEICON);
				imageList2.Images.Add(Icon.FromHandle(shfi.hIcon));

				//16 x 16サイズのアイコンを取得
				hImageSmall=Shell32.SHGetFileInfo(s,0,ref shfi,(uint)Marshal.SizeOf(shfi),
					Shell32.SHGFI_ICON|Shell32.SHGFI_SMALLICON);
				imageList1.Images.Add(Icon.FromHandle(shfi.hIcon));
				
				//リストビューにアイテムを追加
				listView1.Items.Add(
					new ListViewItem(
					new string[]{fi.Name,Directory.GetCreationTime(fi.FullName).ToString(),
									Directory.GetLastAccessTime(fi.FullName).ToString()}
					,nIndex++)
					);
			}
		}

		
		private void Form1_Load(object sender, System.EventArgs e)
		{
			//リストビューのヘッダを作成
			ColumnHeader ch1=new ColumnHeader();
			ch1.Text="File";
			ColumnHeader ch2=new ColumnHeader();
			ch2.Text="CreateDate";
			ColumnHeader ch3=new ColumnHeader();
			ch3.Text="AccessDate";

			//リストビューのヘッダ&イメージリスト&サイズ&ドッキング先の設定
			listView1.Columns.AddRange(new ColumnHeader[]{ch1,ch2,ch3});
			listView1.SmallImageList=imageList1;
			listView1.LargeImageList=imageList2;
			//listView1.Size=new Size(200,Size.Height);
			//listView1.Dock=DockStyle.Left|DockStyle.Bottom|DockStyle.Top;

			//2つのイメージリストのサイズ&色深度の設定
			imageList1.ImageSize=SystemInformation.SmallIconSize;
			imageList1.ColorDepth=ColorDepth.Depth32Bit;

			imageList2.ImageSize=SystemInformation.IconSize;
			imageList2.ColorDepth=ColorDepth.Depth32Bit;

			//ファイルの取得
			GetFile();
		}
	}
}

***************************************************************

Shell32.cs
***************************************************************
using System;
using System.Runtime.InteropServices;

namespace WinApi
{
	class Shell32
	{
		public const uint SHGFI_ICON=0x100;
		public const uint SHGFI_LARGEICON=0x0;
		public const uint SHGFI_SMALLICON=0x1;
		
		//typedef struct _SHFILEINFO {
		//    HICON hIcon;
		//    int iIcon;
		//    DWORD dwAttributes;
		//    TCHAR szDisplayName[MAX_PATH];
		//    TCHAR szTypeName[80];
		//} SHFILEINFO
		public struct SHFILEINFO
		{
			public IntPtr hIcon;
			public int iIcon;
			public uint dwAttributes;
			[MarshalAs(UnmanagedType.ByValTStr,SizeConst=260)]
			public string szDisplayName;
			[MarshalAs(UnmanagedType.ByValTStr,SizeConst=80)]
			public string szTypeName;
		}

		//DWORD_PTR SHGetFileInfo(
		//	LPCTSTR pszPath,
		//	DWORD dwFileAttributes,
		//	SHFILEINFO* psfi,
		//	UINT cbFileInfo,
		//	UINT uFlags
		//);
		[DllImport("shell32.dll")]
		public static extern IntPtr SHGetFileInfo(
			string pszPath,
			uint dwFileAttributes,
			ref SHFILEINFO psfi,
			uint cbFileInfo,
			uint uFlags
		);
			 
	}
}
**************************************************************


ネットで調べたところ、
System.Diagnostics.Process.startメソッドを使うところまではわかったのですが、
()のなかをどう記述したらよいのかがわかりません。

よろしくお願いします。

引用返信 編集キー/
■11496 / inTopicNo.2)  Re[1]: listviewに表示されたフォルダ・ファイルの実行
□投稿者/ ID非公開 (7回)-(2007/12/16(Sun) 01:57:19)
7回目の投稿です。

 はじめまして、ID非公開と申します。
私の回答の内容が的外れなものであるかもしれませんが、あらかじめご了承下さい。

 コードを拝見いたしましたところ、1点気になることがありました。それは、

  ファイル名のフルパス情報がListView内に保存されていない。

という点です。
 Process.Startの第1引数にファイル名をフルパスで渡すようにすればOKだと思います。
(例えばGetFile()内で生成したFileInfoインスタンスを破棄せずにどこかに保存する等で対応)

 P.S.多分、既に自己解決されていると思います。

 以上、取り急ぎご報告いたします。

以上です。

引用返信 編集キー/
■11683 / inTopicNo.3)  Re[2]: listviewに表示されたフォルダ・ファイルの実行
□投稿者/ arion (29回)-(2007/12/20(Thu) 07:17:48)
2007/12/20(Thu) 07:36:47 編集(投稿者)

>ネットで調べたところ、
>System.Diagnostics.Process.startメソッドを使うところまではわかったのですが、
>()のなかをどう記述したらよいのかがわかりません。


引用返信 編集キー/
■11684 / inTopicNo.4)  Re[2]: listviewに表示されたフォルダ・ファイルの実行
□投稿者/ mezon (2回)-(2007/12/20(Thu) 08:21:34)
>   ファイル名のフルパス情報がListView内に保存されていない。
>
> という点です。
>  Process.Startの第1引数にファイル名をフルパスで渡すようにすればOKだと思います。
> (例えばGetFile()内で生成したFileInfoインスタンスを破棄せずにどこかに保存する等で対応)
>
>  P.S.多分、既に自己解決されていると思います。
>
 
ありがとうございます。

まだ自己解決してないです。

string[] fileinfo = new string[20];
int i = 0;

を作成し、

GetFile()内のforeach()内の最後に

fileinfo[i] = fi.FullName;
i += 1;

という記述を加えました。

これでファイル名のフルパス情報を保存できたことになると思っているのですがこの考え方はあっていますでしょうか?


ダブルクリックイベントのときに

Process.Start(fileinfo[数字]);

と記述すると、ダブルクリックしたファイルに関係なく数字で指定したフォルダやファイルが開きます。

ダブルクリックしたフォルダやファイルに対応して実行させたいのですが、
どうすればよろしいでしょうか?





また新たな質問なのですが、

任意のフォルダ(マイドキュメント)をGetFileで読み込んだ後に、
listview上に、指定したフォルダだけを表示できないかと考えています。
表示させるフォルダの個数を指定できたりしたいと思っています。

このようなことはできるのでしょうか?

質問ばかりですいません。
どんな些細なことでもいいので教えてください。
引用返信 編集キー/
■11760 / inTopicNo.5)  Re[3]: listviewに表示されたフォルダ・ファイルの実行
□投稿者/ 引っ込んだID非公開 (1回)-(2007/12/21(Fri) 01:59:49)
2007/12/21(Fri) 22:42:13 編集(投稿者)
2007/12/21(Fri) 02:03:23 編集(投稿者)

11回目の投稿です。

 現在謹慎中の身ですが、
 分かる範囲でお答えいたします。


>これでファイル名のフルパス情報を保存できたことになると思っているのですがこの考え方はあっていますでしょうか?

 おっしゃるとおりです。
 ただ、ファイル名(フルパス)のみの保存ではもったいないと思います。
 私の個人的考えでは、

   String[]の代わりにList<Object>を用いたほうが良い   ←[追記]FileInfo自体を保存する
 
 と思います。理由は、
  1.ファイル数がいくつあっても対応可能
   (念のための補足:Listは、要素数を自由に変更可能な配列のようなものです)
  2.FileInfoにはファイル名以外の情報も保存されているので、今後の機能拡張に有利。
   (例えば、右クリックでファイルの詳細情報を表示する等)
   ※Object型で受ける理由は、
    FileInfoとDirectoryInfoとDriveinfoを全て格納できる型が、Objectしかないためです。

    再び念のための補足:
      FileInfoの基本クラスはFileSystemInfoで、
      DirectoryInfoの基本クラスもFileSystemInfoです。
      Driveinfoの基本クラスは、Objectです。
      ちなみに、FileSystemInfoの基本クラスの基本クラスは、Objectです。(オブジェクトブラウザで確認)
    もし、VC#2003をお使いであれば、
      List<T>が(私の記憶が正しければ)使用できないので、
      ArrayListを使用せざるを得ません。(Driveinfoもなかったですよね)
    VC#2005以降なら、
      「FileInfoとDirectoryInfoのみを格納できれば良い」という場合には、List<FileSystemInfo>でもOK。
      3者とも格納したい場合には、List<Object>を使用。(ArrayListでもOK)


 話が脱線しましたが、
 コードは例えばこのような感じです。(文法上の単純ミスがあるかもしれません)

using System.Collections.Generic;

private List<Object> allfileinfo = New List<Object>();

public void GetFile()
{
 allfileinfo.Clear();
 foreach(略)
 {
  FileInfo fi=new FileInfo(s);

  //いろいろな処理
  
  //nIndexやiは多分不要 [修正]左の記述を撤回します。必要です。
  allfileinfo.Add(fi);
 }
}

private void listView1_DoubleClick(略)
{
 int i=listView1.SelectedIndices[0]; //ダブルクリックしたファイルに対応する「数字」を取得
 string ss = ((FileSystemInfo)allfileinfo[i]).FullName;
 Process.Start(ss);
}


>任意のフォルダ(マイドキュメント)をGetFileで読み込んだ後に、
>listview上に、指定したフォルダだけを表示できないかと考えています。
>表示させるフォルダの個数を指定できたりしたいと思っています。
>このようなことはできるのでしょうか?
 
 私に考え付く範囲では、
   「//いろいろな処理」の部分でif文などを使って表示するものとしないものを振り分ける
 ことで十分対応可能です。


 以上、本日は時間切れなのでこれでご了承下さい。

 P.S.
  将来の発展の方向性として、
    ListViewに関する処理はListView内に書く
  とよいと思います。(あくまで個人的意見です)
  例えば、(単純な文法ミスがあるかもしれません)
public class ListViewEx : ListView
{
 private void this_load(略){
  //Form1_Load内の処理のうち、ListViewに関する処理をここに書く
 }
 public void GetFile(string directoryname){
  //中身は省略
 }
 private void this_doubleclick(略){
  //ダブルクリック時の処理(form側に書いても良い)
 }
}

public class form1 : form{
 //この例ではコードが全く不要
}
  ※あくまで、「将来の発展」なので、現在は読み飛ばしてもOKです。

 以上、取り急ぎご報告いたします。
 もしかするとまた的外れな内容を書いているかもしれませんが、その確率は低いです(多分)。

 追加のご質問等ありましたらまたどうぞ。おやすみなさい。

以上です。

引用返信 編集キー/
■11834 / inTopicNo.6)  Re[3]: listviewに表示されたフォルダ・ファイルの実行
□投稿者/ カンタービレ (135回)-(2007/12/21(Fri) 21:01:54)
2007/12/21(Fri) 21:03:52 編集(投稿者)
No11684 (mezon さん) に返信
> まだ自己解決してないです。
> 
> Process.Start(fileinfo[数字]);
> 
> と記述すると、ダブルクリックしたファイルに関係なく数字で指定したフォルダやファイルが開きます。
> 
> ダブルクリックしたフォルダやファイルに対応して実行させたいのですが、
> どうすればよろしいでしょうか?
> 
ちょっとだけ考えてみました。

@イベントハンドラの追加
    // InitializeComponent()内にイベントハンドラの追加
    this.listView1.DoubleClick += new EventHandler(listView1_DoubleClick);

AGetfile()メソッドの変更(引数を増やす+listviewとimagelistの初期化+サブアイテムに情報追加)
    private void GetFile(string path)
    {
        this.listView1.Clear();
        this.imageList1.Images.Clear();
        this.imageList2.Images.Clear();
        nIndex = 0;
        foreach(string s in System.IO.Directory.GetFileSystemEntries(path))

        //(中略)

        //リストビューにアイテムを追加
        listView1.Items.Add(
            new ListViewItem(
                new string[]{fi.Name,Directory.GetCreationTime(fi.FullName).ToString(),
                Directory.GetLastAccessTime(fi.FullName).ToString(),fi.FullName, fi.Attributes.ToString()}
                ,nIndex++)
        );

B追加したイベントハンドラの記述(ディレクトリだったら移動を試みてマス)
    void listView1_DoubleClick(object sender, EventArgs e)
    {
        ListViewItem ci = ((ListView)sender).SelectedItems[0];
        string spath = ci.SubItems[3].Text;
        // クリックされたのがディレクトリなら移動
        if (ci.SubItems[4].Text.Contains("Directory")) {
            GetFile(spath);
        }
        else {
            Process.Start(spath);
        }
    }

あぁぁぁでもディレクトリ先に進むとこれじゃ戻れないw
ということでちょっとだけじゃこの程度、色々な条件をクリアしないとデスね。
#本当にエクスプローラ風に移動しなくてもいいのかも知れませんが・・。

> 
> また新たな質問なのですが、
> 
> 任意のフォルダ(マイドキュメント)をGetFileで読み込んだ後に、
> listview上に、指定したフォルダだけを表示できないかと考えています。
> 表示させるフォルダの個数を指定できたりしたいと思っています。
> 
> このようなことはできるのでしょうか?
> 
> 質問ばかりですいません。
> どんな些細なことでもいいので教えてください。

GetFileメソッド上でいう変数のfi.AttributesでSystem.IO.FileAttributes.Directory属性があれば
フォルダだという判断が出来マス。
それを判断して後はカウントチェックとかすればよいかと思いマス。

引用返信 編集キー/
■11841 / inTopicNo.7)  Re[4]: listviewに表示されたフォルダ・ファイルの実行
□投稿者/ Jitta on the way (66回)-(2007/12/21(Fri) 22:39:22)
No11834 (カンタービレ さん) に返信
> それを判断して後はカウントチェックとかすればよいかと思いマス。

カンタービレさんじゃなく、質問者さんへ

何を根拠に数えましょう?
ここで取れるのは、ファイルのID(コマンドプロンプトでDIRしたとき)の順序だと思います。エクスプローラは、指定の順(いじってなければファイル名の昇順)に並べ替えています。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -