SetWindowSubclass泄漏用户对象 [英] SetWindowSubclass is leaking user objects

查看:149
本文介绍了SetWindowSubclass泄漏用户对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用检查用户对象和WindowProc计数永远不会减少RemoveWindowSubclass. USER中的总数也是如此,它是任务管理器中的用户对象.

I'm using Bear to inspect user objects and the WindowProc count is never decreasing upon RemoveWindowSubclass. So does the total in USER which is the User Objects in Task Manager.

我阅读了雷蒙德(Raymond)的更安全的子类评论在销毁窗口之前删除子类,但我的测试完全没有销毁.

I read Raymond's Safer subclassing comment on removing subclassing before destroying the window but my test is done w/o destroying it at all.

comctl的工具提示类在内部为TTF_SUBCLASS的工具使用了相同的子类API,因此,如果您使用的是非合作工具提示,则会发生更多的泄漏.

The same subclassing API is used internally by the comctl's tooltip class for TTF_SUBCLASS'ed tools, so more leaks occur if you are using non-cooperative tooltips.

这是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

如果有什么可以发表评论的话,那么发生的事情以及如何解决泄漏的问题将非常好.

If any can leave a comment what's going on and how to resolve the leaks will be great.

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

Anyone else be warned if you're doing intensive subclassing with SetWindowSubclass API.

欢呼声,
</wqw>

cheers,
</wqw>

推荐答案

我认为将其称为泄漏"有点夸张.的确,在调用RemoveWindowSubclass时不会还原用户对象,但是在再次调用SetWindowSubclass时不会分配另一用户对象.您可以重复设置和删除该钩子,并且该用户对象在该过程的整个生命周期中似乎一遍又一遍地被重用.

I think calling this a "leak" is a bit hyperbolic. True, the user object isn't restored when RemoveWindowSubclass is called, but neither is another one allocated when you call SetWindowSubclass again. You can repeatedly set and remove the hook, and that same user object appears to be reused over and over again for the life of the process.

在您最简单的情况下,我进行了更多测试.仅作为背景参考,具有两个命令按钮且没有窗口挂钩的表单的每个实例都使用六个用户对象.确实,调用SetWindowSubclass确实会消耗每个窗口类 一个用户对象.也就是说,我可以加载该表单的多个实例,并钩住表单本身以及两个包含的命令按钮的消息流,并且总共消耗两个User对象.如您所见,这些在整个过程的生命周期中都不会被回收.

I did a few more tests that expanded on your simplest-case scenario. Just for background reference, each instance of your form with two command buttons and no window hooks consumes six User objects. Calling SetWindowSubclass does indeed consume one more User object per window class. That is, I can load multiple instances of that form, and hook the message stream for the form itself as well as both contained command buttons, and consume a total of two User objects. These, as you observe, are not recycled for the life of the process.

内部设计会更整洁吗?可能吧.话又说回来,可能不是.我认为这根本不需要引起太多关注.引起更大关注的原因是设计了这样的应用程序,使得该可能引起关注.在这种情况下,可能需要对整个UI设计进行基本的重新考虑.我简直无法想象您何时会在单个进程中将如此多的窗口类子类化,以至于每个类的这个额外对象可能会很重要.

Could the internal design be cleaner? Possibly. Then again, possibly not. I don't see this as much cause for concern, at all. A greater cause for concern would be an application designed such that this might be concerning. In that case, a fundamental reconsideration of the overall UI design may be in order. I simply cannot imagine when you would be subclassing so many window classes in a single process that this extra object for each class could possibly matter.

这篇关于SetWindowSubclass泄漏用户对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