符串,用以接收返回的文件名;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
这个程序支持多个文件的拖动,BeUsed(Byval hwnd1)是一个自己编的函数,用于测试hwnd1这个窗口是否已用于打开其他的文件。MDIForm1是一个多文档窗口。DragQueryFile中的文件名缓冲区一定要足够大,否则VB会出现“一般保护性错误(GPF)”(Global Protection Failure)而把程序连同VB一起关掉,当初我设为20,就老是出现这样的现象,还无法通过调试查其确切原因,VB中使用API经常会因为传入参数类型不对或缓冲区太小而出现GPF,大家使用的时候要小心注意,调试前及时存盘。
这个小程序只是一个引子,和拖动相关的函数还有 ragObject()、DragDelect()、 DragQueryPoint(),第一个是拖动一个对象,后两个是测试拖动点的,这样可以实现 Netants的链接拖动功能。希望这个程序能给你一点小的帮助。
|