DragAcceptFiles(ByVal hwnd As Long, ByVal fAccept As Long)的作用是使一个窗口接收拖动过来的文件,hwnd是该窗口的句柄,fAccept在函数的C原型中是Bool类型,设为True表示使该窗口接收拖过来的文件,为False表示不接收。
DragQueryFiles(ByVal HDROP As Long, ByVal UINT As Long, ByVal lpStr As _ String, ByVal ch As Long)作用是查询拖动过来的文件名。HDOP是一个内部数据结构的地址,该结构中包含了Drag过来的文件名;UNIT是文件索引,若设为-1,则函数返回拖动过来的文件的数目;lpStr是以vbNULL结尾的字符串,用以接收返回的文件名;ch是lpStr 的缓冲区大小。
DragFinsish(ByVal hDrop As Long)释放Windows被分配用来向应用程序传送文件名的内存。
拖动文件时应用程序会接收到WM_DROPFILES消息,该消息的wParam中的数据为hDrop。程序中还要用到函数SetWindowLong(ByVal hwnd As Long, ByVal nIndex As Long,_ ByVal dwNewLong As Long),这个函数的用法很多,取决于参数nIndex,这里用到的值是GWL_WNDPROC,作用是重新指定一个窗口的窗口函数,返回该窗口原来的窗口函数, hwnd为要指定窗口函数的窗口句柄,dwNewLong为新窗口函数的地址。这个过程即常说的子类(SubClass)过程。拦截需要的消息后要把其余的消息发往默认的窗口函数时要用到 CallWindowProc(ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As_ Long, ByVal wParam As Long, ByVal lParam As Long),lpPrevWndFunc是默认窗口函数的地址,最后三个参数是消息参数。这个发送其余消息的过程非常重要,否则程序会不响应你的其它任何操作。
下面是一段示例代码,这是一个多文档记事本程序中的一部分:
模块中声明:
Public Declare Sub DragAcceptFiles Lib "shell32.dll" (ByVal hwnd As Long, ByVal fAccept As Long)
Public Declare Sub DragFinish Lib "shell32.dll" (ByVal hDrop As Long)
Public Declare Function DragQueryFile Lib "shell32.dll" Alias "DragQueryFileA" (ByVal hDrop As Long, ByVal UINT As Long, ByVal lpStr As String, ByVal ch As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const WM_DROPFILES = &H233
Public Const GWL_WNDPROC = (-4)
Public OldWndProc&
Public Sub NewtxtWndFunc(ByVal Hwndl&)
OldWndProc = SetWindowLong(Hwndl, GWL_WNDPROC, AddressOf txtWndProc)’返回 窗口的默认窗口函数的地址,以便恢复
End Sub
Public Sub OldtxtWndFunc(ByVal Hwndl&)' 恢复窗口的默认窗口函数
SetWindowLong Hwndl, GWL_WNDPROC, OldWndProc
End Sub
Public Function txtWndProc&(ByVal NewHwnd&,ByVal uMsg&, ByVal wParam&, ByVal lParam&)
Select Case uMsg
Case WM_DROPFILES
Dim Handle&, FileNameBuff$, Result&, hDrop&, FileNum&
Dim fLine$
hDrop = wParam
FileNameBuff = Space(100)
Result = DragQueryFile(hDrop, (-1), FileNameBuff, 100)'获得拖动的文件的数目
For I& = 0 To Result - 1
DragQueryFile hDrop, I, FileNameBuff, 100
xyOpenFile Trim(FileNameBuff)
Next
DragFinish hDrop
txtWndProc = 1
Case Else
txtWndProc = CallWindowProc(OldWndProc, NewHwnd, uMsg, wParam, lParam)
End Select
End Function
Public Function xyOpenFile(ByVal FN$) As Boolean
If BeUsed(MDIForm1.ActiveForm) Then
MDIForm1.MunNew_Click
End If
Dim FileNum&, fLine$
FileNum = FreeFile()
MDIForm1.ActiveForm.Caption = FN
Open FN For Input As #FileNum
fLine = StrConv(InputB(LOF(FileNum), #FileNum), vbUnicode)
MDIForm1.ActiveForm.Text1 = fLine
Close
End Function
在子窗口Form1中有一个Text1文本框,Form1的Load过程中代码如下:
Private Sub Form_Load()
DragAcceptFiles Text1.hwnd, True
NewtxtWndFunc Text1.hwnd
End Sub
习惯上要在窗口的退出过程中恢复窗口的默认窗口函数:
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
OldtxtWndFunc Text1.hwnd
End Sub