⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mssubclass.bas

📁 使用API函数实现的文件的拖放
💻 BAS
字号:
Attribute VB_Name = "MSubclass"
  Option Explicit
  
  Public Const MAX_PATH As Long = 260&
  
  '标示我们要截获的消息
  Public Const WM_DROPFILES As Long = &H233&


  '保存原 窗体属性的变量,其实是默认的 窗体函数 的地址
  Public procOld As Long
  
  '
  Public Declare Function CallWindowProc& Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc&, _
                                                    ByVal hWnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)
                                                    
  '拖放操作相关的API函数
  Public Declare Sub DragAcceptFiles Lib "shell32.dll" (ByVal hWnd&, ByVal fAccept&)
                               
  Public Declare Function DragQueryFile& Lib "shell32.dll" Alias "DragQueryFileA" (ByVal hDrop&, ByVal iFile&, _
                                                                                  ByVal lpszFile$, ByVal cch&)
  Public Declare Sub DragFinish Lib "shell32.dll" (ByVal hDrop&)

'WARNING!!!!-----------------------------------------------------------
'注意这段代码是不能用DEBUG一步步调试的,否则会造成错误(崩溃)
'VB真绝,想看看回调过程是怎么实现的都不行
'对消息截获的机制可以按下述理解:
'    这里要仔细理解一下,我们为窗体新指定了窗体函数地址,也就是说操作系统发送给窗体的
'消息将被 WindowProc函数 所截获(而改变前消息是被默认的 窗体函数 所获得并作相应处理的)
'    这样我们在 WindowProc函数 中对所截获的消息进行判断,会有三种情况:
'<1>如果是需要通过程序来处理的消息就通过 WindowProc函数 中的相应语句处理;
'<2>如果是要原来的 窗体函数 来处理则把这个消息传递给原窗体函数(其实是指针指向的改变);
'<3>如果不是我们需要的消息,也传递给原 窗体函数 来处理。

    '可以参见 改变系统菜单 中的源码注释
'WARNING!!!!-----------------------------------------------------------

'回调函数,用来截取消息
Public Function WindowProc(ByVal hWnd As Long, ByVal iMsg As Long, _
                                              ByVal wParam As Long, ByVal lParam As Long) As Long
  
  '确定接收到的是什么消息
  Select Case iMsg
    
    '如果是 通知文件放下 的消息,就拦截消息
    Case WM_DROPFILES
      '通知在FORM模块中定义的DropFiles函数来接收 指向 放下的文件 的句柄
      frmDragDropFiles.DropFiles wParam
      
      '返回0并退出这个WindowProc
      WindowProc = False
      Exit Function
      
  End Select
  
  '如果不是我们需要的消息,则传递给原来的窗体函数处理
  WindowProc = CallWindowProc(procOld, hWnd, iMsg, wParam, lParam)

End Function

'---------------------相关内容-----------------------
'什么是子类派生技术
'    WINDOWS运行的基础是“消息机制”,所谓的“消息”是一个唯一的值,这个值会被一个窗体或操作系统
'收到,它能告诉什么事件发生了以及需要采用什么样的动作来响应。这与我们人类的神经系统将感知的信
'息传递给大脑,而大脑发出指令给我们的身体非常相似。
'    于是每一个窗体都具有一个消息句柄,这个机制使得所有发自于WINDOWS操作系统的消息能被接收到
'需要强调的是每个窗体以及每个控件,包括按钮、文本框、图片框等都具有这样的消息句柄。WINDOWS操
'作系统会跟踪这些消息句柄,这称为类结构中的一个WindowProc,所谓的类结构是于窗体句柄相关联的。
'    当我们加入一个新的WindowProc函数而这个WindowProc与原始的窗体函数相符合的话,我们称这个窗
'被子类化了。换言之,如果WINDOWS操作系统发给你所在的WindowProc一个消息,而你所在的WindowProc
'正在响应其它的动作,这时你必须将剩余的消息传递给一个默认的WindoProc。
'如下所示: 操作系统消息-->你所在WindoProc-->默认的WindoProc
'而一个窗体是可以被子类化多次的,这样就产生了如下的情况:
'Windows Message Sender --> Your WindowProc --> Another WindowProc _
'  --> Yet Another WindowProc --> Default WindowProc
' What is subclassing anyway?
'    通过窗体子类化,你可以改变响应消息的顺序,也就是说,你可以把消息传递到默认的WindowProc上
'而不立即响应。举个例子:
'    如果我们要在接收到WM_PAINT 消息后,在窗体上画出一些东西,可以用下面的语句实现:
'
' Public Function WindowProc(Byval hWnd, Byval etc....)
'
'   Select Case iMsg          '筛选出WM_PAINT消息
'     Case SOME_MESSAGE       '如果是其他消息
'       DoSomeStuff
'
'     Case WM_PAINT           '如果是WM_PAINT 消息
'       '首先把消息传递给一个默认的WindowProc
'       WindowProc = CallWindowProc(procOld, hWnd, iMsg, wParam, lParam)
'
'       DoDrawingStuff        '进行画图操作
'
'       Exit Function         '因为我们已经把消息传递给默认的WindowProc,我们可以退出这个WindowProc
'
'   End Select
'
' End Function
'------------------------------------------------------















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -