Newsgroup: it.comp.lang.delphi
Titolo: Property non riconosciuta

Uso un componente che ho chiamato FullEdit al quale ho cercato di aggiungere 
una propriet� per avanzare da un edit all'altro, oltre che con il Tab, anche 
con l'Enter. La sua compilazione � OK, ma in esecuzione mi d� il seguente 
messaggio:
"Project...raised exception EReadError with message "property TabOnEnter 
does not exist" ...
Non riesco a vedere l'errore che, evidentemente, faccio. Allego tutto il 
codice, anche se le righe effettivamente nuove sono solo quelle evidenziate. 
Da notare che a design time la property c'� e si pu� impostare ...
unit FullEditC;
interface
uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, Menus;
type
  TFullEdit = class(TCustomEdit)
  private
    FAlignment: TAlignment;
    FNumberOnly: Boolean;
    FThousendSep: Boolean;
    FMaxLength: integer;
    FMaxDecimals: integer;
    FColorNormal: TColor;
    FColorFocused: TColor;
    FormatString: string;  { '#.##0.'  or  '#0.'}
    FTabOnEnter: boolean;                        ////////////////////// 
NUOVA PROPERTY
    procedure SetMaxDecimals(Value: integer);
    procedure SetMaxLength(Value: integer);
    function  StripThousSep(AString: string): string;
    procedure Reformat;
    procedure CMEnter(var Message: TCMGotFocus); message CM_ENTER;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: char); override;      ////////////////////// 
MODIFICATA X NUOVA PROPERTY
    procedure SetAlignment(Value: TAlignment);
    procedure SetNumberOnly(Value: Boolean);
    procedure SetThousendSep(Value: Boolean);
    procedure SetColorFocused(Value: TColor);
    procedure SetColorNormal(Value: TColor);
    procedure DoEnter; override;
    procedure DoExit; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy;
  published
    property Alignment: TAlignment read FAlignment write SetAlignment 
default taLeftJustify;
    property NumberOnly: Boolean read FNumberOnly write SetNumberOnly;
    property ThousendSep: Boolean read FThousendSep write SetThousendSep;
    property MaxLength: integer read FMaxLength write SetMaxLength;
    property MaxDecimals: integer read FMaxDecimals write SetMaxDecimals;
    property ColorNormal: TColor read FColorNormal write SetColorNormal; 
//da AlignEdit
    property ColorFocused: TColor read FColorFocused write SetColorFocused; 
//da AlignEdit
    property TabOnEnter : boolean read FTabOnEnter write FTabOnEnter; 
////////////////////// NUOVA PROPERTY
    //
    property AutoSelect;
    property AutoSize;
    property BorderStyle;
    property CharCase;
    property Ctl3D;
    property DragCursor;
    property DragMode;
    property Enabled;
    property Font;
    property HideSelection;
    property OEMConvert;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PasswordChar;
    property PopupMenu;
    property ReadOnly;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Text;
    property Visible;
    property OnChange;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
  end;
procedure Register;
implementation
var
  nDecimals: integer;
const
  Alignments: array[TAlignment] of Word = (ES_LEFT, ES_RIGHT, ES_CENTER);
constructor TFullEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
  //Set defaults for the following properties:
  FAlignment := taLeftJustify;
  FNumberOnly := False;
  ThousendSep := False;
  FMaxLength := 16;
  MaxDecimals := CurrencyDecimals;
  FColorNormal  := clWindow;
  FColorFocused := clWindow;
  FTabOnEnter := false;   ////////////////////// NUOVA PROPERTY
  Color := FColorNormal;
  Height := 24;
  Width := 120;
end;
procedure TFullEdit.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.Style := Params.Style or Alignments[FAlignment];
end;
destructor TFullEdit.Destroy;
begin
  inherited Destroy;
end;
procedure TFullEdit.SetAlignment(Value: TAlignment);
begin
  if FAlignment <> Value then
  begin
    FAlignment := Value;
    RecreateWnd;
  end;
end;
procedure TFullEdit.SetNumberOnly(Value: Boolean);
begin
  if FNumberOnly <> Value then
    FNumberOnly := Value;
end;
procedure TFullEdit.SetThousendSep(Value: Boolean);
begin
  if FThousendSep <> Value then
    FThousendSep := Value;
end;
procedure TFullEdit.SetMaxDecimals(Value: integer);
begin
if ( Value > 0 ) and ( Value < FMaxLength-1 ) then
   FMaxDecimals := Value;
