Recent

Author Topic: Identfier not found "Sender"  (Read 3256 times)

draggon

  • New Member
  • *
  • Posts: 41
Identfier not found "Sender"
« on: April 25, 2018, 12:55:13 pm »
Trying to use Timer in unit not assigned to any form when executing the following:
Code: Pascal  [Select][+][-]
  1.         acc_timer.OnTimer:= Access_timer(Sender: TObject);
  2.  
I encountered the following: Identifier not found "Sender" and Syntax error, ")" expected but ":" found. 

The conter is declared:
Code: Pascal  [Select][+][-]
  1. Type
  2.     Tacc_timer = Class(TTimer)
  3. end;
  4.  
  5.  
and
Code: Pascal  [Select][+][-]
  1.    acc_timer: Tacc_timer;
  2.  

and
Code: Pascal  [Select][+][-]
  1. procedure access_timer(Sender: TObject);
  2.  

Procedure for testing:

Code: Pascal  [Select][+][-]
  1. procedure access_timer(Sender: TObject);
  2.  
  3. begin
  4.   counter:= counter + 1;
  5.   if counter = 5 then
  6.   begin
  7.     acc_timer.Enabled:= False;
  8.     ShowMessage('done');
  9.   End;
  10. end;
  11.  

Thanks
« Last Edit: April 25, 2018, 01:03:04 pm by draggon »

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: Identfier not found "Sender"
« Reply #1 on: April 25, 2018, 01:12:53 pm »
Code: [Select]
acc_timer.OnTimer:= Access_timer(Sender: TObject);
                                        ^^^^^^
Don't include the ": TObject".
Furthermore, it depends on where you call this, if Sender is a valid variable.

Normally you would use nil or Self in this call.

Because you don't do anything with Sender in Access_timer it's safe to just pass nil.

Code: [Select]
acc_timer.OnTimer:= Access_timer(nil);
Also make sure acc_timer is "Created" (otherwise you get another error during runtime).
« Last Edit: April 25, 2018, 01:14:51 pm by rvk »

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: Identfier not found "Sender"
« Reply #2 on: April 25, 2018, 01:14:32 pm »
I think it should be:
Code: Pascal  [Select][+][-]
  1.         acc_timer.OnTimer:= @Access_timer;

If it doesn't work, maybe you need to add:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}

If it still doesn't work, you must change the procedure to a class method, read more:
http://forum.lazarus.freepascal.org/index.php/topic,36677.msg244660.html

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: Identfier not found "Sender"
« Reply #3 on: April 25, 2018, 01:16:37 pm »
I think it should be:
Code: Pascal  [Select][+][-]
  1.         acc_timer.OnTimer:= @Access_timer;
Woops, yes, you are correct.

@draggon, also make sure you create acc_timer somewhere.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: Identfier not found "Sender"
« Reply #4 on: April 25, 2018, 01:24:11 pm »
I think it should be:
Code: Pascal  [Select][+][-]
  1.         acc_timer.OnTimer:= @Access_timer;
Woops, yes, you are correct.

