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.
  • 相关阅读:
    window.open的火狐、谷歌兼容写法
    一个分数怎样约分?想知道的速度了。。。
    这是第二道题内容要求写一个银行的ATM系统 这个浪费了好长时间 ,遇到了许多问题,不过都解决了,上程序
    两个有理数相加(要求输入时以分数形式,输出时也以分数形式)
    linux centos 7.5下 源码编译安装 lua环境
    SecureCRT 6.7 vim高亮
    C#第一章笔记
    HTML5考试错题
    第九章博客
    第八章博客
  • 原文地址:https://www.cnblogs.com/hezihang/p/3965179.html
Copyright © 2011-2022 走看看