end;
procedure TFullEdit.SetMaxLength(Value: integer);
begin
if ( Value < 20 ) and ( Value > FMaxDecimals+1 ) then
   FMaxLength := Value;
end;
procedure TFullEdit.SetColorFocused(Value: TColor);
begin
  Color := value;
  FColorFocused := value;
end;
procedure TFullEdit.SetColorNormal(Value: TColor);
begin
  if not ((csDesigning in ComponentState) ) then
    Color := value;
  FColorNormal := value;
end;
procedure TFullEdit.KeyDown(var Key: Word; Shift: TShiftState);
{gestisce la cancellazione dall'edit di 1 o + caratteri
 contemporaneamente. Se ne pu� fare a meno, ma allora non �
 gestita la riformattazione della stringa nell'edit
}
var
  CursorPos: integer;
  Buffer: string;
begin
  inherited KeyDown(Key,Shift);
  if Key = VK_DELETE then
  begin
     Buffer := Text;
     if SelLength > 0 then begin
        //Se la cancellazione coinvolge + caratteri (usato il mouse)
        CursorPos := Length(Buffer)-SelStart-SelLength;
        Delete( Buffer, SelStart+1, SelLength);
        SelLength:= 0;
        Key := 0;
        Text := Buffer; //RESETTA text al valore rimasto dopo la 
cancellazione
     end else begin
        //Se la cancellazione coinvolge 1 solo carattere
        CursorPos := Length(Buffer)-SelStart;
        Delete( Buffer, Length(Buffer)-CursorPos+1, 1 );
        Dec(CursorPos);
        Text := Buffer; //RESETTA text al valore rimasto dopo la 
cancellazione
     end;
     Key := 0;
     if length(Text) = 0 then exit;
     Reformat;
     SelStart := Length(Text)-CursorPos;
  end;
end;
procedure TFullEdit.KeyPress( var Key: char );
{ La routine � attivata dalla digitazione di un valore nell'edit.
  (prima esegue KeyDown)
  VIENE ESEGUITA SOLO SE E'IMPOSTATA LA PROPERTY <NumberOnly>
  Alla digitazione, la key digitata c'� in "key", ma non ancora in "Text".
  Poich� il contenuto di Text viene ogni volta formattato con la
  stringa di formattazione (FormatString := '#,##0.'), la prima volta
  nell'edit comparir� '0,00'
  Nota:
     SelStart   : contiene sempre la posizione del cursore
                  per la immissione del carattere nell'edit
     CursorPos  : contiene la posizione del cursore, ma partendo
                  da destra
                  Es:  |15,234     SelStart = 0  CursorPos=6
}
var
  Buffer: string;
  CursorPos: integer;
