I have created a new component which is derived from TEdit. In the below code, I am setting MaxLength Property to 10 after setting AllowValues to true.
I set the component on form and set the AllowValues to true and run the application and edit box is allowing more than 10 characters. whats wrong with my code?
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.
Working on an answer I realized that you re-invented the MaxLength
property for your custom edit. Was that your intention? Unless I'm mistaken all that currently differs is that you accidentally introduced the bug that is topic of this question. Your code should work if you hadn't introduced that property.
So one way to solve your issue is to remove the MaxLength
property from TDUMMYEdit
, instead rely on the one TCustomEdit
implements.
Your issue is that when your code takes effect during component streaming from DFM, no Handle
is allocated, HandleAllocated
returns False
and your EM_LIMITTEXT
message will not be sent. Setting the AllowValues
property later on, e.g. in an event handler of your form, would work as you'd expect, as at that time, a handle is allocated.
A way to fix this can be found looking atTCustomEdit
in Vcl.StdCtrls
- code you might have taken as example, it looks very similar - the procedure DoSetMaxLength
- which will send the same message you are trying to send - will also be called in TCustomEdit.CreateWnd
, at a time where there is a valid Handle
created. A fix for your code would then look like this:
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;
...