修改子对象的行为

时间:2016-05-19 01:46:11

标签: delphi delphi-7 vcl

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

1 个答案:

答案 0 :(得分:2)

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

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

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

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

通过TCustomListBox.InternalGetItemData()属性更新现有项目的字符串时,事情变得有点复杂:

    调用
  1. InternalGetItemData()(可以被覆盖)来检索项目的现有对象(如果有的话)。默认情况下,GetItemData()调用LB_GETITEMDATA(也可以覆盖),默认情况下会向列表框HWND发送TCustomListBox.InternalSetItemData()消息。
  2. 调用
  3. Delete()(可以被覆盖)将项目对象设置为nil(如果InternalSetItemData()在下一步中尝试销毁它)。默认情况下,SetItemData()调用LB_SETITEMDATA(也可以覆盖),默认情况下会向列表框HWND发送Items.Delete()消息。
  4. 调用
  5. Items.InsertObject()删除该项目。
  6. 调用
  7. nil以使用TCustomListBox.InternalSetItemData()对象
  8. 插入新字符串 调用
  9. Items.Objects[]将原始对象恢复为新项目。
  10. 通过Style属性更新现有项目的对象时,如果ListBox的TCustomListBox.SetItemData()未设置为虚拟模式,则调用Items.Exchange()。< / p>

    使用Style方法移动项目时,如果列表框的Exchange()设置为虚拟模式,则Items.Strings[]只会退出而不执行任何操作。否则,它使用Internal(Get/Set)ItemData()属性来交换两个项目字符串,并调用TCustomListBox.DeleteString()来交换两个项目对象。

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

    1. TCustomListBox.WndProc()
    2. LB_(ADD/INSERT)STRING来处理LB_(GET/SET)ITEMDATA,也许TCustomListBox.Internal(Get/Set)ItemData()
    3. TCustomListBox.(Get/Set)ItemData()android.support.v7.widget.Toolbar