子类调用的一些总结
2005-10-20 18:21
204 查看
今天遇到个问题:VB中的子类技术(Sub-Class)。经过查阅一些资料了解到,这是一种挂钩技术(Hook)。主要通过两个API来实现,CallWindowProc和SetWindowLong。
SetWindowLong函数的作用是在窗口结构中为指定的窗口设置属性,利用它我们来改变窗口的属性参数,其中各个参数的意义如下表所示:
参数 意义
hwnd Long,欲为其取得信息的窗口的句柄
nIndex Long,这里取GWL_WNDPROC,表示设置该窗口的窗口函数的地址
dwNewLong Long,由nIndex指定的窗口信息的新值
返回值 Long,指定数据的前一个值
CallWindowProc函数的作用是截获发给窗体的消息。会有三种情况:
<1>如果是需要通过程序来处理的消息就通过 WindowProc函数 中的相应语句处理;
<2>如果是要原来的 窗体函数 来处理则把这个消息传递给原窗体函数(其实是指针指向的改变);
<3>如果不是我们需要的消息,也传递给原 窗体函数 来处理。
那么怎么来使用这两个API呢?下面是具体实现,首先申明几个变量
Public Const GWL_WNDPROC = -4'常量参数,函数地址
Public IsHooked As Boolean'是否建立挂钩 --建立后必须UnHook,且不能再次建立
Global lpPrevWndProc As Long'保留原函数地址
Global gHW As Long'保存窗体句柄
'调用SetWindowLong替换窗口gHW中的GWL_WNDPROC消息为WindowProc(WindowProc是自己定义的函数),并且把本次调用的函数地址保留在lpPrevWndProc中
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
'UnHook,将lpPrevWndProc函数替换回去
Dim temp As Long
temp = SetWindowLong(gHW, GWL_WNDPROC,lpPrevWndProc)
'获得传递给原函数的消息(lpPrevWndProc),获得后可根据Msg判断是否是自己需要处理的消息
Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'如果是自己需要的就处理,如果不需要处理则返回给原函数处理
WindowProc = CallWindowProc(lpPrevWndProc, hWnd, Msg, wParam, lParam)
通过以上方式我们可以实现用自定义的右键菜单取代系统菜单,实现资源管理器中的拖拽等。
最后使用SetWindowLong这个API来将原来的窗口函数指针换成自己的函数指针,并将原来的窗口函数指针保存下来。这样窗口消息就可以发到我们自己的函数里来,并且我们随时可以用CallWindowProc来调用前面保存下来的窗口指针,以调用原来的窗口函数。这样,我们可以在不破坏原有窗口功能的前提下处理钩入的消息。这样我们可以实现比如"外部调用内部的函数指针",从VB调用C,C++函数等。
SetWindowLong函数的作用是在窗口结构中为指定的窗口设置属性,利用它我们来改变窗口的属性参数,其中各个参数的意义如下表所示:
参数 意义
hwnd Long,欲为其取得信息的窗口的句柄
nIndex Long,这里取GWL_WNDPROC,表示设置该窗口的窗口函数的地址
dwNewLong Long,由nIndex指定的窗口信息的新值
返回值 Long,指定数据的前一个值
CallWindowProc函数的作用是截获发给窗体的消息。会有三种情况:
<1>如果是需要通过程序来处理的消息就通过 WindowProc函数 中的相应语句处理;
<2>如果是要原来的 窗体函数 来处理则把这个消息传递给原窗体函数(其实是指针指向的改变);
<3>如果不是我们需要的消息,也传递给原 窗体函数 来处理。
那么怎么来使用这两个API呢?下面是具体实现,首先申明几个变量
Public Const GWL_WNDPROC = -4'常量参数,函数地址
Public IsHooked As Boolean'是否建立挂钩 --建立后必须UnHook,且不能再次建立
Global lpPrevWndProc As Long'保留原函数地址
Global gHW As Long'保存窗体句柄
'调用SetWindowLong替换窗口gHW中的GWL_WNDPROC消息为WindowProc(WindowProc是自己定义的函数),并且把本次调用的函数地址保留在lpPrevWndProc中
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
'UnHook,将lpPrevWndProc函数替换回去
Dim temp As Long
temp = SetWindowLong(gHW, GWL_WNDPROC,lpPrevWndProc)
'获得传递给原函数的消息(lpPrevWndProc),获得后可根据Msg判断是否是自己需要处理的消息
Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'如果是自己需要的就处理,如果不需要处理则返回给原函数处理
WindowProc = CallWindowProc(lpPrevWndProc, hWnd, Msg, wParam, lParam)
通过以上方式我们可以实现用自定义的右键菜单取代系统菜单,实现资源管理器中的拖拽等。
最后使用SetWindowLong这个API来将原来的窗口函数指针换成自己的函数指针,并将原来的窗口函数指针保存下来。这样窗口消息就可以发到我们自己的函数里来,并且我们随时可以用CallWindowProc来调用前面保存下来的窗口指针,以调用原来的窗口函数。这样,我们可以在不破坏原有窗口功能的前提下处理钩入的消息。这样我们可以实现比如"外部调用内部的函数指针",从VB调用C,C++函数等。
相关文章推荐
- 对操作系统一些常用模块调用的简单总结
- electron开发记录(五):调用jquery,bootstrap并对其一些用法的总结
- C++和JAVA中一些区别,包括指向子类的引用会调用谁的方法,子类构造函数自动调用父类构造函数时,父构造会调用的谁方法
- 最近在ArcGIS Engine开发中关于调用gp工具过程出现COM 组件的调用返回了错误 HRESULT E_FAIL 错误的解决方法 和 学习oracle中遇到的一些问题总结
- C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用
- 关于java 与 ajax之间调用的一些总结
- IOS安装FFmpeg调用成功总结的一些问题
- 关于Java对相对目录的文件读写和调用方法的一些总结
- 关于jquery 的ajax调用的一些总结(记录插入数据库成功,但ajax返回false)
- 在内容页中调用母版页控件 一些方法总结
- 关于继承及父类引用指向子类的一些总结
- Java中父类和子类中的方法调用和参数传递总结
- 关于动态链接库调用的一些经验总结
- 看了《spring技术内幕》简单的图解总结下spring一些请求调用流程
- 内容页中调用母版页控件一些方法总结
- Qt刷新机制的一些总结(Qt内部画的时候是相当于画在后台一个对象里,然后在刷新的时候调用bitblt统一画,调用window的api并不会影响到后面的那个对象)
- 关于ASPCMS标签调用的一些总结
- linux下关于调用动态库的一些总结
- 关于MFC中CDHtmlDialog嵌入flash和调用JS一些技术总结
- Java中子类调用父类构造函数总结