胡羽杨 發表於 2008-3-15 18:14:50

插件管理框架 for Delphi(二)

unit untDllManager;
<br><br>interface
<br><br>uses
<br>&nbsp;&nbsp;Windows,&nbsp;Classes,&nbsp;SysUtils,&nbsp;Forms;
<br><br>type
<br><br>&nbsp;&nbsp;EDllError&nbsp;=&nbsp;Class(Exception);
<br><br>&nbsp;&nbsp;TDllClass&nbsp;=&nbsp;Class&nbsp;of&nbsp;TDll;
<br>&nbsp;&nbsp;TDll&nbsp;=&nbsp;Class;
<br><br>&nbsp;&nbsp;TDllEvent&nbsp;=&nbsp;procedure(Sender:&nbsp;TObject;&nbsp;ADll:&nbsp;TDll)&nbsp;of&nbsp;Object;
<br><br>&nbsp;&nbsp;{&nbsp;TDllManager
<br>&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;提供对&nbsp;Dll&nbsp;的管理功能;&nbsp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;Add&nbsp;时自动创建&nbsp;TDll&nbsp;对象,但不尝试装载;
<br>&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;Delete&nbsp;时自动销毁&nbsp;TDll&nbsp;对象;
<br>&nbsp;&nbsp;}
<br><br>&nbsp;&nbsp;TDllManager&nbsp;=&nbsp;Class(TList)
<br>&nbsp;&nbsp;private
<br>&nbsp;&nbsp;&nbsp;&nbsp;FLock:&nbsp;TRTLCriticalSection;
<br>&nbsp;&nbsp;&nbsp;&nbsp;FDllClass:&nbsp;TDllClass;
<br>&nbsp;&nbsp;&nbsp;&nbsp;FOnDllLoad:&nbsp;TDllEvent;
<br>&nbsp;&nbsp;&nbsp;&nbsp;FOnDllBeforeUnLoaded:&nbsp;TDllEvent;
<br>&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;GetDlls(const&nbsp;Index:&nbsp;Integer):&nbsp;TDll;
<br>&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;GetDllsByName(const&nbsp;FileName:&nbsp;String):&nbsp;TDll;
<br>&nbsp;&nbsp;protected
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;Notify(Ptr:&nbsp;Pointer;&nbsp;Action:&nbsp;TListNotification);&nbsp;override;
<br>&nbsp;&nbsp;public
<br>&nbsp;&nbsp;&nbsp;&nbsp;constructor&nbsp;Create;
<br>&nbsp;&nbsp;&nbsp;&nbsp;destructor&nbsp;Destroy;&nbsp;override;
<br>&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;Add(const&nbsp;FileName:&nbsp;String):&nbsp;Integer;&nbsp;overload;
<br>&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;IndexOf(const&nbsp;FileName:&nbsp;String):&nbsp;Integer;&nbsp;overload;
<br>&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;Remove(const&nbsp;FileName:&nbsp;String):&nbsp;Integer;&nbsp;overload;
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;Lock;
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;UnLock;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;DllClass:&nbsp;TDllClass&nbsp;read&nbsp;FDllClass&nbsp;write&nbsp;FDllClass;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;Dlls:&nbsp;TDll&nbsp;read&nbsp;GetDlls;&nbsp;default;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;DllsByName:&nbsp;TDll&nbsp;read&nbsp;GetDllsByName;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;OnDllLoaded:&nbsp;TDllEvent&nbsp;read&nbsp;FOnDllLoad&nbsp;write&nbsp;FOnDllLoad;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;OnDllBeforeUnLoaded:&nbsp;TDllEvent&nbsp;read&nbsp;FOnDllBeforeUnLoaded&nbsp;write&nbsp;FOnDllBeforeUnLoaded;
<br>&nbsp;&nbsp;end;
<br><br>&nbsp;&nbsp;{&nbsp;TDll
<br>&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;代表一个&nbsp;Dll,&nbsp;Windows.HModule
<br>&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;销毁时自动在&nbsp;Owner&nbsp;中删除自身;
<br>&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;子类可通过覆盖override&nbsp;DoDllLoaded,&nbsp;以及DoDllUnLoaded进行功能扩展;
<br>&nbsp;&nbsp;}
<br><br>&nbsp;&nbsp;TDll&nbsp;=&nbsp;Class(TObject)
<br>&nbsp;&nbsp;private
<br>&nbsp;&nbsp;&nbsp;&nbsp;FOwner:&nbsp;TDllManager;
<br>&nbsp;&nbsp;&nbsp;&nbsp;FModule:&nbsp;HMODULE;
<br>&nbsp;&nbsp;&nbsp;&nbsp;FFileName:&nbsp;String;
<br>&nbsp;&nbsp;&nbsp;&nbsp;FPermit:&nbsp;Boolean;
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;SetFileName(const&nbsp;Value:&nbsp;String);
<br>&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;GetLoaded:&nbsp;Boolean;
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;SetLoaded(const&nbsp;Value:&nbsp;Boolean);
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;SetPermit(const&nbsp;Value:&nbsp;Boolean);
<br>&nbsp;&nbsp;protected
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;DoDllLoaded;&nbsp;virtual;
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;DoBeforeDllUnLoaded;&nbsp;virtual;
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;DoDllUnLoaded;&nbsp;virtual;
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;DoFileNameChange;&nbsp;virtual;
<br>&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;DoPermitChange;&nbsp;virtual;
<br>&nbsp;&nbsp;public
<br>&nbsp;&nbsp;&nbsp;&nbsp;constructor&nbsp;Create;&nbsp;virtual;
<br>&nbsp;&nbsp;&nbsp;&nbsp;destructor&nbsp;Destroy;&nbsp;override;
<br>&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;GetProcAddress(const&nbsp;Order:&nbsp;Longint):&nbsp;FARPROC;&nbsp;overload;
<br>&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;GetProcAddress(const&nbsp;ProcName:&nbsp;String):&nbsp;FARPROC;&nbsp;overload;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;FileName:&nbsp;String&nbsp;read&nbsp;FFileName&nbsp;write&nbsp;SetFileName;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;Loaded:&nbsp;Boolean&nbsp;read&nbsp;GetLoaded&nbsp;write&nbsp;SetLoaded;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;Owner:&nbsp;TDllManager&nbsp;read&nbsp;FOwner;
<br>&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;Permit:&nbsp;Boolean&nbsp;read&nbsp;FPermit&nbsp;write&nbsp;SetPermit;
<br>&nbsp;&nbsp;end;
<br><br>implementation
<br><br>{&nbsp;TDll&nbsp;}
<br><br>constructor&nbsp;TDll.Create;
<br>begin
<br>&nbsp;&nbsp;FOwner&nbsp;:=&nbsp;nil;
<br>&nbsp;&nbsp;FFileName&nbsp;:=&nbsp;&acute;&acute;;
<br>&nbsp;&nbsp;FModule&nbsp;:=&nbsp;0;
<br>&nbsp;&nbsp;FPermit&nbsp;:=&nbsp;True;
<br>end;
<br><br>destructor&nbsp;TDll.Destroy;
<br>var
<br>&nbsp;&nbsp;Manager:&nbsp;TDllManager;
<br>begin
<br>&nbsp;&nbsp;Loaded&nbsp;:=&nbsp;False;
<br>&nbsp;&nbsp;if&nbsp;FOwner&nbsp;&lt;&gt;&nbsp;nil&nbsp;then
<br>&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;//在拥有者中删除自身
<br>&nbsp;&nbsp;&nbsp;&nbsp;Manager&nbsp;:=&nbsp;FOwner;
<br>&nbsp;&nbsp;&nbsp;&nbsp;//未防止在&nbsp;TDllManager中重复删除,因此需要将
<br>&nbsp;&nbsp;&nbsp;&nbsp;//FOwner设置为&nbsp;nil;&nbsp;&lt;--&nbsp;此段代码和&nbsp;TDllManager.Notify&nbsp;需要配合
<br>&nbsp;&nbsp;&nbsp;&nbsp;//才能确保正确。&nbsp;
<br>&nbsp;&nbsp;&nbsp;&nbsp;FOwner&nbsp;:=&nbsp;nil;
<br>&nbsp;&nbsp;&nbsp;&nbsp;Manager.Remove(Self);
<br>&nbsp;&nbsp;end;
<br>&nbsp;&nbsp;inherited;
<br>end;
<br><br>function&nbsp;TDll.GetLoaded:&nbsp;Boolean;
<br>begin
<br>&nbsp;&nbsp;result&nbsp;:=&nbsp;FModule&nbsp;&lt;&gt;&nbsp;0;
<br>end;
<br><br>function&nbsp;TDll.GetProcAddress(const&nbsp;Order:&nbsp;Longint):&nbsp;FARPROC;
<br>begin
<br>&nbsp;&nbsp;if&nbsp;Loaded&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;Windows.GetProcAddress(FModule,&nbsp;Pointer(Order))
<br>&nbsp;&nbsp;else
<br>&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;EDllError.CreateFmt(&acute;Do&nbsp;Load&nbsp;before&nbsp;GetProcAddress&nbsp;of&nbsp;&quot;%u&quot;&acute;,&nbsp;);
<br>end;
<br><br>function&nbsp;TDll.GetProcAddress(const&nbsp;ProcName:&nbsp;String):&nbsp;FARPROC;
<br>begin
<br>&nbsp;&nbsp;if&nbsp;Loaded&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;Windows.GetProcAddress(FModule,&nbsp;PChar(ProcName))
<br>&nbsp;&nbsp;else
<br>&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;EDllError.CreateFmt(&acute;Do&nbsp;Load&nbsp;before&nbsp;GetProcAddress&nbsp;of&nbsp;&quot;%s&quot;&acute;,&nbsp;);
<br>end;
<br><br>procedure&nbsp;TDll.SetLoaded(const&nbsp;Value:&nbsp;Boolean);
<br>begin
<br>&nbsp;&nbsp;if&nbsp;Loaded&nbsp;&lt;&gt;&nbsp;Value&nbsp;then
<br>&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;not&nbsp;Value&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert(FModule&nbsp;&lt;&gt;&nbsp;0);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoBeforeDllUnLoaded;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeLibrary(FModule);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FModule&nbsp;:=&nbsp;0;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Application.HandleException(Self);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoDllUnLoaded;
<br>&nbsp;&nbsp;&nbsp;&nbsp;end
<br>&nbsp;&nbsp;&nbsp;&nbsp;else
<br>&nbsp;&nbsp;&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FModule&nbsp;:=&nbsp;LoadLibrary(PChar(FFileName));
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Win32Check(FModule&nbsp;&lt;&gt;&nbsp;0);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoDllLoaded;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;On&nbsp;E:&nbsp;Exception&nbsp;do
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;FModule&nbsp;&lt;&gt;&nbsp;0&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeLibrary(FModule);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FModule&nbsp;:=&nbsp;0;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;EDllError.CreateFmt(&acute;LoadLibrary&nbsp;Error:&nbsp;%s&acute;,&nbsp;);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
<br>&nbsp;&nbsp;&nbsp;&nbsp;end;
<br>&nbsp;&nbsp;end;
<br>end;
<br><br>procedure&nbsp;TDll.SetFileName(const&nbsp;Value:&nbsp;String);
<br>begin
<br>&nbsp;&nbsp;if&nbsp;Loaded&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;EDllError.CreateFmt(&acute;Do&nbsp;Unload&nbsp;before&nbsp;load&nbsp;another&nbsp;Module&nbsp;named:&nbsp;&quot;%s&quot;&acute;,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);
<br>&nbsp;&nbsp;if&nbsp;FFileName&nbsp;&lt;&gt;&nbsp;Value&nbsp;then
<br>&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;FFileName&nbsp;:=&nbsp;Value;
<br>&nbsp;&nbsp;&nbsp;&nbsp;DoFileNameChange;
<br>&nbsp;&nbsp;end;
<br>end;
<br><br>procedure&nbsp;TDll.DoFileNameChange;
<br>begin
<br>&nbsp;&nbsp;//&nbsp;do&nbsp;nonthing.
<br>end;
<br><br>procedure&nbsp;TDll.DoDllLoaded;
<br>begin
<br>&nbsp;&nbsp;if&nbsp;Assigned(FOwner)&nbsp;and&nbsp;Assigned(FOwner.OnDllLoaded)&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;FOwner.OnDllLoaded(FOwner,&nbsp;Self);
<br>end;
<br><br>procedure&nbsp;TDll.DoDllUnLoaded;
<br>begin
<br>&nbsp;&nbsp;//do&nbsp;nonthing.
<br>end;
<br><br>procedure&nbsp;TDll.DoPermitChange;
<br>begin
<br>&nbsp;&nbsp;//do&nbsp;nonthing.
<br>end;
<br><br>procedure&nbsp;TDll.SetPermit(const&nbsp;Value:&nbsp;Boolean);
<br>begin
<br>&nbsp;&nbsp;if&nbsp;FPermit&nbsp;&lt;&gt;&nbsp;Value&nbsp;then
<br>&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;FPermit&nbsp;:=&nbsp;Value;
<br>&nbsp;&nbsp;&nbsp;&nbsp;DoPermitChange;
<br>&nbsp;&nbsp;end;
<br>end;
<br><br>procedure&nbsp;TDll.DoBeforeDllUnLoaded;
<br>begin
<br>&nbsp;&nbsp;if&nbsp;Assigned(FOwner)&nbsp;and&nbsp;Assigned(FOwner.OnDllBeforeUnLoaded)&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;FOwner.OnDllBeforeUnLoaded(FOwner,&nbsp;Self);
<br>end;
<br><br>{&nbsp;TDllManager&nbsp;}
<br><br>function&nbsp;TDllManager.Add(const&nbsp;FileName:&nbsp;String):&nbsp;Integer;
<br>var
<br>&nbsp;&nbsp;Dll:&nbsp;TDll;
<br>begin
<br>&nbsp;&nbsp;result&nbsp;:=&nbsp;-1;
<br>&nbsp;&nbsp;Lock;
<br>&nbsp;&nbsp;try
<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;DllsByName&nbsp;=&nbsp;nil&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dll&nbsp;:=&nbsp;FDllClass.Create;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dll.FileName&nbsp;:=&nbsp;FileName;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;Add(Dll);
<br>&nbsp;&nbsp;&nbsp;&nbsp;end
<br>&nbsp;&nbsp;&nbsp;&nbsp;else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;-1;
<br>&nbsp;&nbsp;finally
<br>&nbsp;&nbsp;&nbsp;&nbsp;UnLock;
<br>&nbsp;&nbsp;end;
<br>end;
<br><br>constructor&nbsp;TDllManager.Create;
<br>begin
<br>&nbsp;&nbsp;FDllClass&nbsp;:=&nbsp;TDll;
<br>&nbsp;&nbsp;InitializeCriticalSection(FLock);
<br>end;
<br><br>destructor&nbsp;TDllManager.Destroy;
<br>begin
<br>&nbsp;&nbsp;DeleteCriticalSection(FLock);
<br>&nbsp;&nbsp;inherited;
<br>end;
<br><br>function&nbsp;TDllManager.GetDlls(const&nbsp;Index:&nbsp;Integer):&nbsp;TDll;
<br>begin
<br>&nbsp;&nbsp;Lock;
<br>&nbsp;&nbsp;try
<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(Index&nbsp;&gt;=0)&nbsp;and&nbsp;(Index&nbsp;&lt;=&nbsp;Count&nbsp;-&nbsp;1)&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;Items
<br>&nbsp;&nbsp;&nbsp;&nbsp;else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;EDllError.CreateFmt(&acute;Error&nbsp;Index&nbsp;of&nbsp;GetDlls,&nbsp;Value:&nbsp;%d,&nbsp;Total&nbsp;Count:&nbsp;%d&acute;,&nbsp;);
<br>&nbsp;&nbsp;finally
<br>&nbsp;&nbsp;&nbsp;&nbsp;UnLock;
<br>&nbsp;&nbsp;end;
<br>end;
<br><br>function&nbsp;TDllManager.GetDllsByName(const&nbsp;FileName:&nbsp;String):&nbsp;TDll;
<br>var
<br>&nbsp;&nbsp;I:&nbsp;Integer;
<br>begin
<br>&nbsp;&nbsp;Lock;
<br>&nbsp;&nbsp;try
<br>&nbsp;&nbsp;&nbsp;&nbsp;I&nbsp;:=&nbsp;IndexOf(FileName);
<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;I&nbsp;&gt;=&nbsp;0&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;Dlls
<br>&nbsp;&nbsp;&nbsp;&nbsp;else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;nil;
<br>&nbsp;&nbsp;finally
<br>&nbsp;&nbsp;&nbsp;&nbsp;UnLock;
<br>&nbsp;&nbsp;end;
<br>end;
<br><br>function&nbsp;TDllManager.IndexOf(const&nbsp;FileName:&nbsp;String):&nbsp;Integer;
<br>var
<br>&nbsp;&nbsp;I:&nbsp;Integer;
<br>begin
<br>&nbsp;&nbsp;result&nbsp;:=&nbsp;-1;
<br>&nbsp;&nbsp;Lock;
<br>&nbsp;&nbsp;try
<br>&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;I&nbsp;:=&nbsp;0&nbsp;to&nbsp;Count&nbsp;-&nbsp;1&nbsp;do
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;CompareText(FileName,&nbsp;Dlls.FileName)&nbsp;=&nbsp;0&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;I;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;
<br>&nbsp;&nbsp;finally
<br>&nbsp;&nbsp;&nbsp;&nbsp;UnLock;
<br>&nbsp;&nbsp;end;
<br>end;
<br><br>procedure&nbsp;TDllManager.Lock;
<br>begin
<br>&nbsp;&nbsp;OutputDebugString(Pchar(&acute;TRLock&nbsp;DM&acute;&nbsp;+&nbsp;IntToStr(GetCurrentThreadId)&nbsp;+&nbsp;&acute;:&acute;&nbsp;+&nbsp;IntToStr(DWORD(Self))));
<br>&nbsp;&nbsp;EnterCriticalSection(FLock);
<br>&nbsp;&nbsp;OutputDebugString(Pchar(&acute;Locked&nbsp;DM&acute;&nbsp;+&nbsp;IntToStr(GetCurrentThreadId)&nbsp;+&nbsp;&acute;:&acute;&nbsp;+&nbsp;IntToStr(DWORD(Self))));
<br>end;
<br><br>procedure&nbsp;TDllManager.Notify(Ptr:&nbsp;Pointer;&nbsp;Action:&nbsp;TListNotification);
<br>begin
<br>&nbsp;&nbsp;if&nbsp;Action&nbsp;=&nbsp;lnDeleted&nbsp;then
<br>&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;//若TDll(Ptr).Owner和Self不同,则
<br>&nbsp;&nbsp;&nbsp;&nbsp;//表明由&nbsp;TDll.Destroy&nbsp;触发;
<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;TDll(Ptr).Owner&nbsp;=&nbsp;Self&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;begin
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//防止FOwner设置为nil之后相关事件不能触发
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TDll(Ptr).DoBeforeDllUnLoaded;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TDll(Ptr).FOwner&nbsp;:=&nbsp;nil;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TDll(Ptr).Free;
<br>&nbsp;&nbsp;&nbsp;&nbsp;end;
<br>&nbsp;&nbsp;end
<br>&nbsp;&nbsp;else
<br>&nbsp;&nbsp;if&nbsp;Action&nbsp;=&nbsp;lnAdded&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;TDll(Ptr).FOwner&nbsp;:=&nbsp;Self;
<br>&nbsp;&nbsp;inherited;
<br>end;
<br><br>function&nbsp;TDllManager.Remove(const&nbsp;FileName:&nbsp;String):&nbsp;Integer;
<br>var
<br>&nbsp;&nbsp;I:&nbsp;Integer;
<br>begin
<br>&nbsp;&nbsp;result&nbsp;:=&nbsp;-1;
<br>&nbsp;&nbsp;Lock;
<br>&nbsp;&nbsp;try
<br>&nbsp;&nbsp;&nbsp;&nbsp;I&nbsp;:=&nbsp;IndexOf(FileName);
<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;I&nbsp;&gt;=&nbsp;0&nbsp;then
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;Remove(Dlls)
<br>&nbsp;&nbsp;&nbsp;&nbsp;else
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;:=&nbsp;-1;
<br>&nbsp;&nbsp;finally
<br>&nbsp;&nbsp;&nbsp;&nbsp;UnLock;
<br>&nbsp;&nbsp;end;
<br>end;
<br><br>procedure&nbsp;TDllManager.UnLock;
<br>begin
<br>&nbsp;&nbsp;LeaveCriticalSection(FLock);
<br>&nbsp;&nbsp;OutputDebugString(Pchar(&acute;UnLock&nbsp;DM&acute;&nbsp;+&nbsp;IntToStr(GetCurrentThreadId)&nbsp;+&nbsp;&acute;:&acute;&nbsp;+&nbsp;IntToStr(DWORD(Self))));
<br>end;
<br><br>end.
                           
                            <div class="art_xg">
                              
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: 插件管理框架 for Delphi(二)