begin
  inherited KeyPress(Key);
   ////////////////////// MODIFICA X NUOVA PROPERTY
  if TabOnEnter AND (Owner is TWinControl) then
  begin
    if Key = Char(VK_RETURN) then
    begin
     if HiWord(GetKeyState(VK_SHIFT)) <> 0 then
        PostMessage((Owner as TWinControl).Handle, WM_NEXTDLGCTL, 1, 0)
     else
        PostMessage((Owner as TWinControl).Handle, WM_NEXTDLGCTL, 0, 0);
    end;
  end;
   ////////////////////// FINE MODIFICA X NUOVA PROPERTY
  if FNumberOnly then
  begin
     Buffer := Text; //la 1a key digitata ancora non � in Text (ma � in Key)
     //prima cancella i car eventualmente selezionati con il cursore
     //su cui si � battuto il nuovo carattere
     //if SelLength > 0 then begin //Correzione 2004.08.17
     //Correzione 2004.08.17 (x calcolatrice: quando � battuto =
     //e il ris � zero, evita il delete, altrimenti sparisce lo zero)
     if (Key <> #0) and (SelLength > 0) then begin
         Delete( Buffer, SelStart+1, SelLength);
         SelLength:= 0;
     end;
     //CursorPos identifica la pos dove sotto la istr di "insert"
     //inserisce il carattere appena battuto contenuto in key (v. nota 
sopra)
     CursorPos := Length(Buffer)-SelStart;
     //Rifiuta il car in key se � stato digitato nel testo
     //prima di un -  (Es: 1-50)
     if (length(Buffer) > 0) and (Buffer[1] = '-') then
        if CursorPos = length(Buffer) then
        begin
           //Abblenca Key (il car immesso), altrimenti viene inserito
           //nell'edit nella posizione dove si � battuto
           Key := #0;
           exit;
        end;
     if key = DecimalSeparator then
     {1-DIGITATO NELL'EDIT IL SEPARATORE DECIMALE}
     begin
       //Immesso il Separatore decimale (, op .)
       //Verifica che il numero non sia gi� al limite
       //della lunghezza max consentita (FMaxLength).
       //Se ammesso, da Key inseriscilo in Text come ultimo carattere.
       //Ignoralo invece se gi� presente in Text
       if Length(StripThousSep(Buffer)) < FMaxLength-1 then
         if pos(DecimalSeparator,Text) = 0 then
           //Insert( Key, Buffer, Length(Buffer)+1); //non inserisce al 
punto giusto se ho mosso il cursore in mezzo al numero
           Insert( Key, Buffer, SelStart+1);
     end else
     if key in ['+','-'] then
     {2-DIGITATO NELL'EDIT UN CAR + o -}
     begin
        {il + e il - vanno accettati solo se sono immessi
         come primi car del numero e se non ce ne sono gi�}
        if (length(Text) = 0) or
           ((SelStart=0) and (pos('-',Text)=0))
        then
          Insert( Key, Buffer, Length(Buffer)-CursorPos+1 );
     end else
     if key in ['0'..'9'] then
     {2-DIGITATO NELL'EDIT UN CAR TRA 0 E 9}
     begin
        //aggiungi qui il car immesso (contenuto in key e
        //non ancora in Text)
        //Non ammettere caratteri (prima e dopo la virgola) eccedenti
        //la lunghezza Massima ammessa x il numero (MaxLength)
        //Non ammettere caratteri (dopo la virgola) eccedenti il
        //numero Massimo di decimali (MaxDecimals)
        //(x capire se la key immessa � dopo la virgola,i num dopo la 
virgola hanno un selStart
       //Verifica che il numero non sia gi� al limite
       //della lunghezza max consentita (FMaxLength).
        if Length(StripThousSep(Buffer)) < FMaxLength then begin
          if pos(DecimalSeparator,Text) = 0 then
            //non c'� sep decimale, quindi inserisci Key in Buffer
            Insert( Key, Buffer, Length(Buffer)-CursorPos+1 )
          else
          if SelStart > nDecimals then
            //c'� sep decimale, e la key battuta � un decimale:
            //inserisci Key in Buffer solo se non raggiunto max x dec
            if nDecimals+1 <= MaxDecimals then
              Insert( Key, Buffer, Length(Buffer)-CursorPos+1 )
            else
          else
            //c'� sep decimale, ma la key battuta non � un decimale
            //quindi inserisci Key in Buffer
            Insert( Key, Buffer, Length(Buffer)-CursorPos+1 )
        end;
     end else
     if key = #8 then
     {3-DIGITATO NELL'EDIT BACKSPACE}
        Delete( Buffer, Length(Buffer)-CursorPos, 1 );
     { IN OGNI CASO, PROSEGUI..}
     { A questo punto il car appena battuto � stato dal prg }
     { inserito al punto giusto della stringa di edit Buffer}
     Key := #0;
     Text := Buffer;
     { La stringa nell'edit � una stringa formattata con il formato
       generato in FormatString. Poich� alla immissione di ogni nuovo
       carattere la stringa si modifica, ad ogni carattere immesso
       essa va riformattata.
       Per evitare errore di formattazione, questa va evitata nei due
       casi seguenti:
       1 - quando nell'edit c'� un solo carattere '-' o '+'
         (Es: -, xch� FormatFloat di '-' darebbe errore)
       2 - quando l'ultimo carattere immesso nell'edit sia il
         separatore decimale
         (Es: 12, xch� FormatFloat di '12,' darebbe errore)
     }
     if length(Text) > 0 then
        //(Text pu� essere vuoto x effetto di cancellazione)
        if (length(Text) = 1) and (Text='-') then
           //non fare niente
           else
        //Evita la Formattazione della stringa immessa solo se l'ultimo car
        //immesso � il separatore decimale (es. se text = '12,' )
        if pos(DecimalSeparator,Text[length(Text)]) = 0 then
           {-----------}
           Reformat;
           {-----------}
     //A questo punto Text � riformattato e pu� contenere
     // separatori di migliaia e decimali
     //imposta in SelStart la posiz del prox car (da 0)
     SelStart := Length(Text)-CursorPos; //CursorPos=Len(buffer)-SelStart
  end; //if NumberOnly
end;
function TFullEdit.StripThousSep(AString: string): string;
{ Questa funzione accetta in input in aString una stringa
  formattata con separatori di migliaia e decimali
  nel qual caso la priva temporaneamente del separatore
  delle migliaia, ai fini della riformattazione della
  stringa con il formato in FormatString, che pu� sempre
  variare...
}
begin
  //Cancella tutti i separatori di migliaia
  while (Pos(ThousandSeparator, AString) > 0 ) do
    delete(AString, Pos(ThousandSeparator, AString), 1);
  Result := AString;
end;
procedure TFullEdit.Reformat;
var
  i: integer;
begin
  //reinizializza sempre la stringa del formato ( FormatString )
  if FThousendSep then
     FormatString := '#,##0.'
  else
     FormatString := '#0.';
  // nel formato, includi tante posizioni decimali quanti
  // decimali effettivamente sono stati immessi nell'edit
  Text:= StripThousSep(Text);
  nDecimals := 0;
  if pos(DecimalSeparator,Text) > 0 then
  begin
     //Se ci sono, conta i decimali gi� presenti nell'edit
     if pos(DecimalSeparator,Text) > 0 then
        for i:= pos(DecimalSeparator,Text) to length(text)-1 do
          inc(nDecimals)
     else
        nDecimals:= 0;
     //Crea la stringa di formattazione con tante cifre di decimali
     //quanti quelli gi� presenti nel numero immesso nell'edit
     for i := 1 to nDecimals do FormatString := FormatString + '0';
     //Usa la stringa di formattazione per presentare nell'edit
     //(in Text) il numero immesso
     Text := FormatFloat(FormatString, StrToFloat(StripThousSep(Text)));
  end else
     //Decimali non ce ne sono nell'edit, quindi usa la formatString
     //cos� come inizializzata
     Text := FormatFloat(FormatString, StrToFloat(StripThousSep(Text)));
end;
procedure TFullEdit.CMEnter(var Message: TCMGotFocus);
begin
  SelStart := Length(Text);
  inherited;
end;
procedure TFullEdit.DoEnter;
begin
  SetColorFocused(FColorFocused);
  inherited DoEnter;
end;
procedure TFullEdit.DoExit;
begin
  SetColorNormal(FColorNormal);
  inherited DoExit;
end;
procedure Register;
begin
  RegisterComponents('3PartiPro', [TFullEdit]);
end;
end.

 does not exist" ...
L'errore viene restituito quando inserisci il controllo in un Form, a 
designtime, oppure a runtime creandolo dinamicamente via codice?
E' possibile che tu abbia abilitato la compilazione con i "runtime 
package" nel progetto di prova, e che il package che contiene il 
componente non sia stato ricompilato con la modifica?
Ciao,
   Marco.
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)

 ha scritto nel messaggio 
news:4a828a00$1...@news.x-privat.org...


 ha scritto nel messaggio 
news:4a828a62$0$34619$4faf...@reader4.news.tin.it...


 
non conosco la gestione dei componenti nuova ( diciamo da Delphi 3 in 
poi hanno cambiato ).
Hai provato a togliere il componente dalla non so come si chiama ( 
dovrebbe essere qualcosa che suona come package ), proprio togliere 
tutto e riregistrare il tutto da capo.
Se non sbaglio sono divisi in componenti in designtime e runtime ( 
magari la sparo grossa ) e non sono perfettamente allineati come 
aggiornamento.

 ha scritto nel messaggio 
news:4a8303c9$0$6155$4faf...@reader5.news.tin.it...


 
- copio e incollo
- registro il componente ( con il D2 per� non ho i package )
- inserisco 3 TFullEdit
- imposto la propriet� TabOnEnter ( sia da design che da codice )
- runno.
Non c'entra, mi da un warning sul distruttore.
Non conoscendoli, mi permetto di insistere sul package.

 ha scritto nel messaggio 
news:4a8286c2$0$34618$4faf...@reader4.news.tin.it...


 dal package e ricompilare. Poi l'ho reinserito e ricompilato.
invece di ricompilare, sopratutto se si tratta di pakages, meglio una
build
A.

 componente dal package e ricompilare. Poi l'ho reinserito e ricompilato.
Era ci� che intendevo io quando ho scritto
"...e che il package che contiene il componente non sia stato 
ricompilato con la modifica?"
Secondo me, il package non era completamente aggiornato con tutte le 
modifiche che hai fatto per integrare quella propriet�, bench� sia 
difficile fare una diagnosi senza essere fisicamente sul tuo PC per 
verificare la situazione generale.
Ciao!
