要求:
主窗口通过菜单调用各个DLL中的窗体,主窗体启动时初始化数据模块,各个dll必须共享相同的DLL数据模块的ADOconnection1,
我自己写了一个总是报内存错误,就是dll释放方面没搞明白,请高手共享一些例子,谢谢不是数据库dll封装的例子请不要给我发,那些我会用,就是数据库方面的比较麻烦,特别是共用数据模块等方面,跟普通的dll封装窗体的例子大不一样
主窗口通过菜单调用各个DLL中的窗体,主窗体启动时初始化数据模块,各个dll必须共享相同的DLL数据模块的ADOconnection1,
我自己写了一个总是报内存错误,就是dll释放方面没搞明白,请高手共享一些例子,谢谢不是数据库dll封装的例子请不要给我发,那些我会用,就是数据库方面的比较麻烦,特别是共用数据模块等方面,跟普通的dll封装窗体的例子大不一样
TDllPreferenceItemClassFactory.Create
TDllPreferenceItemClassFactory.GetItemClass
TDllPreferenceItemClassFactory.Destroy
这些涉及DLL库的管理(利用TList管理DLL文件的Handle)Unit PreferenceItemFactroy;
/// 包含用来产生配置项目类的类。InterfaceUses
SysUtils, Windows, Classes, BasePreferenceMgr;Type
/// @[link TDllHandleInfo]的指针类型。
PDllHandleInfo = ^TDllHandleInfo;
/// 记录动态链接库(Dynamic-Link Librabry,DLL)文件的信息。
TDllHandleInfo = Record
/// 文件的位置。
Location: String;
/// 句柄值。
Handle: THandle;
End; /// 获取配置项目类的过程调用原型。
/// @param ItemClassName 配置项目类的名称。
/// @param ItemClass 获得的配置项目类的指针。
TGetItemClass = Procedure(ItemClassName: ShortString; Var ItemClass: Pointer);
stdcall; /// 用来产生配置项目类的类的基类。
TBasePreferenceItemClassFactroy = Class(TObject)
Protected
/// 获得配置项目类。
/// @param GetItemClass 用以获得配置项目类的过程引用。
/// @param ItemClassName 配置项目类的名称。
/// @return 获得的配置项目类。
/// @exception EIllegalItemClass 非法的配置项目类。
Function DoGetItemClass(GetItemClass: TGetItemClass; ItemClassName:
ShortString): TManualInterfacedClass;
End; /// 用以获得动态链接库(Dynamic-Link Librabry,DLL)文件内的配置项目目的类。
TDllPreferenceItemClassFactory = Class(TBasePreferenceItemClassFactroy)
Private
/// 储存打开DLL文件的句柄列表。
FHandles: TList;
Public
/// 构造过程@[p]
/// 创建用以储存打开DLL文件句柄的列表,并将此句柄添加到@[link FHandles],若
/// 无重复者。
Constructor Create;
/// 获得DLL文件内的配置项目类。
/// @param Location DLL文件的文件名,例如:C:\Path\FileName.dll。
/// @param ItemClassName 配置项目类的名称
/// @return 获得的配置项目类。
Function GetItemClass(Const Location: String; ItemClassName: ShortString):
TManualInterfacedClass;
/// 释放加载的DLL文件时获得的所有句柄,并销毁@[link FHandles]。
Destructor Destroy; Override;
End;Implementation{ TBasePreferenceItemClassFactroy }Function TBasePreferenceItemClassFactroy.DoGetItemClass(GetItemClass:
TGetItemClass; ItemClassName: ShortString): TManualInterfacedClass;
Var
mPItemClass: Pointer;
Begin
GetItemClass(ItemClassName, mPItemClass);
If Not Supports(TManualInterfacedClass(mPItemClass), IPreferenceItem) Then
Raise EIllegalItemClass.Create(CItemClassUnsupported);
Result := TManualInterfacedClass(mPItemClass);
End;{ TDllPreferenceItemClassFactory }Constructor TDllPreferenceItemClassFactory.Create;
Begin
FHandles := TList.Create;
End;Destructor TDllPreferenceItemClassFactory.Destroy;
Var
mIndex: Integer;
Begin
For mIndex := 0 To FHandles.Count - 1 Do
Begin
FreeLibrary(TDllHandleInfo(FHandles.Items[mIndex]^).Handle);
FreeMem(FHandles.Items[mIndex], SizeOf(TDllHandleInfo));
End;
FHandles.Free;
FHandles := Nil; Inherited Destroy;
End;Function TDllPreferenceItemClassFactory.GetItemClass(Const Location: String;
ItemClassName: ShortString): TManualInterfacedClass;
Var
mGetItemClass: TGetItemClass;
mIndex: Integer;
mPointer: PDllHandleInfo;
mFullLocation: String;
mSize: Integer;
mDummy: PChar;
Begin
Result := Nil; mSize := GetFullPathName(PChar(Location), 0, PChar(mFullLocation), mDummy);
If mSize = 0 Then
RaiseLastOSError;
SetLength(mFullLocation, mSize);
GetFullPathName(PChar(Location), mSize, PChar(mFullLocation), mDummy); mIndex := -1;
Repeat
Inc(mIndex);
Until (mIndex = FHandles.Count) Or
(TDllHandleInfo(FHandles.Items[mIndex]^).Location = mFullLocation); If mIndex = FHandles.Count Then
Begin
mPointer := AllocMem(SizeOf(TDllHandleInfo));
mPointer^.Location := mFullLocation;
mPointer^.Handle := 0;
FHandles.Add(mPointer);
End
Else
mPointer := PDllHandleInfo(FHandles.Items[mIndex]); If mPointer^.Handle = 0 Then
mPointer^.Handle := SafeLoadLibrary(PChar(mPointer^.Location));
@mGetItemClass := GetProcAddress(mPointer^.Handle, 'GetItemClass');
If @mGetItemClass <> Nil Then
Result := DoGetItemClass(mGetItemClass, ItemClassName)
Else
RaiseLastOSError;
End;End.
[email protected]
我给你发。