TCustomListBox - 如何引入OnInsert和OnRemove方法?

时间:2014-11-04 00:12:09

标签: delphi delphi-xe

我想在我从TCustomListBox派生的自定义控件中引入一些新方法。

我想要的是一个方法,可以在项目添加/插入列表框时使用,以及从列表框中删除项目时的方法。

从这个开始的好地方是什么?我知道像TListView这样的控件有一个OnInsert事件,但我看不到列表框的任何内容?

我想引入我的控件例如:

OnInsert
OnRemove

我是否需要使用某种API或消息来检测何时添加/删除项目然后从那里获取项目?有没有更简单的方法来做到这一点还是需要一些困难?

我试着查看一些VCL来源,但大部分都让我感到困惑。

提前致谢。

1 个答案:

答案 0 :(得分:6)

您需要的API已经存在。

如果您检查 TCustomListBox 的来源,您将看到使用窗口消息实现从列表中添加,插入或删除项目的机制。例如,在 TListBoxString.Add()以及管家代码中,您将看到最终通过向控件发送消息来添加字符串:

 Result := SendTextMessage(ListBox.Handle, LB_ADDSTRING, 0, S);

Delphi提供了各种机制,用于在控件和窗口类上提供响应特定消息的处理程序。对于添加一个简单的通知机制(如您的require),最简单和最合适的方法是实现特定的消息处理程序方法。

您提供了一个消息处理程序过程并声明它响应的消息。例如,在您的情况下,您可以添加自己对 LB_ADDSTRING 消息的处理:

TChattyList = class(TCustomListbox)
  procedure LBAddString(var aMessage: TMessage); message LB_ADDSTRING;
end;

消息的参数( wParam lParam )打包在作为by参数传递给处理程序的 TMessage 记录中)。您需要查阅Windows API文档以获取相关消息,以确定这些参数的使用。

你可以在你的消息处理程序中做任何你想做的事情,尽管你应该总是密切关注一个窗口应该做什么来响应记录的消息,包括任何返回值(在结果中设置 TMessage 参数的strong>字段,这就是它通过引用传递的原因,如 var

在这个简单的例子中,新的处理程序调用继承以确保允许继承的实现通过实际添加新的项字符串来响应,然后粗略地弹出一个消息框让我们知道添加了一个项目:

procedure TChattyList.LBAddString(var aMessage: TMessage);
begin
  inherited;
  ShowMessage('item added');
end;

从本质上讲,您的事件机制将完全相同,但是在允许继承的实现完成它的工作(并检查结果代码集,以确保)之后,您将触发新事件,而不是显示消息框。它是成功的,根据所讨论的消息的预期返回值:

procedure TChattyList.LBAddString(var aMessage: TMessage);
begin
  inherited;

  if (aMessage.Result = LB_ERR) or (aMessage.Result = LB_ERRSPACE) then
    EXIT;

  if Assigned(fOnInsert) then
    fOnInsert(self);
end;

如果继承的处理程序未能添加项目,那么根据文档,它应该将结果设置为 LB_ERR LB_ERRSPACE ,因此我们测试这些值并退出if他们被发现了。否则,我们调用适当的事件处理程序(如果已分配)。

这假设出于您的目的,一个简单的 TNotifyEvent 就足够了,并且您不会区分插入的项目与添加的项目。您当然可以有单独的事件或在参数中为特定事件类型提供一些指示。

您选择处理和公开哪些事件的消息是您的要求究竟是什么,但根据您在问题中说明的内容,我认为您至少需要消息处理程序< strong> LB_ADDSTRING , LB_INSERTSTRING LB_DELETESTRING

您可能需要处理其他消息,并应参考Windows API documentation for listbox controls for further information