设置 CustomComponent(TEDIT) MaxLength 属性 无效

Setting CustomComponent(TEDIT) MaxLength Property not working

我创建了一个派生自 TEdit 的新组件。在下面的代码中,我在将 A​​llowValues 设置为 true.

后将 MaxLength 属性 设置为 10

我在表单上设置组件并将 A​​llowValues 设置为 true 并且 运行 应用程序和编辑框允许超过 10 个字符。我的代码有什么问题?

unit DummyEdit;

interface

uses
  SysUtils, Classes, Controls, StdCtrls,Dialogs,Windows,Messages;

type
  TDUMMYEdit = class(TEdit)
  private
    { Private declarations }
    FAllowValues : Boolean;
    FMaxLength: Integer;
    Procedure SetAllowValues(Value : Boolean);
    procedure SetMaxLength(Value: Integer);
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    Property AllowValues : Boolean read FAllowValues write SetAllowValues;
    property MaxLength: Integer read FMaxLength write SetMaxLength default 0;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('DUMMY', [TDUMMYEdit]);
end;

{ TDUMMYEdit }


procedure TDUMMYEdit.SetAllowValues(Value: Boolean);
begin
  if FAllowValues <> value then
    FAllowValues := Value;
  if FAllowValues then
    MaxLength := 10
  else
    MaxLength := 0;    
end;

procedure TDUMMYEdit.SetMaxLength(Value: Integer);
begin
  if FMaxLength <> Value then
  begin
    FMaxLength := Value;
    if HandleAllocated then SendMessage(Handle, EM_LIMITTEXT, Value, 0);
  end;
end;

end.

在回答问题时我意识到您重新发明了 MaxLength 属性 用于您的自定义编辑。那是你的意图吗?除非我弄错了,否则目前的所有不同之处在于您不小心引入了该问题的主题错误。如果您没有引入 属性,您的代码应该可以工作。

因此,解决您的问题的一种方法是从 TDUMMYEdit 中删除 MaxLength 属性,而不是依靠 TCustomEdit 工具。

您的问题是,当您的代码在从 DFM 流式传输组件期间生效时,没有分配 HandleHandleAllocated returns False 和您的 EM_LIMITTEXT 消息将不会被发送。稍后设置 AllowValues 属性,例如在您的表单的事件处理程序中,将按您预期的方式工作,因为那时分配了一个句柄。

可以在 Vcl.StdCtrls 中查看 TCustomEdit 找到解决此问题的方法 - 您可能以代码为例,它看起来非常相似 - 过程 DoSetMaxLength - 这将发送您尝试发送的相同消息 - 也将在 TCustomEdit.CreateWnd 中调用,此时创建了有效的 Handle。代码的修复将如下所示:

  TDUMMYEdit = class(TEdit)
  private
    { Private declarations }
    FAllowValues : Boolean;
    FMaxLength: Integer;
    Procedure SetAllowValues(Value : Boolean);
    procedure SetMaxLength(Value: Integer);
  protected
    { Protected declarations }
    procedure CreateWnd; override;    
  public
    { Public declarations }
  published
    { Published declarations }
    Property AllowValues : Boolean read FAllowValues write SetAllowValues;
    property MaxLength: Integer read FMaxLength write SetMaxLength default 0;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('DUMMY', [TDUMMYEdit]);
end;

{ TDUMMYEdit }

...
procedure TDUMMYEdit.CreateWnd;
begin
  inherited CreateWnd;
  SendMessage(Handle, EM_LIMITTEXT, FMaxLength, 0);
end;
...