NonSoft

別EXEからのファイル ドロップを受け取る
サンプル(C#.NET)


 サンプル(ソース/コード)
<このサンプルの概要>
このサンプルは、別アプリケーション(ファイラ等)からのファイルドロップを受け付ける
C#.NET版のサンプルです。

AllowDropをTrueにしてDragEnterとDragDropを実装しても、
別アプリケーション(ファイラ等)からのファイルドロップを受け取れませんので、
DragAcceptFilesによりファイルドロップを受け取れるようにアピールし、
ドロップされたファイルをDragQueryFileで取得する必要があります。

VB6版はこちらです。
別EXEからのファイル ドロップを受け取るサンプル(VB6)

VB.NET版はこちらです。
別EXEからのファイル ドロップを受け取るサンプル(VB.NET)

このサンプルを使用したツールは以下のものがあります。ファイラーを使用している方からファイラから
送ったファイルを受け取れるようにして欲しいと言う要望があり、実装しました。
フォルダ内のファイル比較ツール
テキスト差分表示ツール

★クラスモジュール(Class1.cs)
class Class1
{
    // デリゲートの定義
    private delegate int D_DropWndProc(int hWnd, int uMsg, int wParam, int lParam);

    // APIの定義
    private const int WM_DROPFILES = 0x233;
    private const int GWL_WNDPROC = -4;
    [System.Runtime.InteropServices.DllImport("shell32.dll")]
    extern static void DragAcceptFiles(int hWnd, int fAccept);
    [System.Runtime.InteropServices.DllImport("shell32.dll")]
    extern static void DragFinish(int HDROP);
    [System.Runtime.InteropServices.DllImport("shell32.dll")]
    extern static int DragQueryFile(int HDROP, int UINT, StringBuilder lpStr, int ch);
    [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "CallWindowProcA")]
    extern static int CallWindowProc(int lpPrevWndFunc, int hWnd, int msg, int wParam, int lParam);
    [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowLongA")]
    extern static int SetWindowLong(int hWnd, int nIndex, int dwNewLong);
    [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowLongA")]
    extern static int SetWindowLong(int hWnd, int nIndex, D_DropWndProc dwNewLong);

    private static int Msg_Proc;    // メッセージ関数アドレスの保存
    private static int Hook_hWnd;   // ウインドウのハンドルの保存
    private static Form1 _frm;     // 親ウィンドウオブジェクト

    // 別アプリケーション(ファイラ等)からのドロップ許可開始
    public static void DropStart(int hWnd, Form1 frm)
    {
        if( hWnd != 0 ){
            _frm = frm;
            if( Msg_Proc != 0 ) DropEnd();
            Hook_hWnd = hWnd;
            DragAcceptFiles(Hook_hWnd, 1);
            Msg_Proc = SetWindowLong(Hook_hWnd, GWL_WNDPROC, DropWndProc);
        }
    }

    // 別アプリケーション(ファイラ等)からのドロップ許可終了
    public static void DropEnd()
    {
        if( Hook_hWnd != 0 && Msg_Proc != 0 ){
            SetWindowLong(Hook_hWnd, GWL_WNDPROC, Msg_Proc);
        }
    }

    // メッセージ処理関数
    private static int DropWndProc(int hWnd, int uMsg, int wParam, int lParam)
    {
        if (uMsg == WM_DROPFILES)
        {
            // ファイルドロップのメッセージ
            DropFilesProc(wParam);
            return 0;
        }
        else
        {
            // その他のメッセージ
            return CallWindowProc(Msg_Proc, hWnd, uMsg, wParam, lParam);
        }
    }

    // ファイルドロップ処理関数
    private static void DropFilesProc(int hDropFile)
    {
        try
        {

            // ドロップされたファイル/フォルダ数を取得
            int dropNum;
            dropNum = DragQueryFile(hDropFile, -1, null, 0);

            String[] dropFiles = new String[dropNum];

            for (int i = 0; i <= dropNum - 1; i++)
            {
                // ドロップされたファイル/フォルダの取得
                StringBuilder dropFile = new StringBuilder(512);
                DragQueryFile(hDropFile, i, dropFile, 512);
                dropFiles[i] = dropFile.ToString();

                // ファイル/フォルダPATH文字列の後のNULLを削除
                int p = dropFiles[i].IndexOf((char)0);
                if (p >= 0) dropFiles[i] = dropFiles[i].Substring(0, p);
            }

            // ファイル/フォルダPATHをテキストボックスへ設定
            _frm.Text1_DropFiles(dropFiles);

            // ドロップされたファイル/フォルダの取得終了
            DragFinish(hDropFile);
        }
        catch { }
    }

}

★フォームモジュール(Form1.cs)
public partial class Form1 : Form
{
    // フォーム・ロード
    private void Form1_Load(object sender, EventArgs e)
    {
        Class1.DropStart((int)textBox1.Handle, this);
    }

    // フォーム・アンロード
    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        Class1.DropEnd();
    }

    // テキストボックスへのファイルドロップ処理
    public void Text1_DropFiles(String[] files)
    {
        // ファイル/フォルダPATHをテキストボックスへ設定
        // このサンプルは1個だけ
        if (files.Length > 0)
        {
            textBox1.Text = files[0];
        }
    }
    public void a() { }
}