Board index » cppbuilder » Problems in creating new properties and default key handling behaviour

Problems in creating new properties and default key handling behaviour

In all the time I've used BCB, I have not had need to make my own
components. But I have been asked to make some example projects for use by
one of my colleagues. I made examples for DLLs and packages and context
sensitive help, but I have run into a problem with the example for making a
component. I used the component wizard to make a new component derived from
TEdit, with a view toward adding a double property, and changing the default
behaviour of the key press handler. The resulting header and cpp files are
appended. These are simple enough that my intent ought to be obvious.
Basically, I am creating, as an example, an edit control that will ignore
any character that is not part of a valid floating point number, and which
has a function to verify that its contents do in fact represent a number.
However, following the example from the Developer's Guide *that came with
BCB6), page 48-6, I declared and implemented a keypress event handler, but
the declaration gets an error message. Also, I followed the examples for
making a property, and that declaration, too, causes problems. Here are the
exact error messages:

[C++ Error] SuperDuperEdit.h(16): E2113 Virtual function '_fastcall

TSuperDuperEdit::KeyPress(char &)' conflicts with base class 'TWinControl'

[C++ Error] SuperDuperEdit.h(77): E2313 Constant expression required

The first error relates to my declaration of my keypress function, and the
second relates to my declaration of the "Value" proprty I'm trying to add.
What were my errors? I'll bet that my implementation of keypress needs to be
modified to have the conditional control whether or not the handler from
TWinControl is used, rather than just setting the value of Key to 0; right?

Thanks,

Ted

===========SuperDuperEdit.h=============================

//--------------------------------------------------------------------------
-

#ifndef SuperDuperEditH

#define SuperDuperEditH

//--------------------------------------------------------------------------
-

#include <SysUtils.hpp>

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

//--------------------------------------------------------------------------
-

class PACKAGE TSuperDuperEdit : public TEdit

{

private:

double value;

protected:

__fastcall void KeyPress(char &Key);

public:

__fastcall TSuperDuperEdit(TComponent* Owner);

__fastcall double GetValue(void) { return value; };

__fastcall void SetValue(double v) { value = v; };

__fastcall bool DataIsValid(void);

__published:

__property Anchors = {default=3};

__property AutoSelect = {default=1};

__property AutoSize = {default=1};

__property BevelEdges = {default=15};

__property BevelInner = {index=0, default=2};

__property BevelKind = {default=0};

__property BevelOuter = {index=1, default=1};

__property BiDiMode ;

__property BorderStyle = {default=1};

__property CharCase = {default=0};

__property Color = {default=-2147483643};

__property Constraints ;

__property Ctl3D ;

__property DragCursor = {default=-12};

__property DragKind = {default=0};

__property DragMode = {default=0};

__property Enabled = {default=1};

__property Font ;

__property HideSelection = {default=1};

__property ImeMode = {default=3};

__property ImeName ;

__property MaxLength = {default=0};

__property OEMConvert = {default=0};

__property ParentBiDiMode = {default=1};

__property ParentColor = {default=0};

__property ParentCtl3D = {default=1};

__property ParentFont = {default=1};

__property ParentShowHint = {default=1};

__property PasswordChar = {default=0};

__property PopupMenu ;

__property ReadOnly = {default=0};

__property ShowHint ;

__property TabOrder = {default=-1};

__property TabStop = {default=1};

__property Text ;

__property Visible = {default=1};

__property OnChange ;

__property OnClick ;

__property OnContextPopup ;

__property OnDblClick ;

__property OnDragDrop ;

__property OnDragOver ;

__property OnEndDock ;

__property OnEndDrag ;

__property OnEnter ;

__property OnExit ;

__property OnKeyDown ;

__property OnKeyPress ;

__property OnKeyUp ;

__property OnMouseDown ;

__property OnMouseMove ;

__property OnMouseUp ;

__property OnStartDock ;

__property OnStartDrag ;

__property double Value = {read=GetValue,write=SetValue,default=0.0 };

Quote
};

//--------------------------------------------------------------------------
-

#endif

===========SuperDuperEdit.cpp===========================

//--------------------------------------------------------------------------
-

#include <vcl.h>

#pragma hdrstop

#include "SuperDuperEdit.h"

