VC#でドラッグアンドドロップ時のカーソルの制御

このQ&Aのポイント
  • プログラミング初心者のため、VC#でドラッグアンドドロップ時のカーソルの制御方法について教えてください。
  • VC#でのファイル管理ソフトの作成に取り組んでいますが、ドラッグアンドドロップ機能に関して困っています。特定の拡張子以外のファイルをドラッグした時、カーソルを禁止のマークに変える方法を教えてください。
  • VC#を使用してファイル管理ソフトを作成していますが、ドラッグアンドドロップ時のカーソルの制御方法について教えてください。特定の拡張子以外のファイルをドラッグした時、カーソルを禁止のマークに変える方法が分かりません。
回答を見る
  • ベストアンサー

VC#でドラッグアンドドロップ時のカーソルの制御

プログラミング初心者です。 ファイル管理ソフトを作りたいなと、種々の言語を比較した結果VC#が一番やりやすいかなと思い、基礎知識もなくvisual studioをインストールしてあれこれ試行錯誤しながら、メニューやボタンやリストビューを作るところまでは行きました。ドラッグアンドドロップ機能を付けたいと思い、色々と検索してドラッグアンドドロップでlistView1に特定の拡張子のファイルを入れる下記のコードは見つかりました。さらに、特定の拡張子(ここでは.txt)以外のファイルをドラッグしてlistView1の領域に入った時、カーソルを禁止のマークに変えたいのですがそのコードがわかりません。ご教授いただければと存じます。 // もちろん基礎知識も平行して勉強しているところです。 // 下記のlistView1_DragEnterイベントハンドラ内に // if(ドラッグしたファイルの拡張子が.txt以外だったら){Cursor.Current = Cursors.No;} // とすると思い色々試したのですがうまくいきませんでした。(素人の試行錯誤なので提示できません) private void listView1_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Link; } } private void listView1_DragDrop(object sender, DragEventArgs e) { string[] handles = (string[])e.Data.GetData(DataFormats.FileDrop, false); foreach (string s in handles) { if (File.Exists(s)) { if (string.Compare(Path.GetExtension(s), ".txt", true) == 0) { AddFileToListview(s); } } else if (Directory.Exists(s)) { DirectoryInfo di = new DirectoryInfo(s); FileInfo[] files = di.GetFiles("*.txt"); foreach (FileInfo file in files) AddFileToListview(file.FullName); } } } private void AddFileToListview(string fullFilePath) { if (!File.Exists(fullFilePath)) return; string fileName = Path.GetFileNameWithoutExtension(fullFilePath); string dirName = Path.GetDirectoryName(fullFilePath); if (dirName.EndsWith(Convert.ToString(Path.DirectorySeparatorChar))) dirName = dirName.Substring(0, dirName.Length - 1); //hack off the trailing \ ListViewItem itm = listView1.Items.Add(fileName); itm.SubItems.Add(dirName); //second column = path }

  • ONEONE
  • お礼率68% (834/1223)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

惜しいです。 DragEnterではLinkを設定あともループを続けると,最後の物のみが有効になってしまいます。 対策としては,最初に見つかったらそのままreturnのが簡単です。 # 見た目上の対策として,U+0020二つをU+3000に置き換えています。使用時は逆変換して下さい。 private void listView1_DragEnter(object sender, DragEventArgs e) {  string[] fileName = (string[])e.Data.GetData(DataFormats.FileDrop, false);  foreach (string s in fileName)  {   if (File.Exists(s))   {    if (string.Compare(Path.GetExtension(s), ".txt", true) == 0)    {     e.Effect = DragDropEffects.Link;     return; // 後で処理する物があったらLinkを設定して終わり。    }   }   else if (Directory.Exists(s))   {    if (Directory.GetFiles(s, "*.txt").Length > 0) // DirectoryInfoを持ち出さなくてもOKで,条件は「存在すれば」なのでループで回さず,Lengthのみを見ている    {     e.Effect = DragDropEffects.Link;     return; // 後で処理する物があったらLinkを設定して終わり。    }   }  }  e.Effect = DragDropEffects.None; }

