Greetings all coders. I'm having a bit of a head scratcher, and I can't afford to lose any more hair.
I've got a Callback sequence I thought was set up correctly but obviously not. I'm adding a progress signal to the COPYDIR unit (from Bastla).
I define the callback signature and a variable to hold it in COPYDIR. I Added a parameter to COPYDIR.CREATE to pass the COPYDIR routine. Following is generic illustration code, not the actual code.
Lazarus 4.2/FPC 3.2.2 on Windows 11/64bit
unit longprocess; {in actual code this is the COPYDIR unit}
{$MODE DELPHI}
type
tProgressCallback = function(const n,m:integer; const text:string):boolean; // NOT of object;
tlongrunner = class
private
_ProgressCallback : tProgressCallback; //assigned at create
public
constructor create(myCallBack : tProgressCallback);
function ProgressStep(n, m: integer; aText: string): boolean;
procedure GoLong;
end;
The "catcher" is in a utility unit. It is NOT an object member.
unit Utils;
{
This is a general purpose utility unit
Among other things it contains the actual callback routine which is
invoked by the longrunner program.
}
{$MODE DELPHI}
interface
uses
LongProcess; // get access to the call back routine signature
...
Function HandleCallback : tProgressCallback; //(const n,m:integer; text:string):boolean;
The main unit has the code to invoke the long running process and to handle the periodic progress messages.
unit Main;
{
This is the main form unit.
The form has, among other gumpf, a progress bar and a label
When the longrunning operation decides to report its progress,
the label and the progress bar are to be updated.
}
{$MODE DELPHI}
interface
uses Utils, LongRunning;
type
{ TForm1 }
TForm1 = class(TForm)
DetailProgress: TProgressBar;
CurrentOperation: TLabel;
public
procedure StartErUp; //invokes long running process
Function HandleProgess(const n,m:integer; const text:string):boolean;
end;
implementation
Function tForm1.StartErUp;
var
MyLongRunner : tLongRunner;
begin
// create longrunner and install callback
myLongRunner := tLongRunner.Create(HandleCallback);
myLOngRunner.GoLOng;
end;
Function tForm1.HandleProgess(const n,m:integer; const text:string):boolean;
// although the signature here is the same as tProgressCallback
// but this call is isolated from the callback mechanism (supposedly)
begin
Form1.CurrentOperation.Caption := text;
Form1.DetailProgress.max := m;
Form1.DetailProgress.Position := n;
Application.ProcessMessages;
result := true;
end;
So,
1) the Main unit creates the longrunning object routine, specifies the callback routine (that is in the utils unit) and starts the longrunning process.
2) Periodically the longrunning process checks for a defined callback and if found invokes it.
{unit longprocess implementation}
tLongrunner.progressstep(n, m: integer; aText: string): boolean;
begin
if assigned(_progresscallback)
then result := progressCallback(n, m, aText);
end;
tLongrunner.GoLong;
BEGIN
while moretodo do begin
ProgressStep(currentstep, maxsteps, '...working...');
DoSomeProcessStep;
end;
ProgressStep(maxSteps, maxSteps, '...All Done...');
END;
The callback is in the Utils unit. It catches the callback and forwards it to the invoking form's routine
{unit utils implementation}
FUNCTION HandleCallback; //(const n, m: integer; const text: string): boolean;
// notice no signature specified... therefore use signature from interface definition
BEGIN
// call the progress bar updating routine in the mainform
Form1.HandleProgress(n,m,text);
end;
The COMPILER ERROR occurs on the "Form1.HandleProgress(n,m,text);" (line 6 here).
"Error: identifier idents no member "HandleProgress"
I used to do this kind of thing in Delphi fairly regularly, but I can't figure out what FPC's problem is here.
I see something in the various documentation about using an '@' sign to indicate reference, but not in Delphi mode. I see something about a new syntax using the word 'reference' and/or '&reference' but I don't grok what that is telling me different.
So the fundamental issue is "Why can't the function in the UTILS unit 'see' the Form's method? Any advice accepted.
Thanks in advance.
Keith