none
ドラッグ&ドロップについてご教示ください。 RRS feed

  • 質問

  • いつもお世話になります。
    ドラッグ&ドロップについてご教示ください。
    Windows7、IE9、VisualStudio2010 Express C#という環境です。
    IE9でふつうに適当なWebページを開いて、そのリンクの部分をドラッグ&ドロップで受けようとしています。

    private void Form1_DragEnter (object sender, DragEventArgs e) {
     e.Effect = DragDropEffects.All;
    }

    private void Form1_DragDrop(object sender, DragEventArgs e) {
     if (e.Data.GetDataPresent("UniformResourceLocator")) {
      string dragPath = e.Data.GetData(DataFormats.Text).ToString();
     }
     else{
      string[] dragFilePathArray = (string[])e.Data.GetData(DataFormats.FileDrop, false);
     }
    }
    としています。

    これで、IEのURLを書いてあるところの小さなアイコンを受けとってそのURLを取得することはできるのですが、IEのウィンドウ内のリンク(下線の部分)をドラッグしても受けとった内容が空(null)になっています。
    どうすればリンクをデータとして受けとることができるのでしょう?
    ご教示いただければ幸いです。

    2013年7月22日 13:42

回答

  • Vista 以降、IE は保護モードで動いていることが大半だと思います。Windows 7 の IE も同様です。

    さて、DOBON.NET さんの記事 によると、「補足:Internet ExplorerからリンクをDrag&Dropしようとすると、マウスポインタが赤い丸に斜線が引かれたアイコンになり、ドロップできない場合があります。これはInternet Explorerが保護モードで実行されているためです。」とあり、保護モード(low integrity)のプロセスからはドロップできない制限があるようです。(他の情報ソース
    なお、保護モードが OFF になるローカルのファイル(例:c:\test\test.html)にハイパーリンクを設定した HTML ファイルを用意し、それを IE10(Win8) で開き、ハイパーリンクをドラッグ&ドロップすると、このスレッドで掲示されているソースコードで dragPath に URL が入ってくることを確認していますので、ソースコードレベルでの問題ではなく、IE のセキュリティのメカニズム的な課題であることがうかがえます。

    保護モードを解除すれば障害はなくなるようですが、通常のユーザーにそれを求めるのは酷ですので、自分しか使わないケース以外では回避策にならないとは考えています。
    (申し訳ないですが、なぜ URL 部分のアイコンとハイパーリンクで挙動が異なるのか、この制限を超えられるかどうかについては未調査です)

    2013年7月22日 22:25
    モデレータ

すべての返信

  •  「受け取った内容」とは、どれを指していますか?dragPath のことでしょうか?

     どのようにデバッグしましたか?
    DragDrop イベントが発生し、ハンドラ メソッドにきていますか?
    if (e.Data.GetDataPresent("UniformResourceLocator")) の結果は?
    その次の e.Data.GetData の結果は?


    Jitta@わんくま同盟

    2013年7月22日 13:59
  • Vista 以降、IE は保護モードで動いていることが大半だと思います。Windows 7 の IE も同様です。

    さて、DOBON.NET さんの記事 によると、「補足:Internet ExplorerからリンクをDrag&Dropしようとすると、マウスポインタが赤い丸に斜線が引かれたアイコンになり、ドロップできない場合があります。これはInternet Explorerが保護モードで実行されているためです。」とあり、保護モード(low integrity)のプロセスからはドロップできない制限があるようです。(他の情報ソース
    なお、保護モードが OFF になるローカルのファイル(例:c:\test\test.html)にハイパーリンクを設定した HTML ファイルを用意し、それを IE10(Win8) で開き、ハイパーリンクをドラッグ&ドロップすると、このスレッドで掲示されているソースコードで dragPath に URL が入ってくることを確認していますので、ソースコードレベルでの問題ではなく、IE のセキュリティのメカニズム的な課題であることがうかがえます。

    保護モードを解除すれば障害はなくなるようですが、通常のユーザーにそれを求めるのは酷ですので、自分しか使わないケース以外では回避策にならないとは考えています。
    (申し訳ないですが、なぜ URL 部分のアイコンとハイパーリンクで挙動が異なるのか、この制限を超えられるかどうかについては未調査です)

    2013年7月22日 22:25
    モデレータ
  • Jittaさん、ありがとうございます。
    受けとった内容とはeです。
    DragDropイベントは発生しています。
    if ()はfalseで、受けとったデータは、nullです。
    デバッグは、DragEnterとDragDropで一時停止を設定しておいて、IEからドラッグしました。
    2013年7月23日 10:19
  • Azuleanさん、ありがとうございます。
    まさにこの症状なので、C#の問題ではなく、保護モードの問題なのですね。
    すっきりしました。
    たしかに、保護モードを解除するのは、自分しか使わないとしても酷なので、ちょっとこれはあきらめたほうがよいと考えました。
    とりあえずURLの部分からはドラッグできるので、それで代替しようと思います。
    または、IEで表示している部分を、自前で取得してしまうようにします。
    ありがとうございました。
    2013年7月23日 10:20
  • nullになったのはDataFormats.FileDropでないからではありませんか? 具体的にdropされている形式を確認することが先決ではありませんか?
    2013年7月23日 11:55
  • nullになったのはDataFormats.FileDropでないからではありませんか? 具体的にdropされている形式を確認することが先決ではありませんか?

    実験するとわかるのですが、すべて null が得られます。

    private void Form2_DragDrop(object sender, DragEventArgs e)
    {
        StringBuilder sb = new StringBuilder();
        foreach (var format in e.Data.GetFormats())
        {
            object data = e.Data.GetData(format);
            sb.AppendFormat("{0} : is null? = {1}", format, (data == null));
            sb.AppendLine();
        }
        MessageBox.Show(sb.ToString());
    }

    こういったコードで保護モード ON の IE からハイパーリンクをドラッグ&ドロップすると、以下のような出力を得られます。

    UntrustedDragDrop : is null? = True
    msSourceUrl : is null? = True
    HTML Format : is null? = True
    DragImageBits : is null? = True
    DragContext : is null? = True
    System.String : is null? = True
    UnicodeText : is null? = True
    Text : is null? = True
    FileGroupDescriptor : is null? = True
    FileGroupDescriptorW : is null? = True
    FileContents : is null? = True
    UniformResourceLocator : is null? = True

    他方、ローカルに配置した HTML を使って、保護モード OFF のハイパーリンクをドラッグ&ドロップすると、以下のような出力を得られます。

    UntrustedDragDrop : is null? = False
    msSourceUrl : is null? = False
    HTML Format : is null? = False
    DragImageBits : is null? = False
    DragContext : is null? = False
    System.String : is null? = False
    UnicodeText : is null? = False
    Text : is null? = False
    FileGroupDescriptor : is null? = False
    FileGroupDescriptorW : is null? = False
    FileContents : is null? = True
    UniformResourceLocator : is null? = False

    このことから、保護モードの影響が本質的な原因であると考えています。
    (GetFormats で返せるように示しておいて、実際に取得すると null とかいじめに見えますが)

    もっとも、キャットリリスさんが示したソースコードは論理的に間違い(UniformResourceLocator があるかどうかを調べてから DataFormats.Text をもらうといったこと)があるらしいという点は否めないですが…。

    2013年7月23日 13:41
    モデレータ
  • コードが怪しいままはっきりとさせずに結論に達してしまったために突っ込んでしまいました。すみませんでした。

    ちなみに、手元のPCでIEからVisual StudioにURLをドラッグ&ドロップを試したところ成功したのでおかしいと思いました。しかしよくよく調べてみると、信頼済みサイトだったため保護モードで動作していませんでした orz

    2013年7月24日 1:16