Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to code a property editor for integer with min/max values?
    text
    copied!<p>Edit: original question below, but I revise it now that I have some code to post....</p> <p>I am created an editbox which only accepts an integer as input. I didn't use a TMaskEDit because I want to derive a bunch of others from it (only accepts float, and both float &amp; integer with min/max properties).</p> <p>Here's my code. I think the problem is that my property editor SetValue() is never being called, so maybe I haven't registered it correctly?</p> <pre><code>unit IntegerEditBoxMinMax; // An edit box which only accepts integer values between the stated mix/max values interface uses SysUtils, Classes, Controls, StdCtrls, DesignEditors; type TMinimumProperty = class(TIntegerProperty) procedure SetValue(const newValue: string); override; end; TMaximumProperty = class(TIntegerProperty) procedure SetValue(const newValue: string); override; end; TValueProperty = class(TIntegerProperty) procedure SetValue(const newValue: string); override; end; TIntegerEditBoxMinMax = class(TCustomEdit) private FMinimum : Integer; FMaximum : Integer; FValue : Integer; published { Published declarations - available in the Object Inspector at design-time } property Minimum : Integer read FMinimum write FMinimum; property Maximum : Integer read FMaximum write FMaximum; property Value : Integer read FValue write FValue; end; // of class TIntegerEditBoxMinMax() procedure Register; implementation Uses TypInfo, Consts, DesignIntf, Dialogs; procedure Register; begin RegisterComponents('Standard', [TIntegerEditBoxMinMax]); RegisterPropertyEditor(TypeInfo(Integer), TIntegerEditBoxMinMax, 'Minumim', TMinimumProperty); RegisterPropertyEditor(TypeInfo(Integer), TIntegerEditBoxMinMax, 'Maximum', TMaximumProperty); RegisterPropertyEditor(TypeInfo(Integer), TIntegerEditBoxMinMax, 'Value', TValueProperty); end; procedure TMinimumProperty.SetValue(const newValue: string); var L: Longint; min, max : Integer; propInfo: PPropInfo; exceptionString : String; begin MessageDlg('editor !!', mtWarning, [mbOK], 0); // This is never seen !! L := StrToInt(newValue); { convert string to number } with GetTypeData(GetPropType())^ do { this uses compiler data for type Integer } min := GetOrdProp(GetComponent(0), 'Minimum'); max := GetOrdProp(GetComponent(0), 'Maximum'); if min &gt; max then begin exceptionString := 'Minimum value (%l) cannot be greater than maximum (%l)'; raise Exception.CreateResFmt(@exceptionString, [min, max]); end; if L &lt; min then begin PropInfo := GetPropInfo(); SetOrdProp(Nil , propInfo, Int64(min)); exceptionString := 'Value (%l) less than new minimum (%l); value set to minimum'; raise Exception.CreateResFmt(@exceptionString, [L, min]); end; SetOrdValue(L); { if in range, go ahead and set value } end; // of TMinimumProperty.SetValue() procedure TMaximumProperty.SetValue(const newValue: string); var L: Longint; min, max : Integer; propInfo: PPropInfo; exceptionString : String; begin L := StrToInt(newValue); { convert string to number } with GetTypeData(GetPropType())^ do { this uses compiler data for type Integer } min := GetOrdProp(Nil, 'Minimum'); max := GetOrdProp(Nil, 'Maximum'); if max &lt; min then begin exceptionString := 'Maximum value (%l) cannot be less than minimum (%l)'; raise Exception.CreateResFmt(@exceptionString, [max, min]); end; if L &gt; max then begin PropInfo := GetPropInfo(); SetOrdProp(Nil , propInfo, Int64(max)); exceptionString := 'Value (%l) more than new maximum (%l); value set to maximum'; raise Exception.CreateResFmt(@exceptionString, [L, max]); end; SetOrdValue(L); { if in range, go ahead and set value } end; // of TMaximumProperty.SetValue() procedure TValueProperty.SetValue(const newValue: string); var L: Longint; min, max: Integer; begin L := StrToInt(newValue); { convert string to number } // see also http://www.freepascal.org/docs-html/rtl/typinfo/getobjectprop.html // for other useful functions with GetTypeData(GetPropType())^ do { this uses compiler data for type Integer } begin min := GetOrdProp(Nil, 'Minimum'); max := GetOrdProp(Nil, 'Maximum'); // for Float, etc, see http://www.blong.com/Conferences/BorConUK98/DelphiRTTI/CB140.htm if (L &lt; min) or (L &gt; max) then { make sure it's in range... } raise Exception.CreateResFmt(@SOutOfRange, [min, max]); { ...otherwise, raise exception } SetOrdValue(L); { if in range, go ahead and set value } end; end; // of TMinimumProperty.SetValue() end. </code></pre> <hr> <p>Original question:</p> <p><a href="http://www.podgoretsky.com/ftp/docs/Delphi/D5/dg/register.html" rel="nofollow noreferrer">This link</a> gives a pretty good example of a property editor for an integer property.</p> <p>How can I change this method ... </p> <pre><code>procedure TIntegerProperty.SetValue(const Value: string); var L: Longint; begin L := StrToInt(Value); { convert string to number } with GetTypeData(GetPropType)^ do { this uses compiler data for type Integer } if (L &lt; MinValue) or (L &gt; MaxValue) then { make sure it is in range } { otherwise, raise exception } raise EPropertyError.Create(FmtLoadStr(SOutOfRange, [MinValue, MaxValue])); SetOrdValue(L); { if in range, go ahead and set value } end; </code></pre> <p>... what I want is to male a new property, say <code>TIntegerMinMaxProperty</code>, derived from <code>TIntegerProperty</code> where the component editor also shows minimum and maximum permitted values for the integer.</p> <p>I was thinking of adding two new Integer properties, called Minimum &amp; Maximum, but it looks like I could maybe use the existing MinValue &amp; MaxValue if I could only publish them, but I don't see how ... neither of these compile </p> <pre><code>published { available in the Object Inspector at design-time } property Minimum : Longint read MinValue write MinValue; property Minimum : Longint read FMinValue write FMinValue; </code></pre> <p>So it looks like I have two options and am stuck at both :-/</p> <p>1) find a way to publish those MinValue &amp; MaxValue properties (which is probably cleaner) 2) publish 2 new properties, Minimujm &amp; Maximum and figure how to refer to them in TIntegerProperty.SetValu()</p> <p>And help gratefully appreciated as this is my first sortie into property editors (in case it helps influence the answer to this, my next property will be one that accepts decimal input, with a a point)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload