代码之家  ›  专栏  ›  技术社区  ›  wqw

SetWindowSub类正在泄漏用户对象

  •  1
  • wqw  · 技术社区  · 17 年前

    我在用 Bear

    Safer subclassing

    这是VB6代码

    '--- Form1.frm '
    Option Explicit
    
    Private Declare Function SetWindowSubclass Lib "comctl32" (ByVal hwnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
    Private Declare Function DefSubclassProc Lib "comctl32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function RemoveWindowSubclass Lib "comctl32" (ByVal hwnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long) As Long
    
    Private Sub Command1_Click()
        Call SetWindowSubclass(hwnd, AddressOf RedirectTabPaneEditWndProc, 10, ObjPtr(Me))
    End Sub
    
    Private Sub Command2_Click()
        Call RemoveWindowSubclass(hwnd, AddressOf RedirectTabPaneEditWndProc, 10)
    End Sub
    
    Friend Function frWndProc(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        frWndProc = DefSubclassProc(hwnd, wMsg, wParam, lParam)
    End Function
    
    '--- Module1.bas '
    Option Explicit
    
    Public Function RedirectTabPaneEditWndProc( _
                ByVal hwnd As Long, _
                ByVal wMsg As Long, _
                ByVal wParam As Long, _
                ByVal lParam As Long, _
                ByVal uIdSubclass As Long, _
                ByVal This As Form1) As Long
        #If uIdSubclass Then '--- touch args
        #End If
        RedirectTabPaneEditWndProc = This.frWndProc(hwnd, wMsg, wParam, lParam)
    End Function
    

    如果您正在使用SetWindowSubclass API进行密集的子类化,请警告其他任何人。


    </wqw>

    2 回复  |  直到 12 年前
        1
  •  2
  •   Karl E. Peterson    17 年前

    我认为称之为“泄密”有点夸张。确实,调用RemoveWindowSubclass时不会还原用户对象,但再次调用SetWindowSubclass后也不会分配另一个对象。您可以重复设置和删除钩子,并且在流程的生命周期内,同一个用户对象似乎会被反复使用。

    我还做了一些测试,扩展了你最简单的案例场景。仅供背景参考,你的表单的每个实例都有两个命令按钮,没有窗口挂钩,会消耗 每个窗口类

    可能 令人担忧。在这种情况下,可能需要对整体UI设计进行根本性的重新考虑。我简直无法想象,什么时候你会在一个进程中子类化这么多窗口类,以至于每个类的这个额外对象可能很重要。

        2
  •  1
  •   Community Mohan Dere    9 年前

    在VB6中,这是一种不寻常的子类化方式。你可能会更幸运 SetWindowLong(GWL_WNDPROC) -看 this VB6 code 卡尔·彼得森。

    有趣的是,看起来卡尔 experimenting right now 与您正在使用的comctl32函数相同。编辑:是的,他是 posted an article an answer to this question :)