zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    HDU 1106 排序
    strtok函数()
    HDU 2187汶川地震
    HDU 1716 排列2
    Rightmost Digit
    Text Reverse
    快速幂
    插入排序的一个应用-调整负数在前,正数在后,原来相对位置不变
    cuda 5.0配置vs2008+Visual Assist X +安装问题解决
    vc 热键、组合键的用法
  • 原文地址:https://www.cnblogs.com/hezihang/p/3965179.html
Copyright © 2011-2022 走看看