设置CustomComponent(TEDIT)MaxLength属性不起作用

时间:2017-12-05 12:12:15

标签: delphi delphi-7

我创建了一个从TEdit派生的新组件。在下面的代码中,我将 AllowValues设置为true 后将MaxLength属性设置为10。

我在表单上设置组件并将 AllowValues设置为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.

1 个答案:

答案 0 :(得分:2)

根据答案,我意识到您重新发明了 MaxLength属性以进行自定义编辑。那是你的意图吗?除非我错了,目前所有不同之处在于你不小心引入了这个问题主题的bug。如果您没有引入该属性,您的代码应该可以工作。

因此解决问题的一种方法是从MaxLength中删除TDUMMYEdit属性,而不是依赖于TCustomEdit个实现。

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

可以在TCustomEdit中查看Vcl.StdCtrls - 您可能已经采用的代码,它看起来非常相似 - 程序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;
...