This is not a way to use BeginThread . This function expects a pointer to a function that takes one parameter, but the function you are trying to call requires four. One parameter that you pass BeginThread to send to the thread procedure is the string, but you obviously hope that some kind of magic will turn this string of characters into the values โโthat these variables contain.
This is not how Delphi works, and even for languages โโthat can do something similar, it is usually not recommended to do this.
To pass several parameters to BeginThread , define a record with all the necessary values, and also define a record pointer:
type PCompareFilesParams = ^TCompareFilesParams; TCompareFilesParams = record Edit3Text, Edit4Text: string; Grid: TStringGrid; Op: Integer; end;
Modify CompareFiles to accept a pointer to this entry:
function CompareFiles(Params: PCompareFilesParams): Integer;
To start the stream, you need to select an instance of this record and fill in its fields:
var Params: PCompareFilesParams; begin New(Params); Params.Edit3Text := Edit3.Text; Params.Edit4Text := Edit4.Text; Params.Grid := StringGrid2; Params.Op := op; BeginThread(nil, 0, @CompareFiles, Params, 0, x);
CompareFiles so that the record is freed before the stream completes:
function CompareFiles(Params: PCompareFilesParams): Integer; begin try // <Normal implementation goes here.> finally Dispose(Params); end; end;
You can make it all a lot easier if you just use TThread . You can make your descendant class have as many parameters as you want in its constructor, so you donโt have to bother with dynamic allocation and freeing up a special record.
type TCompareFilesThread = class(TThread) private FEdit3Text, FEdit4Text: string; FGrid: TStringGrid; FOp: Integer; procedure Execute; override; public constructor Create(const Edit3Text, Edit4Text: string; Grid: TStringGrid; Op: Integer); property ReturnValue; end; constructor TCompareFilesThread.Create; begin inherited Create(False); FEdit3Text := Edit3Text; FEdit4Text := Edit4Text; FGrid := Grid; FOp := Op; end; procedure TCompareFilesThread.Execute; begin ReturnValue := CompareFiles(FEdit3Text, FEdit4Text, FGrid, FOp); end;
Instead of calling BeginThread you simply create an instance of the class and run it:
var ThreadRef: TThread; ThreadRef := TCompareFilesThread.Create(Edit3.Text, Edit4.Text, StringGrid2, Op);
There is more to use threads, for example, knowing when the thread finished working, but I think you have enough to get started. The last thing to be wary of is that TStringGrid is a VCL control. You should not do anything with it from this new thread that you create (no matter how you create it). Everything you do with grid control should be done from the main thread. Use TThread.Synchronize and TThread.Queue to change any VCL operations to the main thread. Your file compare thread will wait for the synchronized operation to complete, but it will continue to work without waiting for the queue to complete.