Delphi写的DLL,OCX中多线程一个同步问题

Delphi写的DLL,OCX中如果使用了TThread.Synchronze(Proc),可能导致线程死锁,原因是无法唤醒EXE中主线程,

Synchronze并不会进入EXE主线程消息队列.

下面的程序自动解决此问题,只需要加入DLL,OCX工程文件中,在DLL,OCX中便可以使用TThread.Synchronze(Proc)了,无需再写一行代码。

//解决Delphi编译的DLL,OCX文件中的线程调用 TThread.Synchronize后挂起无法再激活问题

//调用了TThread.Synchronize函数的所有工程请包含此文件

//仅需将此单元包含到工程文件即可



unit Lib.Common.DLLThread;



interface





implementation



uses Classes, Windows, Messages;



type



  { TDLLSystemController }



  TDLLSystemController = class

  private

    FHandle: HWND;

    FPrevWakeMainThread: TNotifyEvent;

    procedure WakeMainThread(Sender: TObject);

    procedure HookSynchronizeWakeup;

    procedure UnhookSynchronizeWakeup;

  protected

    procedure WndProc(var Message: TMessage);

  public

    constructor Create;

    destructor Destroy; override;

  end;



var

  FDLLController:TDLLSystemController;



{ TDLLSystemController }



constructor TDLLSystemController.Create;

begin

  inherited;

  if IsLibrary then

  begin

    FHandle := AllocateHWnd(WndProc);

    HookSynchronizeWakeup;

  end;

end;



destructor TDLLSystemController.Destroy;

begin

  if IsLibrary then

  begin

    DeallocateHWnd(FHandle);

    UnhookSynchronizeWakeup;

  end;

  inherited;

end;



procedure TDLLSystemController.WndProc(var Message: TMessage);

begin

  case Message.Msg of

    WM_NULL: CheckSynchronize;

  else

    Message.Result := DefWindowProc(FHandle, Message.Msg, Message.wParam, Message.lParam);

  end;

end;



procedure TDLLSystemController.WakeMainThread(Sender: TObject);

begin

  PostMessage(FHandle, WM_NULL, 0, 0);

end;



procedure TDLLSystemController.HookSynchronizeWakeup;

begin

  FPrevWakeMainThread := Classes.WakeMainThread;

  Classes.WakeMainThread := WakeMainThread;

end;



procedure TDLLSystemController.UnhookSynchronizeWakeup;

begin

  Classes.WakeMainThread := FPrevWakeMainThread;

end;





initialization

  if IsLibrary then FDLLController := TDLLSystemController.Create

    else FDLLController:=nil;

finalization

  if Assigned(FDLLController) then FDLLController.Free;

end.

 

你可能感兴趣的:(Delphi)