Board index » delphi » App compiles fine but exception on start, why?

App compiles fine but exception on start, why?

(Posted to the wrong group so here it is again)

I have developed a component to handle some security issues. This
component contains among other stuff a timer that is created in
component.Create wher I also set interval to 0 and enabled to false.
If I put this component on a form and compile the application all is
fine, but when I try to start this minimalistic app then there is
immediately a very strange exception:
"Exception EClassNotFound in module Project1.exe at 0000CA2A
Class TTimer not found."
If I step through the start sequence I get to the Create and the timer
property setting and there are no problems. Then after leaving Create
I get to the setters for the component properties and there I again
meet the timer and it is set successfully. Then at the very end
(stepping next on the 'end' line) there is this exception.

Where is it coming from and what can be done about it?

Final note:
If I try to remove the component from the form then Delphi locks up
completely! I cannot even get to Task Manager easily to kill it off.
I am running Delphi 5 pro on a Win XP-Pro system.

/Bo

Bo Berglund
bo.bergl...@telia.com

 

Re:App compiles fine but exception on start, why?


"Bo Berglund" <bo.bergl...@telia.com> skrev i melding
news:3ce060d3.1169459203@news.telia.net...

Quote
> (Posted to the wrong group so here it is again)

> I have developed a component to handle some security issues. This
> component contains among other stuff a timer that is created in
> component.Create wher I also set interval to 0 and enabled to false.
> If I put this component on a form and compile the application all is
> fine, but when I try to start this minimalistic app then there is
> immediately a very strange exception:
> "Exception EClassNotFound in module Project1.exe at 0000CA2A
> Class TTimer not found."

I believe the problem may be that if you don't use TTimer in your
application, the class won't be registered. And - and here is the strange
point - that you have created your component so that a TTimer - property is
to be read, either when loading your component *or* as a result ogf your
component creating a TTimer object that is streamed with the form. The
workaround is to do a RegisterClass(TTimer);. I wouldn't do that if I
weren't sure about what the trouble was...

Quote
> If I step through the start sequence I get to the Create and the timer
> property setting and there are no problems. Then after leaving Create
> I get to the setters for the component properties and there I again
> meet the timer and it is set successfully. Then at the very end
> (stepping next on the 'end' line) there is this exception.

> Where is it coming from and what can be done about it?

> Final note:
> If I try to remove the component from the form then Delphi locks up
> completely! I cannot even get to Task Manager easily to kill it off.
> I am running Delphi 5 pro on a Win XP-Pro system.

Creating a component that can actually be removed without bombing is one of
the more challenging tasks in delphi. ;-) The only tougher one is to make it
survive deleting a *referenced component*.
- You'll have to read your code again, asking yourself: "What about this
reference, will it allways be valid ?"
The "classic" error is when 2 components reference each other, and these
references are not "enforced" by notifications (see TComponent's methods:
FreeNotifier / Notification).
--
Bj?rge S?ther
bjorge@hahaha_itte.no

Re:App compiles fine but exception on start, why?


I 'solved' my problem by adding a dummy TTimer to the same Data Module
where I had placed the security component. After this there were no
more exceptions. Of course I don't need the timer, but its presence
stops the exceptions....

/Bo

On Tue, 14 May 2002 06:20:58 GMT, "Bj?rge S?ther"

Quote
<bjorge@hahaha_itte.no> wrote:
>"Bo Berglund" <bo.bergl...@telia.com> skrev i melding
>news:3ce060d3.1169459203@news.telia.net...
>> (Posted to the wrong group so here it is again)

>> I have developed a component to handle some security issues. This
>> component contains among other stuff a timer that is created in
>> component.Create wher I also set interval to 0 and enabled to false.
>> If I put this component on a form and compile the application all is
>> fine, but when I try to start this minimalistic app then there is
>> immediately a very strange exception:
>> "Exception EClassNotFound in module Project1.exe at 0000CA2A
>> Class TTimer not found."

>I believe the problem may be that if you don't use TTimer in your
>application, the class won't be registered. And - and here is the strange
>point - that you have created your component so that a TTimer - property is
>to be read, either when loading your component *or* as a result ogf your
>component creating a TTimer object that is streamed with the form. The
>workaround is to do a RegisterClass(TTimer);. I wouldn't do that if I
>weren't sure about what the trouble was...

>> If I step through the start sequence I get to the Create and the timer
>> property setting and there are no problems. Then after leaving Create
>> I get to the setters for the component properties and there I again
>> meet the timer and it is set successfully. Then at the very end
>> (stepping next on the 'end' line) there is this exception.

>> Where is it coming from and what can be done about it?

>> Final note:
>> If I try to remove the component from the form then Delphi locks up
>> completely! I cannot even get to Task Manager easily to kill it off.
>> I am running Delphi 5 pro on a Win XP-Pro system.

>Creating a component that can actually be removed without bombing is one of
>the more challenging tasks in delphi. ;-) The only tougher one is to make it
>survive deleting a *referenced component*.
>- You'll have to read your code again, asking yourself: "What about this
>reference, will it allways be valid ?"
>The "classic" error is when 2 components reference each other, and these
>references are not "enforced" by notifications (see TComponent's methods:
>FreeNotifier / Notification).
>--
>Bj?rge S?ther
>bjorge@hahaha_itte.no

Bo Berglund
bo.bergl...@telia.com

Re:App compiles fine but exception on start, why?


"Bo Berglund" <bo.bergl...@telia.com> skrev i melding
news:3ce17eb4.1242644125@news.telia.net...

Quote
> I 'solved' my problem by adding a dummy TTimer to the same Data Module
> where I had placed the security component. After this there were no
> more exceptions. Of course I don't need the timer, but its presence
> stops the exceptions....

But you have a TTimer created by your component, OK ?
If creating this component results in a TTimer object being inserted in the
form's components list, then it will be streamed. That is the reason for
your error, it tries to read a TTimer component from the .dfm resource. It
should be created without being inserted in *any* 'components' list (Owner =
nil !). Or - it should be a published property...then I believe class
registration will be taken care of "by magic".
--
Bj?rge S?ther
bjorge@hahaha_itte.no

Re:App compiles fine but exception on start, why?


On Tue, 14 May 2002 21:38:09 GMT, "Bj?rge S?ther"

Quote
<bjorge@hahaha_itte.no> wrote:
>"Bo Berglund" <bo.bergl...@telia.com> skrev i melding
>news:3ce17eb4.1242644125@news.telia.net...
>> I 'solved' my problem by adding a dummy TTimer to the same Data Module
>> where I had placed the security component. After this there were no
>> more exceptions. Of course I don't need the timer, but its presence
>> stops the exceptions....

>But you have a TTimer created by your component, OK ?
>If creating this component results in a TTimer object being inserted in the
>form's components list, then it will be streamed. That is the reason for
>your error, it tries to read a TTimer component from the .dfm resource. It
>should be created without being inserted in *any* 'components' list (Owner =
>nil !). Or - it should be a published property...then I believe class
>registration will be taken care of "by magic".
>--
>Bj?rge S?ther
>bjorge@hahaha_itte.no

Hmm,
I don't understand the statements above (I am by far no Delphi
*expert*....).
Here is my component declaration, can you see where I am off? (The
purpose of the component is to encapsulate the use of a Sentinel
hardware key, and the timer is intended as an independent key checker
at a predetermined interval)

TSentinelAGI = class(TComponent)
private
{ Private declarations }
 FSentinelPacket : RB_SPRO_APIPACKET;
 FOnAlarm: TAlarmEvent;
 FTimer: TTimer;
 FLastErrorCode,
 FKeySerial,
 FAppNumber,
 FInterval: word;
 FLastErrorText,
 FAppName: string;
 FAutoTerminate,
 FbInitialized: boolean;
 procedure SetAppNumber (value: word);
 function GetLicense: word;
 function GetSerialNo: word;
 function ClearKey: boolean;
 procedure Delay(T: cardinal);
 function ActivateAppInKey(var status: word; nApp: word; var thePacket
: RB_SPRO_APIPACKET): boolean;
 function CheckSuperProKey(var status: word; nApp: word; var thePacket
: RB_SPRO_APIPACKET): boolean;
 function DeActivateAppInKey(var status: word; nApp: word; var
thePacket : RB_SPRO_APIPACKET): boolean;
 function GenerateSuperProQueries(nApp, nQueries: word; slQueryFile:
TStrings; var thePacket : RB_SPRO_APIPACKET): boolean;
 function InitSuperProKey(var thePacket : RB_SPRO_APIPACKET): word;
 function OverWriteWord(var status: word; data, address: word; var
thePacket : RB_SPRO_APIPACKET; dataAccessCode: word): boolean;
 function ReprogramAll(var status: word; var thePacket :
RB_SPRO_APIPACKET): boolean;
 procedure SetAppError(ErrorCode: word);
 procedure ClearAppError;
 function StatusDesc(status: WORD): string;
 procedure Swap32 (var Source; bFlip: boolean);
 function WriteWordToKey(var status: word; data, address: word; var
thePacket : RB_SPRO_APIPACKET): boolean;
 function GetDate: TDateTime;
 procedure SetDate(const Value: TDateTime);
 procedure SetInterval(const Value: word);
 function GetInfo: word;
 procedure SetInfo(const Value: word);
 procedure OnCheckTimer(Sender: TObject);
protected
{ Protected declarations }
public
{ Public declarations }
 constructor Create(AOwner: TComponent); override;
 function InitKey: boolean;
 function CheckKey: boolean;
 function CheckCurrentKey: boolean;
 function Activate: boolean;
 function DeActivate: boolean;
 function ReprogramKey: boolean;
 function SetLicense(value: word): boolean;
 function MakeLicense(var sLicense:string; nSerial, nProg, nLicense,
nExpire, nData, nMode: word):boolean;
 function UpdateLicense(sLicense: string): boolean;
 function SearchSerial(nSerial: word): boolean;
 function SearchApp(nApp: word): boolean;
 function NextKey: boolean;
 function FirstKey: boolean;
 function CreateResponses(sFileName: string): boolean;
