Synchronize TThreads (Views: 29)
Problem/Question/Abstract: I am using a thread that does some system checks and outputs the results to a TRichEdit, so I need to use a Syncronize(AMethod) to update the interface and the TRichEdit mentioned before. But I cannot do this if AMethod accepts parameters. I would like to pass some parameters to AMethod, but have not been able to do this. Is this possible? Answer: Below is the complete code to do this, using the function: function ExecuteInMainThread(Proc: MainThreadProcType; var Parameter): boolean; It will call Proc in the main Windows thread and wait for the procedure to finish before returning. Proc takes one untyped variable. If you want to pass more than one variable, put the data into a record and pass the record. You don't really have to code anything. Just copy this code to a unit, use the unit in your code, and call the function. There is no TThread method that does this. unit ThreadLib; interface uses Windows, Messages, ExtCtrls, Classes, Forms, SyncObjs; type MainThreadProcType = procedure(var Parameter) of object; function ExecuteInMainThread(Proc: MainThreadProcType; var Parameter): boolean; implementation uses SysUtils; const UM_EXECMAIN = WM_USER + 590; type WindowProcType = function(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; ProcInfoType = record Method: MainThreadProcType; Param: pointer; end; ProcInfoPtrType = ^ProcInfoType; var OrigThreadWndProc: WindowProcType; function ExecuteInMainThread(Proc: MainThreadProcType; var Parameter): boolean; var ProcInfo: ProcInfoType; begin if GetCurrentThreadID = MainThreadID then try Proc(Parameter); Result := true; except Result := false; end else begin ProcInfo.Method := Proc; ProcInfo.Param := @Parameter; Result := SendMessage(Application.Handle, UM_EXECMAIN, 0, longint(@ProcInfo)) = ord(true); {To send a message without waiting for it to return (PostMessage), make sure that the message parameters do not include pointers. Otherwise, the functions will return before the receiving thread has had a chance to process the message and the sender will free the memory before it is used.} end; end; function ParamThreadWndProc(Window: HWND; Message, wParam, lParam: longint): longint; stdcall; begin if Message = UM_EXECMAIN then try with ProcInfoPtrType(pointer(lParam))^ do Method(Param^); Result := ord(true); except Result := ord(false); end else Result := OrigThreadWndProc(Window, Message, wParam, lParam); end; begin OrigThreadWndProc := WindowProcType(SetWindowLong(Application.Handle, GWL_WNDPROC, longint(@ParamThreadWndProc))); end. |