很基本的dll中含有form的问题(30分)

  • 主题发起人 主题发起人 陈桂坚
  • 开始时间 开始时间

陈桂坚

Unregistered / Unconfirmed
GUEST, unregistred user!
我用MDI主窗口调用在动态库中的MDI子窗口,我该在那里释放我的DLL资源:
type
TPUBLICA4DLLload=procedure (App: TApplication; AppSessions: TSession;YYYGH :STRING;in_right :string);
var

FPointer: TFarProc;
myfunct : TPUBLICA4DLLload;
begin
HInst := LoadLibrary (pchar(dllname));
try
try
FPointer:=nil;
if HInst > 0 then
FPointer := GetProcAddress (HInst,PChar (funcname));
if FPointer <> nil then
begin
MyFunct := TPUBLICA4DLLload(FPointer);
MyFunct(application,session,'eeee','ererer');
end;
except
messagebox(handle,'11'´11',MB_OK);
end;
finally
//FreeLibrary(HInst); //我不能这里释放他,我是SHOW的,我该在那里释放!
end;
end;
 
自己关注一下...
[:(][:(]
 
在不需要它的时候释放。
 
DLL中自己计数,当打开的窗体数为0时,发消息给EXE,再让EXE释放
 
其中FDllHandle是窗体的句柄,
ALastForm 是你当前打开的窗体
{ 调用动态链接库中当前窗体的关闭过程 }
{ 2005-09-20 by muhx }
procedure TFrmMain.CloseDLLForm(ALastForm: Integer);
var
tmpProc: procedure; stdcall;
begin
if FDllHandle >= 32 then
begin
try
case ALastForm of
2: tmpProc := GetProcAddress(FDllHandle, 'CloseData');
3: tmpProc := GetProcAddress(FDllHandle, 'CloseConfig');
4: tmpProc := GetProcAddress(FDllHandle, 'CloseUser');
5: tmpProc := GetProcAddress(FDllHandle, 'CloseLog');
6: tmpProc := GetProcAddress(FDllHandle, 'CloseAlarmLog');
7: tmpProc := GetProcAddress(FDllHandle, 'CloseProcTable');
8: tmpProc := GetProcAddress(FDllHandle, 'CloseProcGuide');
else
Exit;
end;
tmpProc;
finally
FreeLibrary(FDllHandle);
FDllHandle := 0;
end;
end;
end;

比如关闭我的DLL中一个叫FrmConfig 的窗体
我的DLL中的关闭代码为
{ 在释放DLL前先释放窗体 }
procedure CloseConfig;
begin
if FrmConfig <> nil then
FrmConfig.Free;
FrmConfig := nil;
end;
 
兄弟,好象不行呀...
 
如何制作dephi7 的 MDI窗体?
 
郁闷呀..
 
郁闷呀..
 
子窗体关闭事件里Free.
 
DLL_PROCESS_DETACH
在这中吗?
 
因为窗体是非模态的.
在dll中定义一个FromClose方法来释放dll资源
然后在主程序中调用这个方法释放dll资源 .
 
做了一下测试:
主窗体(fsMDIForm)单元:
unit CMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus;

const
WM_CALLBACK = WM_USER + 100;

type
//Same as DLL Exports
TShowForm = function (App: TApplication; CallProc: Pointer; FormID: Integer; ParentForm: TForm): longint; stdcall;
TActiveForm = function : LongInt; stdcall;
TCloseForm = function : LongInt; stdcall;

TfrmMain = class(TForm)
MainMenu: TMainMenu;
mmFile: TMenuItem;
mmFileOpen: TMenuItem;
mmFileClose: TMenuItem;
procedure mmFileOpenClick(Sender: TObject);
procedure mmFileCloseClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
FLibHandle : THandle;
FShowForm : TShowForm;
FActiveForm : TActiveForm;
FCloseForm : TCloseForm;
procedure CallPostMessage(ID:Integer);
procedure BackCallMessage(var Msg: TMessage); message WM_CALLBACK;
public
{ Public declarations }
end;

var
frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure CallBackProc(ID:Integer); stdcall;
begin
frmMain.CallPostMessage(ID);
end;

procedure TfrmMain.CallPostMessage(ID: Integer);
begin
PostMessage(self.Handle, WM_CALLBACK, ID, 0);
end;

procedure TfrmMain.BackCallMessage(var Msg: TMessage);
begin
if Msg.Msg = WM_CALLBACK then
begin
if Msg.WParam = FLibHandle then
begin
FreeLibrary(FLibHandle);
FLibHandle := 0;
end;
end;
end;

procedure TfrmMain.mmFileOpenClick(Sender: TObject);
var
FarPointer : FarProc;
begin
if FLibHandle = 0 then
begin
try
FLibHandle := LoadLibrary('Project2.dll');
except
FLibHandle := 0;
end;
if FLibHandle <> 0 then
begin
FarPointer := GetProcAddress(FLibHandle, 'ShowForm');
FShowForm := FarPointer;
FarPointer := GetProcAddress(FLibHandle, 'ActiveForm');
FActiveForm := FarPointer;
FarPointer := GetProcAddress(FLibHandle, 'CloseForm');
FCloseForm := FarPointer;
if Assigned(FShowForm) then
FShowForm(Application, @CallBackProc, FLibHandle, self);
end;
end
else
begin
if Assigned(FActiveForm) then
begin
FActiveForm;
end;
end;
end;

procedure TfrmMain.mmFileCloseClick(Sender: TObject);
begin
if FLibHandle <> 0 then
FCloseForm;
end;

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if FLibHandle <> 0 then
FCloseForm;
end;

end.

动态库Library

library Project2;

uses
SysUtils,
Classes,
Forms,
Windows,
Unit2 in 'Unit2.pas' {frmChild};

{$R *.res}

function ShowForm(App: TApplication; CallProc: Pointer; CallID: Integer; ParentForm: TForm): LongInt; stdcall;
begin
Application := App;
@FreeProc := CallProc;
ProcID := CallID;

frmChild := TfrmChild.Create(ParentForm);
Result := Longint(frmChild);
frmChild.Show;
frmChild.BringToFront;
end;

function ActiveForm: LongInt; stdcall;
begin
if Assigned(frmChild) then
begin
frmChild.BringToFront;
frmChild.SetFocus;
end;
Result := 0;
end;

function CloseForm: LongInt;stdcall;
begin
if Assigned(frmChild) then
begin
frmChild.Close;
end;
Result := 0;
end;

exports
ShowForm, ActiveForm, CloseForm;

{Dll Entry Point}
procedure ExitDll(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then // detaching from process
begin
// restore application
Application := DllApp;
end;
end;

begin
// backup application
DllApp := Application;
DllProc := @ExitDll;
end.

动态库中子窗体单元
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TFreeProc = procedure (ProcID: Integer); stdcall;

TfrmChild = class(TForm)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmChild : TfrmChild;

FreeProc : TFreeProc; //if childform is free(close), notify parent process
ProcID : Integer; //handle that is loaded from parent process
DllApp : TApplication; //a copy of dll application

implementation

{$R *.dfm}

procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;

procedure TfrmChild.FormDestroy(Sender: TObject);
begin
if Assigned(@FreeProc) then
FreeProc(ProcID);
end;

end.
 

Similar threads

后退
顶部