NonSoft

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


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

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

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

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

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

★標準モジュール(Module1.vb)
Module Module1
    ' デリゲートの定義
    Private Delegate Function D_DropWndProc(ByVal hWnd As Integer, ByVal uMsg As Integer, _
        ByVal wParam As Integer, ByVal lParam As Integer) As Integer

    ' APIの定義
    Private Const WM_DROPFILES = &H233
    Private Const GWL_WNDPROC = -4
    Private Declare Sub DragAcceptFiles Lib "shell32.dll" _
        (ByVal hWnd As Integer, ByVal fAccept As Integer)
    Private Declare Sub DragFinish Lib "shell32.dll" _
        (ByVal HDROP As Integer)
    Private Declare Function DragQueryFile Lib "shell32.dll" Alias "DragQueryFileA" _
        (ByVal HDROP As Integer, ByVal UINT As Integer, _
         ByVal lpStr As String, ByVal ch As Integer) As Integer
    Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" _
        (ByVal lpPrevWndFunc As Integer, ByVal hWnd As Integer, _
         ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" _
        (ByVal hWnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
    Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" _
        (ByVal hWnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As D_DropWndProc) As Integer

    Private Msg_Proc As Integer    'メッセージ関数アドレスの保存
    Private Hook_hWnd As Integer   'ウインドウのハンドルの保存

    ' 別アプリケーション(ファイラ等)からのドロップ許可開始
    Public Sub DropStart(ByVal hWnd As Integer)
        If hWnd <> 0 Then
            If Msg_Proc <> 0 Then DropEnd()
            Hook_hWnd = hWnd
            Call DragAcceptFiles(Hook_hWnd, 1)
            Msg_Proc = SetWindowLong(Hook_hWnd, GWL_WNDPROC, AddressOf DropWndProc)
        End If
    End Sub

    ' 別アプリケーション(ファイラ等)からのドロップ許可終了
    Public Sub DropEnd()
        If Hook_hWnd <> 0 And Msg_Proc <> 0 Then
            Call SetWindowLong(Hook_hWnd, GWL_WNDPROC, Msg_Proc)
        End If
    End Sub

    ' メッセージ処理関数
    Private Function DropWndProc( _
        ByVal hWnd As Integer, ByVal uMsg As Integer, _
        ByVal wParam As Integer, ByVal lParam As Integer) As Integer
        If uMsg = WM_DROPFILES Then
            ' ファイルドロップのメッセージ
            Call DropFilesProc(wParam)
            Return 0
        Else
            ' その他のメッセージ
            Return CallWindowProc(Msg_Proc, hWnd, uMsg, wParam, lParam)
        End If
    End Function

    ' ファイルドロップ処理関数
    Private Sub DropFilesProc(ByVal hDropFile As Integer)
        Try

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

            Dim dropFiles As String() = New String(dropNum - 1) {}

            For i As Integer = 0 To dropNum - 1
                ' ドロップされたファイル/フォルダの取得
                Dim dropFile As String = New String("", 512)
                Call DragQueryFile(hDropFile, i, dropFile, 512)
                dropFiles(i) = dropFile

                ' ファイル/フォルダPATH文字列の後のNULLを削除
                Dim p As Integer = dropFiles(i).IndexOf(Chr(0))
                If p >= 0 Then dropFiles(i) = dropFiles(i).Substring(0, p)
            Next i

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

            ' ドロップされたファイル/フォルダの取得終了
            Call DragFinish(hDropFile)
        Catch

        End Try
    End Sub
End Module

★フォームモジュール(Form1.vb)
Public Class Form1
    ' フォーム・ロード
    Private Sub Form1_Load( _
        ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles MyBase.Load
        DropStart(TextBox1.Handle)
    End Sub

    ' フォーム・アンロード
    Private Sub Form1_FormClosed( _
        ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) _
        Handles Me.FormClosed
        DropEnd()
    End Sub

    ' テキストボックスへのファイルドロップ処理
    Public Sub Text1_DropFiles(ByVal files() As String)
        ' ファイル/フォルダPATHをテキストボックスへ設定
        ' このサンプルは1個だけ
        If UBound(files) >= 0 Then
            TextBox1.Text = files(0)
        End If
    End Sub
End Class