ONEONE
質問者

お礼

訂正ありがとうございます。 そうですね、やってて気づきました。こちらの回答に気づかず、自分であれこれと考えておりましたところ奇跡的にdirecotryにある*.txtのファイル数が>0ならばドラッグ可能にすればいいとわかり、こちらの回答とほぼ同じ内容に辿りつけました。 ただ、確かにreturnの処理に困っていたので大変ありがたかったです。 ありがとうございました。

その他の回答 (2)

回答No.2

根本的な部分は,「受け入れたくないならe.EffectにDragDropEffects.Noneを代入する」ことです。 今回の場合は,DragDropイベントでの走査と同じ事を行い, AddFileToListViewを呼び出すような状態になればe.EffectにLinkを設定し, そのような状況に一切ならなければNoneを設定するこことになります。

ONEONE
質問者

お礼

回答ありがとうございました!無事できたと思います。 一応他の人のためになるかもしれないのでコードを記しておきます。 private void listView1_DragEnter(object sender, DragEventArgs e) { string[] fileName = (string[])e.Data.GetData(DataFormats.FileDrop, false); foreach (string s in fileName) { if (File.Exists(s)) { if (string.Compare(Path.GetExtension(s), ".txt", true) == 0) { e.Effect = DragDropEffects.Link; } else if (Directory.Exists(s)) { DirectoryInfo di = new DirectoryInfo(s); FileInfo[] files = di.GetFiles("*.txt"); foreach (FileInfo file in files) e.Effect = DragDropEffects.Link; } else e.Effect = DragDropEffects.None; } } } private void listView1_DragDrop(object sender, DragEventArgs e) { e.Effect = DragDropEffects.None; string[] handles = (string[])e.Data.GetData(DataFormats.FileDrop, false); foreach (string s in handles) { if (File.Exists(s)) { if (string.Compare(Path.GetExtension(s), ".txt", true) == 0) { AddFileToListview(s); } } else if (Directory.Exists(s)) { DirectoryInfo di = new DirectoryInfo(s); FileInfo[] files = di.GetFiles("*.txt"); foreach (FileInfo file in files) AddFileToListview(file.FullName); } } } private void AddFileToListview(string fullFilePath) { if (!File.Exists(fullFilePath)) return; string fileName = Path.GetFileNameWithoutExtension(fullFilePath); string dirName = Path.GetDirectoryName(fullFilePath); if (dirName.EndsWith(Convert.ToString(Path.DirectorySeparatorChar))) dirName = dirName.Substring(0, dirName.Length - 1); //hack off the trailing \ ListViewItem itm = listView1.Items.Insert(0, fileName); itm.SubItems.Add(dirName); //second column = path }

回答No.1

e.GetDataPresentでFileDropを確認した後,e.GetDataでファイル名の一覧を取得し, 拡張子が.txtであればe.EffectにDragDropEffects.Linkを設定し, 設定していない場合はe.EffectにDragDropEffects.Noneを設定する, というので対応できませんか。

ONEONE
質問者

お礼

回答ありがとうございます。 とりあえず、下記のコードをlistView1_DragEnterイベントハンドラに来j通することで.txtでない場合は禁止マークが出るようになりました! string[] fileName = (string[])e.Data.GetData(DataFormats.FileDrop, false); if (Path.GetExtension(fileName[0]) == ".txt") e.Effect = DragDropEffects.Link; else e.Effect = DragDropEffects.None; しかし、これでは複数選択してドラッグしたファイル内に.txtと.txtで無いものが混じっていると全てのファイルが弾かれてしまいます。この場合には.txtだけ入れたいと考えています。どう条件付けすればいいのか加えて教えていただけないでしょうか?よろしくお願い致します。

関連するQ&A

  • ドラッグ&ドロップの対象をフォルダに限定したい

    こんばんは。 テキストボックスにドラッグ&ドロップされたフォルダのパスを取得させたいのですがドラッグの対象をフォルダに限定させたい、もしくはファイルがドラッグ&ドロップされたらそのファイルのカレントディレクトリまでのパスを取得させたいのですが、下記のコードでは取得までは出来るのですがファイルがきた場合にファイルまでのパスが取得されてしまいまいます。 よろしくお願いします。 Dim ddpath As String Private Sub TxtPath_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TxtPath.DragEnter If e.Data.GetDataPresent(DataFormats.FileDrop) Then e.Effect = DragDropEffects.Copy Else e.Effect = DragDropEffects.None End If End Sub Private Sub TxtPath_DragDrop(ByVal sender As Object, ByVal e As _System.Windows.Forms.DragEventArgs) Handles TxtPath.DragDrop ddpath = e.Data.GetData(DataFormats.FileDrop)(0) If Dir(ddpath, FileAttribute.Directory) <> "" Then TxtPath.Text = ddpath End If End Sub

  • C#での画像ファイルをドラッグアンドドロップで描画

    C#で画像ファイルをドラッグアンドドロップで描画させるプログラムを作りたいのですが、うまくできません。 ドラッグしたファイル名を読み取る部分までは動作確認できています。このファイル名の画像ファイルをForm1に描画させる部分でエラーになってしまいます。 どのように修正したらよいのかわからないのでお助けください。 ----- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Drag {   public partial class Form1 : Form   {     public Form1()     {       InitializeComponent();     }     private void Form1_DragEnter(object sender, DragEventArgs e)     {       e.Effect = DragDropEffects.All;     }     private void Form1_DragDrop(object sender, DragEventArgs e)     {       Graphics g = e.Graphics;   // <------ エラーになる。       if (e.Data.GetDataPresent(DataFormats.FileDrop))       {         foreach (string fileName             in (string[])e.Data.GetData(DataFormats.FileDrop))         {           g.DrawImage(new Bitmap(fileName, new PointF(10F, 50F)));           // Console.WriteLine(fileName); // 動作確認         }       }     }   } }

  • VC++2005 windowsフォームアプリでドラッグ&ドロップを実現する方法

    お世話になっております。 表題についていろいろ調べたのですがエラーの解決方法が見つからないため、質問させてください。 環境はVC++2005 CLD windowsフォームアプリケーション です。 貼り付けたリストボックスにtxtファイルをドラッグドロップして中身を取り出したいのですが、dragdrop関数内で、ファイルのパスを抜き出す部分でエラーが解決できません。 環境に合わせて下記のようなdragdrop関数を作成中です。 System::Void Form1::commandListBox_DragDrop(System::Object^ sender, System::Windows::Forms::DragEventArgs^ e) { if(e ->Data ->GetDataPresent(DataFormats::FileDrop)){ // ファイルドロップのとき std::string files[] = (std::string[])(e->Data->GetData(DataFormats::FileDrop)); } } 最後の行はMSDNなどで書かれていた string[] files = (string[])(e.Data.GetData(DataFormats.FileDrop)); となっている部分を参考にしているつもりですが、この部分で下記のエラーがでます。 1>.\mySrc\tab0.cpp(45) : error C2440: '型キャスト' : 'System::Object ^' から 'std::string []' に変換できません。 1> 配列型への変換はありませんが、参照またはポインタから配列への変換があります。 1>.\mySrc\tab0.cpp(45) : error C2075: 'files' : 配列の初期化には中かっこ ({}) が必要です。 このエラーの解決方法か、ドラッグドロップしたファイルのパスを取得する方法をご教授頂ければ幸いでございます。 よろしくお願いいたします。

  • 【C# 2010】 テキストへのドラック&ドロップ

    VisualStudio C#2010 Express の環境で、テキストボックスにエクスプローラからフォルダを指定(複数)して、ドラック&ドロップすると、そのフォルダのフルパスをテキストボックスへ表示させるアプリケーションを作成しております。 調べながら作成し、フォルダのフルパスをテキストボックスへ表示させられるようになったのですが、わからない点として、複数のフォルダを指定しても、テキストボックスに表示されるのは1フォルダ分のフルパスだけになってしまうという点です。 テキストボックス側のプロパティで、複数行で表示させる設定(Multiline)は有効(True)にしてありますし、ユーザーがドラックしたデータを受け入れるかの設定(AllDrop)も有効にしてあります。 その他、気づいた点として、☆ ドロップイベントの配列(pass)には指定したフォルダ分のフルパスが格納されていますが、textbox1.Text = pass[i] の部分で全てのフルパスがテキストに表示されません。 原因を考えましたが、どうしてもわからなかったので、どなたかお分かりになられる方がいらっしゃい ましたら、ご教授のほどお願いできますでしょうか? 何卒、よろしくお願いいたします。 ----------------------------------------------------------------------------- public Form1() { InitializeComponent(); this.textBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.textBox1_DragDrop); this.textBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.textBox1_DragEnter); } // ☆ ドラッグイベント private void textBox1_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.All; else e.Effect = DragDropEffects.None; } // ☆ ドロップイベント private void textBox1_DragDrop(object sender, DragEventArgs e) { string[] pass = (string[])e.Data.GetData(DataFormats.FileDrop, false); int i; for (i = 0; i < pass.Length; i++) { textBox1.Text = pass[i]; } }

  • ファイルをドラッグドロップでTextBooxにファイル名を出したい

    下記のサンプルコードをWEBサイトで見つけたので ListBox1というところをTextBox1と直して テキストボックスにファイルのフルパスが出るように したかったのですが、Listbox1だと正常なのですが、 TextBox1に変更すると動作しなくなってしまいます。 最後の部分の ListBox1.Items.AddRange(e.Data.GetData(DataFormats.FileDrop))は TextBox1.Text=e.Data.GetData(DataFormats.FileDrop) に変更してあります。 正常に動作するにはどこを直したらよいか教えて頂きたいです。 宜しくお願いします。m(__)m --------------------------------------------------- Private Sub ListBox1_DragEnter(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DragEventArgs) _ Handles ListBox1.DragEnter '関連連づけの確認をしています。 'この場合、ドラッグアンドドロップの形式であるかどうか? If e.Data.GetDataPresent(DataFormats.FileDrop) Then 'ドロップ効果を取得 e.Effect = DragDropEffects.Copy Else 'ドロップ効果を破棄 e.Effect = DragDropEffects.None End If End Sub Private Sub ListBox1_DragDrop(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DragEventArgs) _ Handles ListBox1.DragDrop 'DragEnterイベントで、取得した情報を追加 ListBox1.Items.AddRange(e.Data.GetData(DataFormats.FileDrop)) End Sub

  • C#でドラッグ&ドロップが機能しない。

    使用OSはWindows8で 開発環境はVisualStudio2012 (.NET Framework4.5)です。 ListBox1にドラッグ&ドロップでファイル名を表示する機能を追加したいと思い、以下のようなコードを記述しました。また、ListBox1のイベントととしてListBox1ListBox1_DragEnterとListBox1_DragDropを関連づけました。 この状態でビルドして動作を確認してみると、問題なく動作しました しかし、debugフォルダ内のEXEファイルを直接起動するとドラッグ&ドロップ不可のマークが出てしまいます。 なにが問題が問題なのか分からず困っています。ご回答お願いします。 private void Form1_Load(object sender, EventArgs e) {   this.AllowDrop = true;   ListBox1.AllowDrop = true; } private void ListBox1_DragEnter(object sender,System.Windows.Forms.DragEventArgs e) {   e.Effect = DragDropEffects.Copy; } private void ListBox1_DragDrop(object sender,System.Windows.Forms.DragEventArgs e) {   string[] fileName =(string[])e.Data.GetData(DataFormats.FileDrop, false);   ListBox1.Items.AddRange(fileName); }

  • ドラッグドロップ(AllowDrop)について

    Form1にドラッグドロップ機能を導入しようと思い AllowDropプロパティをTrueにしてDragDropイベントとDragEnterイベントを記述しました。 実際にデバックしてみるとうまく機能して安心したのですが 後で、bin/debug/AAA.exeを直接クリックしてみるとなぜか機能しません。 MyBase.LoadイベントにMyBase.AllowDrop=Trueと記述してみたいのですがダメでした。 何か設定が間違ってるのでしょうか? ぜひご回答お願いします。 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load   MyBase.AllowDrop = True End Sub Private Sub drag_drop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop   Dim list As String() = CType(e.Data.GetData(DataFormats.FileDrop, False), String())   For Each a In list      MsgBox(a)   Next End Sub Private Sub drag_enter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragEnter   e.Effect = DragDropEffects.Copy End Sub

  • DragEnterイベントについて(VS2008、ドラッグ&ドロップ)

    VisualStudio2008 C# で開発をしています。 ListViewにエクスプローラーからファイルをドラッグ&ドロップしようとしているのですが、うまくできません。 いろいろと調べて下記の3点を抑えればできるのかと思っていますが、思ったように動きません。 ListViewのAllowDrop=True; DragEnterイベントでe.Effect = DragDropEffects.Copy; DragDropイベントでDropした後の処理 きちんと記述しているつもりですが、DragEnterイベントが発生しません。 ちなみに、同じListViewの要素をドラッグ&ドロップするとDragEnterイベントは発生するので、あくまで外部(エクスプローラーなど)からドラッグされたものが受け付けないようです。 何が原因なのでしょうか? ほかに設定などあるのでしょうか?

  • C# 使用されたパラメーターが有効では~の対策は?

    C#の勉強を始めました。 ネットでコードを見つけては参考にさせていただいています。 以下のコードでエラーが出るのですが、解決策をお教えください。 Bitmap bitmap = new Bitmap(fName); ← ここでエラー エラー内容 ユーザーが処理していない例外 System.ArgumentException:使用されたパラメーターが有効ではありません /////////////////////////////// namespace WindowsFormsApp21 { public partial class Form1 : Form { private void listView1_DragEnter(object sender, DragEventArgs e) { e.Effect = DragDropEffects.All; } private void listView1_DragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] drags = (string[])e.Data.GetData(DataFormats.FileDrop); foreach (string d in drags) { ・ ・     ・ string[] ar = new string[] { }; foreach (string fName in System.IO.Directory.GetFiles(d)) { ar = fName.Split('.'); if (ar.Length > 1) { string str = ar[ar.Length - 1]; if (str.ToUpper().Equals("JPG")) { Bitmap bitmap = new Bitmap(fName); ← ここでエラー int[] pils = bitmap.PropertyIdList; int index = Array.IndexOf(pils, 0x9003); //撮影日付 if (index == -1) { MessageBox.Show("no date in " + fName); continue; } PropertyItem pi = bitmap.PropertyItems[index]; string date = Encoding.ASCII.GetString(pi.Value, 0, 19); date = date.Replace(':', '-').Replace(' ', '_'); string newName = date + ".jpg"; bitmap.Dispose();       ・       ・       ・ } } } } e.Effect = DragDropEffects.Copy; } } }

  • VB.NETのDrag&Dropでペイントが起動してしまう。

    VB.NETにてDrag&Dropでbmpファイルをピクチャーボックスに 表示させようと思い、こちらで他の方が質問されていた ソースを加工してテストしています。 画像ファイルをexplolerで掴んでピクチャーボックスの 上まで持ってくるとDragEnterイベントでアクセサリの ペイントが起動してしまってそこで処理が止まってしまっています。 ブレークポイントを置いてみると e.Data.GetDataPresentで起動してるようです。 ペイントが起動しないようにしたいのですが どうすればいいのでしょうか? どなたかよろしければご教授お願いいたします。 使用ツール:VS2005 OS:WinXpSP2 使用しているソース: Private Sub pict1_DragEnter(ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.DragEventArgs) Handles picturebox1.DragEnter   If e.Data.GetDataPresent(DataFormats.FileDrop) Then e.Effect = DragDropEffects.Copy End If End Sub