【问题标题】:Modify behaviour of subobjects修改子对象的行为
【发布时间】:2016-05-19 01:46:10
【问题描述】:

有没有办法通过在子类化组件时重新定义子对象的行为(方法)来修改它们。例如,我是 Tlistbox 的子类,并且我想修改其 Items 子对象的 Delete() 方法的行为。有正式的方法吗? 谢谢

【问题讨论】:

  • Delphi XE 引入了一个 TVirtualMethodInterceptor 类,它可以满足您的要求,因为 Delete() 是虚拟的,但在 Delphi 7 中不存在类似的东西(除非您手动备份它),并且您无权直接访问以不同的实现替换 Items 对象。你真正想要完成什么?可能有不同的处理方式。
  • 我正在添加附加到 items 属性的额外内部信息结构,所以我想将它添加到 objects[] 列表中,在这种情况下我必须限制使用 items.add ( ) 以防止在没有新信息的情况下输入字符串,或者制作单独的 tstrings 对象并重新定义 items.add 和 items.delete 以同步两个 tstrings 对象。

标签: delphi delphi-7 vcl


【解决方案1】:

根据您的 cmets,您实际上不需要更改 Items 属性本身的行为。还有其他方法可以检测何时在 ListBox 中操作项目,以便您可以根据需要更新自己的内部对象。

删除项目时,Items.Delete() 方法只需调用 TCustomListBox.DeleteString() 将要删除的索引传递给它。 DeleteString() 可以被后代覆盖。很简单。

在添加/插入新项目时,它并不是那么简单。 Items.Add() 直接向 ListBox 的 HWND 发送 LB_ADDSTRING 消息(除非 ListBox 的 Style 设置为虚拟模式,在这种情况下 Add() 直接退出而不做任何事情)。与Items.Insert() 方法(LB_INSERTSTRING 消息)相同。要捕获这些消息,您必须重写 ListBox 的虚拟 WndProc() 方法。

Items.AddObject() 首先调用Items.Add(),然后使用Items.Objects[] 设置器将对象分配给新项目。与Items.InsertObject() 相同,调用Items.Insert() 而不是Items.Add()

当通过Items.Strings[] 属性更新现有项目的字符串时,事情会变得有点复杂:

  1. 调用TCustomListBox.InternalGetItemData()(可以被覆盖)以检索项目的现有对象(如果有)。默认情况下,InternalGetItemData() 调用GetItemData()(也可以被覆盖),默认情况下会向 ListBox 的HWND 发送LB_GETITEMDATA 消息。
  2. 调用TCustomListBox.InternalSetItemData()(可以被覆盖)将项目的对象设置为nil(以防Delete()在下一步尝试销毁它)。默认情况下,InternalSetItemData() 调用SetItemData()(也可以被覆盖),默认情况下会向列表框的HWND 发送LB_SETITEMDATA 消息。
  3. 调用Items.Delete() 来删除项目。
  4. 调用Items.InsertObject() 以插入带有nil 对象的新字符串
  5. 调用TCustomListBox.InternalSetItemData() 将原始对象恢复为新项目。

通过Items.Objects[] 属性更新现有项的对象时,如果列表框的Style 未设置为虚拟模式,则调用TCustomListBox.SetItemData()

当使用Items.Exchange() 方法移动项目时,如果ListBox 的Style 设置为虚拟模式,那么Exchange() 会直接退出而不做任何事情。否则,它使用Items.Strings[] 属性交换两个项目字符串,并调用Internal(Get/Set)ItemData() 交换两个项目对象。

因此,基本上,管理内部对象所需的一切都归结为重写这些方法:

  1. TCustomListBox.DeleteString()
  2. TCustomListBox.WndProc() 处理LB_(ADD/INSERT)STRING,也许LB_(GET/SET)ITEMDATA
  3. TCustomListBox.Internal(Get/Set)ItemData()TCustomListBox.(Get/Set)ItemData()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-10
    • 2017-12-28
    • 2012-05-30
    • 1970-01-01
    • 2018-05-15
    • 2021-10-16
    • 1970-01-01
    • 2019-03-20
    相关资源
    最近更新 更多