⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mthreaddcom.pas

📁 详细说明:毕业论文中关于小型宾馆管理系统的详细设计毕 业论文中关于小型宾馆...一个酒店管理系统VB+Access [学生学籍管理系统(VB+Acess).zip] - !这个是刚刚编的毕业设计,可能
💻 PAS
字号:
{*******************************************************}
{                                                       }
{          Threaded Class Factory Demo                  }
{                                                       }
{*******************************************************}

unit MThreadDCOM;

{
  This unit provides some custom class factories that implement threading for
  out of process servers.  The TThreadedAutoObjectFactory is for any TAutoObject
  and the TThreadedClassFactory is for and TComponentFactory.  To use them,
  replace the line in the initialization section of your automation object to
  use the appropriate threaded class factory instead of the non-threaded version.
}

interface

uses ComObj, ActiveX, Classes, Windows, VCLCom, Forms;

type

  TCreateInstanceProc = function(const UnkOuter: IUnknown;
    const IID: TGUID; out Obj): HResult of object; stdcall;

{ TThreadedAutoObjectFactory }

  TThreadedAutoObjectFactory = class(TAutoObjectFactory, IClassFactory)
  protected
    function CreateInstance(const UnkOuter: IUnknown; const IID: TGUID;
      out Obj): HResult; stdcall;
    function DoCreateInstance(const UnkOuter: IUnknown; const IID: TGUID;
      out Obj): HResult; stdcall;
  end;

{ TThreadedClassFactory }

  TThreadedClassFactory = class(TComponentFactory, IClassFactory)
  protected
    function CreateInstance(const UnkOuter: IUnknown; const IID: TGUID;
      out Obj): HResult; stdcall;
    function DoCreateInstance(const UnkOuter: IUnknown; const IID: TGUID;
      out Obj): HResult; stdcall;
  end;

{ TApartmentThread }

  TApartmentThread = class(TThread)
  private
    FCreateInstanceProc: TCreateInstanceProc;
    FUnkOuter: IUnknown;
    FIID: TGuid;
    FSemaphore: THandle;
    FStream: Pointer;
    FCreateResult: HResult;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateInstanceProc: TCreateInstanceProc; UnkOuter: IUnknown; IID: TGuid);
    destructor Destroy; override;
    property Semaphore: THandle read FSemaphore;
    property CreateResult: HResult read FCreateResult;
    property ObjStream: Pointer read FStream;
  end;

implementation

{ TThreadedAutoObjectFactory }

function TThreadedAutoObjectFactory.DoCreateInstance(const UnkOuter: IUnknown;
  const IID: TGUID; out Obj): HResult; stdcall;
begin
  Result := inherited CreateInstance(UnkOuter, IID, Obj);
end;

// NOTE: Additions suggested by Binh Ly
// http://www.castle.net/~bly/Programming/Delphi/Threading2/index.html)
function TThreadedAutoObjectFactory.CreateInstance(const UnkOuter: IUnknown;
  const IID: TGUID; out Obj): HResult; stdcall;
begin
  LockServer(TRUE);
  try
    with TApartmentThread.Create(DoCreateInstance, UnkOuter, IID) do
    begin
      if WaitForSingleObject(Semaphore, INFINITE) = WAIT_OBJECT_0 then
      begin
        Result := CreateResult;
        if Result <> S_OK then Exit;
        Result := CoGetInterfaceAndReleaseStream(IStream(ObjStream), IID, Obj);
      end else
        Result := E_FAIL
    end;
  finally
    LockServer(FALSE);
  end;
end;

{ TThreadedClassFactory }

function TThreadedClassFactory.DoCreateInstance(const UnkOuter: IUnknown;
  const IID: TGUID; out Obj): HResult; stdcall;
begin
  Result := inherited CreateInstance(UnkOuter, IID, Obj);
end;

// NOTE: Additions suggested by Binh Ly
// http://www.castle.net/~bly/Programming/Delphi/Threading2/index.html)
function TThreadedClassFactory.CreateInstance(const UnkOuter: IUnknown;
  const IID: TGUID; out Obj): HResult; stdcall;
begin
  LockServer(TRUE);
  try
    with TApartmentThread.Create(DoCreateInstance, UnkOuter, IID) do
    begin
      if WaitForSingleObject(Semaphore, INFINITE) = WAIT_OBJECT_0 then
      begin
        Result := CreateResult;
        if Result <> S_OK then Exit;
        Result := CoGetInterfaceAndReleaseStream(IStream(ObjStream), IID, Obj);
      end else
        Result := E_FAIL
    end;
  finally
    LockServer(FALSE);
  end;
end;

{ TApartmentThread }

constructor TApartmentThread.Create(CreateInstanceProc: TCreateInstanceProc;
  UnkOuter: IUnknown; IID: TGuid);
begin
  FCreateInstanceProc := CreateInstanceProc;
  FUnkOuter := UnkOuter;
  FIID := IID;
  FSemaphore := CreateSemaphore(nil, 0, 1, nil);
  FreeOnTerminate := True;
  inherited Create(False);
end;

destructor TApartmentThread.Destroy;
begin
  FUnkOuter := nil;
  CloseHandle(FSemaphore);
  inherited Destroy;
  Application.ProcessMessages;
end;

procedure TApartmentThread.Execute;
var
  msg: TMsg;
  Unk: IUnknown;
begin
  CoInitialize(nil);
  FCreateResult := FCreateInstanceProc(FUnkOuter, FIID, Unk);
  if FCreateResult = S_OK then
    CoMarshalInterThreadInterfaceInStream(FIID, Unk, IStream(FStream));
  ReleaseSemaphore(FSemaphore, 1, nil);
  if FCreateResult = S_OK then
    while GetMessage(msg, 0, 0, 0) do
    begin
      DispatchMessage(msg);
      Unk._AddRef;
      if Unk._Release = 1 then break;
    end;
  Unk := nil;
  CoUninitialize;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -