Forum > Packages and Libraries

New component installs, but identifier not found

(1/1)

dbaxter:
This is similar to the OnGuard discussion earlier, but evidently different enough that the fix described there doesn't correct my problem. Again the sequence:
- create a new component package
- compile
- install (rebuild IDE)
- component appears in the palette
- create a new project
- add the component in the form
- IDE automatically adds the threadtimer unit
- IDE automatically adds the tthreadtimer dependency
- properties can be set, event procedures written

But when you try to run the program, it stops at the line in the TForm class description where the timer component is declared:
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
...other components
   ThreadTimer1: TThreadTimer;   <- stops here with message "Identifier not Found - TThreadTimer"

I've looked at the comments earlier and checked that design and runtime is checked and everything looks similar to the settings for SpdoSerial package, which went in OK. What magical setting am I missing?

Lazarus 1.0, OSX Mountain Lion
   

ttomas:
Try in Lazarus main menu Tools->Rescan FPC Source Directory?
Sometimes help  :-X

dbaxter:
Thanks- tried that, but no joy. Perhaps if I show the component code, something will jump out to a more knowledgeable person than me:

--- Code: ---unit ThreadTimer;

interface

uses
  Classes;

type

  TThreadTimer = class;

  TTimerThread = class( TThread )
  private
    tt: TThreadTimer;
  protected
    procedure DoExecute;
  public
    constructor CreateTimerThread;
    procedure Execute; override;
  end;

  TThreadTimer = class(TComponent)
  private
    FInterval: integer;
    FPriority: TThreadPriority;
    FOnTimer: TNotifyEvent;
    bStop: boolean;
    bRunning: boolean;
    FEnabled: boolean;
  protected
    procedure setEnabled( b: boolean );
    procedure Start;
    procedure Stop;
  public
    constructor Create( AOwner: TComponent ); override;
  published
    property Enabled: boolean read FEnabled write setEnabled;
    property Interval: integer read FInterval write FInterval;
    property ThreadPriority: TThreadPriority read FPriority write FPriority default tpNormal;
    property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
  end;

procedure Register;

implementation

uses
  SysUtils;

{ No need to pull in the Windows unit. Also this works on all platforms. }
function _GetTickCount: Cardinal;
begin
  Result := Cardinal(Trunc(Now * 24 * 60 * 60 * 1000));
end;

(*********************************************
Initialize thread priority
*********************************************)
constructor TThreadTimer.Create( AOwner: TComponent );
begin
  inherited Create( AOwner );
  FPriority := tpNormal;
end;

(*********************************************
Changing the Enabled property calls either
Start or Stop protected methods.
*********************************************)
procedure TThreadTimer.setEnabled( b: boolean );
begin
  if b then
    Start
  else
    Stop;
  FEnabled := bRunning;
end;

(*********************************************
Starting the timer creates an instance of
TTimerThread and launches the thread.
*********************************************)
procedure TThreadTimer.Start;
begin
  if bRunning then
    Exit;
  bStop := false;
  if not (csDesigning in ComponentState) then
  begin
    with TTimerThread.CreateTimerThread do
    begin
      ThreadPriority := FPriority;
      Resume;
    end;
  end;
  bRunning := true;
end;

(*********************************************
Stopping the timer just sets the stop flag to
true, the TTimerThread's Execute method will
then end and the thread will be destroyed.
*********************************************)
procedure TThreadTimer.Stop;
begin
  bStop := true;
  bRunning := false;
end;

constructor TTimerThread.CreateTimerThread;
begin
  inherited Create( true );
  self.tt := tt;
  FreeOnTerminate := true;
end;

(*********************************************
Execute method for the spawned thread.  Just
repeats while the timer is enabled, and calls the
timer object's OnTimer event.
*********************************************)
procedure TTimerThread.Execute;
var
  SleepTime, Last: integer;
begin
  while not tt.bStop do
  begin
    //Last := timeGetTime;
    Last := _GetTickCount;
    Synchronize( @DoExecute );
    //SleepTime := tt.FInterval - ( timeGetTime - Last );
    SleepTime := tt.FInterval - (_GetTickCount - Last);
   if SleepTime < 10 then
      SleepTime := 10;
    sleep( SleepTime );
  end;
end;

(*********************************************
This method is called within the TTimerThread's
Execute, using the Synchronize method.  This is
because we need to call the event handler from
the main VCL thread.
*********************************************)
procedure TTimerThread.DoExecute;
begin
  with tt do
  begin
    if Assigned( FOnTimer ) then
      FOnTimer( tt );
  end;
end;

procedure Register;
begin
  RegisterComponents( 'System', [TThreadTimer] );
end;

end.

--- End code ---

Hope this helps.

Navigation

[0] Message Index

Go to full version