1
\$\begingroup\$

I am trying to learn callbacks in Delphi (7). Could not find a complete simple tutorial, so I puzzled together a few bits here and there. This is my first attempt, of course trivial.

My form contains a button and a label. For the test, I make a loop in the onClick code, and every time do a callback function.

picture of simple form with 1 button and a label

The code is below. It works, but I am in doubt if it's "correct" to have application.processmessages where I have it. And, if I define / apply the callback functionality correctly.

// ----------- demo to test Callbacks
// https://stackoverflow.com/questions/11314641/method-pointer-and-regular-procedure-incompatible
//
unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;
type
 TCallBackFunction = procedure(sig: integer) of object;
 TForm1 = class(TForm)
 lblProgress: TLabel;
 btn1: TButton;
 procedure btn1Click(Sender: TObject);
 private
 { Private declarations }
 procedure tcb (sig: integer);
 public
 { Public declarations }
 procedure dowithcallback(const something: integer; thefunction: TCallBackFunction);
 end;
var
 Form1: TForm1;
 testvar : integer;
implementation
{$R *.dfm}
// test procedure used for callback argument
//
procedure TForm1.tcb(sig: integer);
begin
 testvar := sig;
 lblProgress.Caption := inttostr(testvar);
 application.ProcessMessages ;
end;
// The procedure that defines the callback function
//
procedure TForm1.dowithcallback(
 const something: integer;
 thefunction: TCallBackFunction);
begin
 if assigned(thefunction) then
 begin
 thefunction(something)
 end;
end;
//
// button click
//
procedure TForm1.btn1Click(Sender: TObject);
var
 i : integer;
begin
 testvar := 0;
 for i := 1 to 10 do
 begin
 dowithcallback(i, tcb);
 sleep(500);
 end;
end;
end.

Any feedback welcomed!

asked Sep 25, 2022 at 16:59
\$\endgroup\$
1
  • 2
    \$\begingroup\$ The current question title, which states your concerns about the code, applies to too many questions on this site to be useful. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly. \$\endgroup\$ Commented Sep 27, 2022 at 20:42

1 Answer 1

2
\$\begingroup\$

This question belongs to StackOverflow but not StackExchange. The title is also misleading, as you're asking about the call to application.ProcessMessages but not the callback function. Regarding your question, my opinion is that you should avoid putting UI code in the function and put them together with Sleep.

The other concern is the use of testvar. This global variable seems completely unnecessary in your code. It also makes the code thread-unsafe. Why did you use it? If you really need it, declare it as a member of TForm1 and not a global variable. It's still not thread-safe but better. Using global variables is against the principle of OOP and very bug-prone.

One last thing, as a benefit of separating codes from UI handling, both tcb and dowithcallback can now be declared as regular functions and not class functions. They run faster.

type
 TCallBackFunction = function(sig: integer): string;
function tcb(sig: integer): string;
begin
 Result := inttostr(sig);
end;
function dowithcallback(
 const something: integer;
 thefunction: TCallBackFunction): string;
begin
 if assigned(thefunction)
 then Result := thefunction(something)
 // else Result := ''; 
 // the else part is not needed because Result is defaulted to ''
end;
procedure TForm1.btn1Click(Sender: TObject);
var
 i : integer;
begin
 for i := 1 to 10 do
 begin
 lblProgress.Caption := dowithcallback(i, tcb);
 application.ProcessMessages ;
 sleep(500);
 end;
end;
answered Dec 4, 2022 at 3:27
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.