我的测试代码 在主窗体中procedure TUnit_main.Button1Click(Sender: TObject); type mypointer=Procedure(ahand:THandle;panel1:TPanel);stdcall; var Handle:THandle; frm_p:mypointer; begin Handle:=loadlibrary('Project2.dll'); if Handle>32 then begin @frm_p:=GetProcAddress(Handle,'ShowTest'); if @frm_p<>nil then frm_p(Panel1.Handle,Panel1); end; Freelibrary(Handle); end; dll工程中 procedure ShowTest(ahand:THandle;panel1:TPanel);stdcall; //dll函数 用于显示窗体 var f:TForm2; begin f:=TForm2.Create(nil); try f.ParentWindow:=ahand; f.ShowModal; //使用ShowModal 能在主窗体显示 但是处于有膜状态,不能操作。。 f.Show;//使用show报内存错误 except f.Free; end; end;
在FormDestroy 中free的 提示内存错误呢, 不需要挨个free 调用的dll窗体吗? procedure TUnit_main.FormDestroy(Sender: TObject); var i:Integer; begin for I := 0 to dllHList.Count - 1 do begin FreeLibrary(strtoint(dllHList[i])); end; end; 最后报错
在FormDestroy 中free的 提示内存错误呢, 不需要挨个free 调用的dll窗体吗? procedure TUnit_main.FormDestroy(Sender: TObject); var i:Integer; begin for I := 0 to dllHList.Count - 1 do begin FreeLibrary(strtoint(dllHList[i])); end; end; 最后报错不能在dll自己的窗体内FreeLibrary 要在主窗体中FreeLibrary
var NewForm; Panel:TPanel);
var
frNewForm : TForm ;
begin
try
if NewFormClass = nil then Exit ;
Panel.Visible := False ;
Panel.Align := alClient ; IsPanelExistForm(Panel) ; //检测下看panel里面是否有别的窗体,有就kill掉。 frNewForm := TForm(NewForm) ;
frNewForm := NewFormClass.CreateParented(Panel.Handle);
frNewForm.BorderStyle := bsNone ;
frNewForm.Parent := Panel ;
frNewForm.Align := alClient ;
frNewForm.Show ; Panel.Visible := True ;
finally
end;
end;调用:CreateNewFormClass(Txxx, xxx, plShow);我使用以上方式创建新窗体到panel的。
不知道换成DLL的窗体,能不能成,我没给你测试。
frNewForm.Parent := Panel ;
使用这种方法来用panel加载窗体,会导致窗体上的组件无法获得焦点,无法操作
应该用windows.setparent函数来设置窗体的容器
windows.setparent函数 我没用过.不过我好像没发现窗体上组件无法获得焦点的问题額~我程序里面窗体这么申请后, 操作是正常的.
在主窗体中procedure TUnit_main.Button1Click(Sender: TObject);
type
mypointer=Procedure(ahand:THandle;panel1:TPanel);stdcall;
var
Handle:THandle;
frm_p:mypointer;
begin
Handle:=loadlibrary('Project2.dll');
if Handle>32 then
begin
@frm_p:=GetProcAddress(Handle,'ShowTest');
if @frm_p<>nil then frm_p(Panel1.Handle,Panel1);
end;
Freelibrary(Handle);
end;
dll工程中
procedure ShowTest(ahand:THandle;panel1:TPanel);stdcall; //dll函数 用于显示窗体
var
f:TForm2;
begin
f:=TForm2.Create(nil);
try
f.ParentWindow:=ahand;
f.ShowModal; //使用ShowModal 能在主窗体显示 但是处于有膜状态,不能操作。。
f.Show;//使用show报内存错误
except
f.Free;
end;
end;
随后就在主程序中Freelibrary估计是这里释放正在加载的dll导致的错误
如果窗体多,可以记录到数组或TStringlist里
已加载的dll也同样需要记录释放dll要根据程序的需要来操作
可以在关闭panel所在的窗体时释放所有已经记录的已加载的dll
string类型与int类型可以互相转换的
procedure TUnit_main.FormDestroy(Sender: TObject);
var i:Integer;
begin
for I := 0 to dllHList.Count - 1 do
begin
FreeLibrary(strtoint(dllHList[i]));
end;
end; 最后报错
procedure TUnit_main.FormDestroy(Sender: TObject);
var i:Integer;
begin
for I := 0 to dllHList.Count - 1 do
begin
FreeLibrary(strtoint(dllHList[i]));
end;
end; 最后报错不能在dll自己的窗体内FreeLibrary
要在主窗体中FreeLibrary
你邮箱多少?我把测试代码发给你帮我看看?谢谢了啊