| 网站首页 | JAVA文章 | AppServers | Web开发 | 应用开发 | 资源下载 | 论坛
    想学好编程,学好外语很重要  [enadd  2006年12月25日]        
设为首页 加入收藏 联系站长
您现在的位置: 编程笔记网 >> 应用开发 >> vb >> API >> 文章正文
让一组相同的控制项有相同的行为(SuperClass)            【字体:
让一组相同的控制项有相同的行为(SuperClass)
作者:-    文章来源:-    点击数:    更新时间:2006-6-8

   如果您见过本人的文章"Window简介(二) 如何拦截ComboBox MouseMove
"应可以了解SubClass的动作是针对某一个Window来动作,像上面的这个文章就告诉大家如
何透过SubClass来让ComboBox能侦测到MouseMove,而如果有一群ComboBox全要侦测到
MouseMove那不就每一个ComboBox都要来做SubClass的动作,有没有一次完成不要如此麻
烦的呢?原则上这是使用SuperClass可完成,SuperClass的作法是:

  1.取得原本Class的设定(如:原本ComboBox的设定),可用GetClassLong来取得
  2.更动Class的设定,可用SetClassLong来设定
  3.依新的设定Create控制项,而且唯有新Create出的控制项才有作用,旧有的没有受
    影响。

再来看一下GetClassLong,SetClassLong的第一个叁数,它是hWnd,想想看,这是更动某
一个Class的API,而不是只更动某个Window的API,怎麽传入hWnd,没错,那是间接的作法
,由hWnd可以得知那是属於哪一种Class的控制项,进而改变/取得 该hWnd所属Class类别
的设定。那现在就出现一个问题,我们要先Create出一个Window(控制项)而後才能取得
其hWnd,之後才下SetClassLong来更动设定,而这个Window因为是在更动设定之前所造出
来的,所以新的设定没有在这个Window上作用(这是Window的作法,没有办法),所以我们
说不得,只好将该Window Kill掉,之後Create的Window才是我们想要的。如果使用的是
纯Window API的设计,可能不用如此,而使用以下三个步骤:

   1.取得Class的设定,使用GetClassInfoEx()取得,并记录下来
   2.更动原先的记录,将之变成另外一个Class
   3.注册该Class,并CreateWindow

但这样做,就没有vb的使用者介面,将Control项放到Form上那麽容易,一切都用API来做,
我想没有人会如此吧?

所以啦,在VB的话,就只好使用物件阵列的作法,因为透过它,可以做到到动态新增、移
除Control项的功能,不过正因它是事後才产生的,所以我们对之的控制相对的就要付出
代价(如:位置的设定)。

'以下程式在module1.bas
 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
 Declare Function SetClassLong Lib "user32" Alias "SetClassLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
 Declare Function GetClassLong Lib "user32" Alias "GetClassLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long

 Public Const GCL_WNDPROC = (-24)
 Public Const WM_MOUSEMOVE = &H200

 Public preWinProc As Long

 Public Function wndproc(ByVal hwnd As Long, ByVal Msg As Long, _
                         ByVal wParam As Long, ByVal lParam As Long) As Long
 '以下程式会截取mouse move,处理完後,再将之送往原来的Window Procedure

 If Msg = WM_MOUSEMOVE Then
    '请处理Mouse Move的动作
    Debug.Print "Combol Mouse Move , hwnd="; hwnd
 End If
 '将之送往原来的Window Procedure
 wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
 End Function

 '以下程式在Form1, form1中有一Combo1并事先设定其Index =1
 Sub Form_Load()
 Dim ret As Long
 Combo1(1).Move 5, 5
 '记录原本的Window Procedure的位址
 preWinProc = GetClassLong(Combo1(1).hwnd, GCL_WNDPROC)
 '设定Combo1的window Procedure到wndproc
 ret = SetClassLong(Combo1(1).hwnd, GCL_WNDPROC, AddressOf wndproc)
 '动态产生两个Combo,Mouse在这两个Combo上才会侦测到MouseMove
 Load Combo1(2)
 Combo1(2).Move 5, 400
 Combo1(2).Visible = True
 Load Combo1(3)
 Combo1(3).Move 5, 800
 Combo1(3).Visible = True
 Debug.Print "Combo1(1).Hwnd="; Combo1(1).hwnd
 Debug.Print "Combo1(2).Hwnd="; Combo1(2).hwnd
 Debug.Print "Combo1(3).Hwnd="; Combo1(3).hwnd
 End Sub

 Private Sub Form_Unload(Cancel As Integer)
 Dim ret As Long
 '取消Message的截取,而使之又只送往原来的Window Procedure
 ret = SetClassLong(Combo1(1).hwnd, GCL_WNDPROC, preWinProc)
 End Sub


文章录入:enadd    责任编辑:enadd 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
  • 用VB编写DirectX7.0游戏(下…

  • 用VB编写DirectX7.0游戏(上…

  • 使用OLE DB和ADO调用返回记录…

  • 使用VB调用Oracle程序包内的…

  • VB中用ADO对象动态创建数据库…

  • fffff

  • 如何用MSComm Control传Bina…

  • MultiLink的WinSock Server程…

  • 用VB制作浏览器

  • 用VB编写网络寻呼机

  •   网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 |