published
{ Published declarations }
 property AppNumber: word read FAppNumber write SetAppNumber default
1;
 property AppName: string read FAppName;
 property AutoTerminate: boolean read FAutoTerminate write
FAutoTerminate;
 property CheckInterval: word read FInterval write SetInterval;
 property ExpDate: TDateTime read GetDate write SetDate;
 property Info: word read GetInfo write SetInfo;
 property LastErrorCode: word read FLastErrorCode;
 property LastErrorText: string read FLastErrorText;
 property License: word read GetLicense;
 property SerialNo: word read GetSerialNo;
 property OnKeyAlarm: TAlarmEvent read FOnAlarm write FOnAlarm;
end;

Bo Berglund
bo.bergl...@telia.com

Re:App compiles fine but exception on start, why?


"Bo Berglund" <bo.bergl...@telia.com> skrev i melding
news:3ce1fc37.1274775515@news.telia.net...
Quote
> On Tue, 14 May 2002 21:38:09 GMT, "Bj?rge S?ther"
> <bjorge@hahaha_itte.no> wrote:

> >"Bo Berglund" <bo.bergl...@telia.com> skrev i melding
> >news:3ce17eb4.1242644125@news.telia.net...
> >> I 'solved' my problem by adding a dummy TTimer to the same Data Module
> >> where I had placed the security component. After this there were no
> >> more exceptions. Of course I don't need the timer, but its presence
> >> stops the exceptions....

> >But you have a TTimer created by your component, OK ?
> >If creating this component results in a TTimer object being inserted in
the
> >form's components list, then it will be streamed. That is the reason for
> >your error, it tries to read a TTimer component from the .dfm resource.
It
> >should be created without being inserted in *any* 'components' list
(Owner =
> >nil !). Or - it should be a published property...then I believe class
> >registration will be taken care of "by magic".
> >--
> Hmm,
> I don't understand the statements above (I am by far no Delphi
> *expert*....).
> Here is my component declaration, can you see where I am off? (The
> purpose of the component is to encapsulate the use of a Sentinel
> hardware key, and the timer is intended as an independent key checker
> at a predetermined interval)

> TSentinelAGI = class(TComponent)
> private
> { Private declarations }
>  FSentinelPacket : RB_SPRO_APIPACKET;
>  FOnAlarm: TAlarmEvent;
>  FTimer: TTimer;

[...]

Hi !

We need the line with TTimer.Create() to see how this is done.

A tip: You don't need a TTimer component, it's s easy to use SetTmer /
KillTimer WinAPI calls as a TTimer replacement (TTimer is a wrapper around
this functionality).

--
Bj?rge S?ther
bjorge@hahaha_itte.no

Re:App compiles fine but exception on start, why?


On Wed, 15 May 2002 08:14:08 GMT, "Bj?rge S?ther"

Quote
<bjorge@hahaha_itte.no> wrote:
>Hi !

>We need the line with TTimer.Create() to see how this is done.

>A tip: You don't need a TTimer component, it's s easy to use SetTmer /
>KillTimer WinAPI calls as a TTimer replacement (TTimer is a wrapper around
>this functionality).

>--
>Bj?rge S?ther
>bjorge@hahaha_itte.no

OK, here is the constructor:

constructor TSentinelAGI.Create(AOwner: TComponent);
begin
        inherited Create(AOwner);
        SetAppNumber(1);        {To set the default value}
        FTimer := TTimer.Create(Application);
        FTimer.Enabled := false;
        FTimer.Interval := 0;
        FTimer.OnTimer := OnCheckTimer;
        FAutoTerminate := false;
        FInterval := 0;
        FLastErrorCode := 0;
        FLastErrorText := '';
end;

/Bo

Bo Berglund
bo.bergl...@telia.com

Re:App compiles fine but exception on start, why?


"Bo Berglund" <bo.bergl...@telia.com> skrev i melding
news:3ce42e86.1418727812@news.telia.net...

Quote
> On Wed, 15 May 2002 08:14:08 GMT, "Bj?rge S?ther"
> <bjorge@hahaha_itte.no> wrote:

> >Hi !

> >We need the line with TTimer.Create() to see how this is done.

> >A tip: You don't need a TTimer component, it's s easy to use SetTmer /
> >KillTimer WinAPI calls as a TTimer replacement (TTimer is a wrapper
around
> >this functionality).

> >--
> >Bj?rge S?ther
> >bjorge@hahaha_itte.no

> OK, here is the constructor:

> constructor TSentinelAGI.Create(AOwner: TComponent);
> begin
> inherited Create(AOwner);
> SetAppNumber(1); {To set the default value}
> FTimer := TTimer.Create(Application);

Now, *this* was somewhat strange - using Application as FTimer's owner. Do
rather use

  FTimer := TTimer.Create(Self);

..and don't free it upon destroy; as this will be taken care of by the
inherited destructor (it destroys all owned components).

--
Bj?rge S?ther
bjorge@hahaha_itte.no

Other Threads