@draggon, also make sure you create acc_timer somewhere.
Woops, caught out by silly mode... Again. :-[ :P
Specialize a type, not a var.

draggon

  • New Member
  • *
  • Posts: 41
Re: Identfier not found "Sender"
« Reply #5 on: April 26, 2018, 10:25:11 am »
Thanks for support, nevertheless no success yet.

I used both
Code: Pascal  [Select][+][-]
  1.         acc_timer.OnTimer:= access_timer(nil);
  2.  

and
Code: Pascal  [Select][+][-]
  1.         acc_timer.OnTimer:= @access_timer(nil);
  2.  

If not using ":Object" how the declaration and the header of the procedure shoul look like?

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: Identfier not found "Sender"
« Reply #6 on: April 26, 2018, 10:26:33 am »
Thanks for support, nevertheless no success yet.
I used both
Did you try the suggestion of Handoko?
acc_timer.OnTimer:= @Access_timer;
or
acc_timer.OnTimer:= Access_timer;

Maybe you should show your complete code because I still don't know if you create acc_timer.

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: Identfier not found "Sender"
« Reply #7 on: April 26, 2018, 10:34:10 am »
If not using ":Object" how the declaration and the header of the procedure shoul look like?

You can create a class method that call to the 'common' procedure. You pass the class method to the acc_Timer.OnTimer.

draggon

  • New Member
  • *
  • Posts: 41
Re: Identfier not found "Sender"
« Reply #8 on: April 26, 2018, 10:37:16 am »
Failure occurs during compilation.  Error occurs:

Incompatible type for arg. no. 1: Got "untyped", expected "<procedure variable type of procedure(TObject) of object;Register>" and there is a hint Found declaration SetOnTimer(TNotifyEvent).

Code: Pascal  [Select][+][-]
  1.     begin
  2.  
  3.         acc_timer:= Tacc_timer.Create(nil);
  4.         acc_timer.Interval:= 1000;
  5.         acc_timer.OnTimer:= access_timer; //this is the errorneous line
  6.         acc_timer.Enabled:= True;
  7. end;
  8.  

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: Identfier not found "Sender"
« Reply #9 on: April 26, 2018, 10:40:30 am »
Failure occurs during compilation.  Error occurs:
Show complete code.

draggon

  • New Member
  • *
  • Posts: 41
Re: Identfier not found "Sender"
« Reply #10 on: April 26, 2018, 10:42:48 am »
I also tried to declare the procedure like this:

Code: Pascal  [Select][+][-]
  1. Type
  2.     Tacc_timer = Class(TTimer)
  3.     Public
  4.        procedure access_timer;
  5. end;
  6.  
In such case there is an error Identifier not found "access_timer"

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: Identfier not found "Sender"
« Reply #11 on: April 26, 2018, 10:46:56 am »
This is how I force a 'common' procedure to become a class method:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, Forms, Controls, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure FormCreate(Sender: TObject);
  17.   private
  18.     procedure SayHello(Sender: TObject);
  19.   end;
  20.  
  21. var
  22.   Form1: TForm1;
  23.  
  24. implementation
  25.  
  26. procedure Hello; // This is a common procedure
  27. begin
  28.   ShowMessage('Hello');
  29. end;
  30.  
  31. {$R *.lfm}
  32.  
  33. { TForm1 }
  34.  
  35. procedure TForm1.FormCreate(Sender: TObject);
  36. begin
  37.   Button1.OnClick := @SayHello;
  38. end;
  39.  
  40. procedure TForm1.SayHello(Sender: TObject);
  41. begin
  42.   Hello; // It calls a common procedure
  43. end;
  44.  
  45. end.

Line #37 - passing the class method to the OnClick event
Line #40 - is a class method calling a 'common' procedure
Line #26 - is the 'common' procedure

If you can you should make the procedure become a class method. If you cant, you can use the trick to force it to be a class method.

draggon

  • New Member
  • *
  • Posts: 41
Re: Identfier not found "Sender"
« Reply #12 on: April 26, 2018, 10:48:21 am »
The code is in unit global_vars that is not assigned to any form. There are global variables stored and procedures used by multiple units.It relates to our previous communication i.e. when the excel file is in use by someone else I want to give the user 5 attempts by 1 second. This is not finished yet.

Code: Pascal  [Select][+][-]
  1. procedure open_workbook(a, b: ShortString; var c, d: Integer);
  2.  
  3. {Based on input variables assigned to required worksheet and range to be
  4. maintained last_row and last_column values are determined fro reading and writing
  5. to data table}
  6.  
  7. begin
  8.  
  9.   XLApp:= CreateOleObject('Excel.Application');
  10.   XLApp.Visible:= False;
  11.   XLApp.DisplayAlerts:= False;
  12.   XLApp.Workbooks.Open[path];
  13.  
  14.   if XLApp.Workbooks.Open(path).ReadOnly then
  15.  
  16.   if counter = 0 then
  17.     begin
  18.     Showmessage('Data file opened by another user' + sLineBreak +
  19.             'Accessing the file may take a while');
  20.     end
  21.     else
  22.     begin
  23.  
  24.         acc_timer:= Tacc_timer.Create(nil);
  25.         acc_timer.Interval:= 1000;
  26.         acc_timer.OnTimer:= access_timer; //this is the errorneous line
  27.         acc_timer.Enabled:= True;
  28.     end;
  29.  
  30.     begin
  31.       Showmessage('Operation timed out' + sLineBreak +
  32.           'Application will be terminated' + sLineBreak +
  33.           'Try later');
  34.       Application.Terminate;
  35.  
  36.     End;
  37.  
  38.   {Finds the number of the rows and columns of the range users in Worksheet users.}
  39.   c := XLApp.ActiveWorkBook.WorkSheets[a].Range[b].Rows.Count;
  40.   d:= XLApp.ActiveWorkBook.WorkSheets[a].Range[b].Columns.Count;
  41.  
  42. end;
  43.  

Code: Pascal  [Select][+][-]
  1. procedure access_timer;
  2.  
  3. begin
  4.   counter:= counter + 1;
  5.   if counter = 5 then
  6.   begin
  7.     acc_timer.Enabled:= False;
  8.     ShowMessage('done');
  9.   End;
  10. end;
  11.  

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: Identfier not found "Sender"
« Reply #13 on: April 26, 2018, 10:58:32 am »
Okay, your case it a bit different.

Where did you get the Tacc_timer? Did you write it your own? If yes, you should modify the code to support non-class-method procedure to link to the event. Or you can write a new class inherited from Tacc_timer, there set the event.

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: Identfier not found "Sender"
« Reply #14 on: April 26, 2018, 11:08:19 am »
Now we are getting somewhere when you provide some real code.

You can make access_timer part of the Tacc_timer class itself. It's the easiest way.

Code: Pascal  [Select][+][-]
  1. type
  2.   Tacc_timer = class(TTimer)
  3.   public
  4.     procedure access_timer(Sender: TObject);
  5.   end;
  6.  
  7. //...
  8.  
  9. procedure Tacc_timer.access_timer(Sender: TObject);
  10. begin
  11.   counter:= counter + 1;
  12.   if counter = 5 then
  13.   begin
  14.     Self.Enabled:= False; // Self is the save as Tacc_timer
  15.     ShowMessage('done');
  16.   end;
  17. end;
  18.  
  19. //...
  20.  
  21.   acc_timer:= Tacc_timer.Create(nil);
  22.   acc_timer.Interval:= 1000;
  23.   acc_timer.OnTimer:= @acc_timer.access_timer; // if in Delphi-mode you need to remove the @
  24.   acc_timer.Enabled:= True;

 

TinyPortal © 2005-2018