#pragma package(smart_init)

//--------------------------------------------------------------------------
-

// ValidCtrCheck is used to assure that the components created do not have

// any pure virtual functions.

//

static inline void ValidCtrCheck(TSuperDuperEdit *)

{

new TSuperDuperEdit(NULL);

Quote
}

//--------------------------------------------------------------------------
-

__fastcall TSuperDuperEdit::TSuperDuperEdit(TComponent* Owner)

: TEdit(Owner)

{

Quote
}

//--------------------------------------------------------------------------
-

void __fastcall TSuperDuperEdit::KeyPress(char &Key) {

if (isdigit(Key) || (Key == '.') || (Key == 'e') || (Key == 'E') || (Key ==

'-')) return;

if (isalpha(Key) || ispunct(Key) )Key = 0;

Quote
};

//--------------------------------------------------------------------------
-

bool __fastcall TSuperDuperEdit::DataIsValid(void) {

try {

value = Text.ToDouble();

return true;

Quote
} catch ( ... ) {

return false;

Quote
};
};

//--------------------------------------------------------------------------
-

namespace Superduperedit

{

void __fastcall PACKAGE Register()

{

TComponentClass classes[1] = {__classid(TSuperDuperEdit)};

RegisterComponents("Samples", classes, 0);

Quote
}
}

//--------------------------------------------------------------------------
-
 

Re:Problems in creating new properties and default key handling behaviour


Quote
"Ted Byers" <r.ted.by...@sympatico.ca> wrote in message

news:3ea7387d$1@newsgroups.borland.com...

Quote
> [C++ Error] SuperDuperEdit.h(16): E2113 Virtual function '_fastcall

> TSuperDuperEdit::KeyPress(char &)' conflicts with base class 'TWinControl'

Your declaration for KeyPress() does not EXACTLY match the declaration
inside of TWinControl.  It should be like the following instead:

    protected:
        DYNAMIC void __fastcall KeyPress(char &Key);

Quote
> [C++ Error] SuperDuperEdit.h(77): E2313 Constant expression required

The 'default' clause for a property cannot use floating-point values, only
integers and booleans.

Quote
> I'll bet that my implementation of keypress needs to be modified
> to have the conditional control whether or not the handler from
> TWinControl is used, rather than just setting the value of Key to 0;
> right?

Only if you want the inherited OnKeyPress event to be triggered, as that is
the only thing TWinControl::KeyPress() does.  Since your code is re-exposing
that event, then I'll assume that you do want it triggered.  In which case
yes, you will need to pass allowed keypresses back to the base class for
further processing.

Gambit

Re:Problems in creating new properties and default key handling behaviour


Thanks, Gambit,

That did the trick.  However, I have one more question.  If default values
can be only booleans and integers, how does one mimic the behaviour of
TEdit, where the Text data member is given a default value of the name of
the instance?  I want to change that to the string "0.0".

I will be changing the setter and getter functions for the new property
Value, so that when the program assigns a value to Value, the Text data
member is also changed to reflect the new value, perhaps constrained
according to options the user has set WRT precision and format (which in
turn suggest a number of new properties).

Thanks,

Ted

Re:Problems in creating new properties and default key handling behaviour


Quote
"Ted Byers" <r.ted.by...@sympatico.ca> wrote in message

news:3ea84069$1@newsgroups.borland.com...

Quote
> If default values can be only booleans and integers

<snip>

Please re-read my earlier comments.  I did not say default *values* couldn't
be floating-point values.  I said the 'default' *clause* of the __property
declaration cannot be floating-point.  They are different things.  Either
way, though, the 'default' clause of the __property declaration does not
actually set the property.  It only tells the DFM streaming system what the
default value is, so the streaming will ignore the propety if it is already
set to its default value.  The properties actual value itself must be set in
the component's constructor regardless.  That is where the actual assignment
occurs.

Quote
> how does one mimic the behaviour of TEdit, where the Text
> data member is given a default value of the name of the instance?

That is a completely different matter altogether, a completely different
implementation, and is not relavent to this particular discussion.

Quote
> I want to change that to the string "0.0".

Just set the Text property in the component's constructor or
AfterConstruction() method.

Gambit

Other Threads