This is a quick reference post to help anyone having problems working with Borland’s / Codegear’s TActiveForm and Synchronizing TThread’s with the VCL’s main thread (as is required for UI type code changes). After experiencing very strange behaviour for months I came across: this link which explains the problem, when it was introduced, and how to overcome it. According to the link above this modified behaviour started with Delphi 6 (so Builder 5 or 6? is my guess).
This surfaced in one of my projects when I noticed period application “hanging” or freeze when threaded operations tried to call TThreads Synchronize or even when calling SendMessage or PostMessage. Interestingly the hang issue is more pronounced when your activeX control is hosted by Internet Explorer 6. IE 7 seems to behave much better. To solve the problem I followed the first part of the article linked to above and hooked into the VCL’s Classes::WakeMainThread callback method. In case the above article dissappears here is the Pascal code (which I easily ported to C++):
const WM_CLSYNCHRONIZE = WM_USER + 1; ... type TActiveFormX = class(TActiveForm, IActiveFormX) procedure WMclSynchronize(var Message: TMessage); message WM_CLSYNCHRONIZE; ... procedure TActiveFormX.ActiveFormCreate(Sender: TObject); begin Classes.WakeMainThread := DoOnWakeMainThread; end; ... procedure TActiveFormX.DoOnWakeMainThread(Sender: TObject); begin PostMessage(Self.Handle, WM_CLSYNCHRONIZE, 0, 0); end; ... procedure TActiveFormX.WMclSynchronize(var Message: TMessage); begin Classes.CheckSynchronize(); end;
Once this was added, no more random madness, thread synchronization returned to normal!