需求:在DLL(或用其他类似的机制)中设置一个窗体
然后在调用这个DLL的主窗体中显示这个窗体
关键:要让DLL中的窗体作为主窗体的一部分显示出来
而不是利用弹出窗口!
测试例子一:在exe中放两个窗口,Form1 及 Form2 在Form1中放一按钮,实现
将Form2嵌入到Form1中
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Form2:=TForm2.Create(nil);
form2.Parent:=form1;
form2.Align := alclient;
SetWindowLong(form2.Handle,GWL_STYLE,GetWindowLong(form2.Handle,GWL_STYLE) and not WS_CAPTION);
form2.show;
end;
以上做法是能完美这现窗体嵌入,但将(Form2及代码)复杂到 dll 中,exe主窗体通过dllApi参数: hParent: TObject传递,在dll 中打开Form2窗体如下:
procedure TForm2.ShowForm(app;application;hParent: TObject);
begin
Form2:=TForm2.Create(app);
form2.Parent:=TForm(hParent);
form2.Align := alclient;
SetWindowLong(form2.Handle,GWL_STYLE,GetWindowLong(form2.Handle,GWL_STYLE) and not WS_CAPTION);
form2.show;
end;
当运行exe,程序执行到dll中 报内存地址错误,Form2也因此无法嵌入到exe窗体Form1中,请各位出手帮忙看看
----------------------------------------------------------------------
试试在Form2的创建前,保存Application.Handle,然后将Application.Handle设置为app.Handle试试
在退出前最好恢复DLL的Application.Handle
--------------------------------------------------------
多谢 minjunw(minjunw) ,你说的方法,试过,但没成,与之前报一样错
--------------------------------------------------------
该问题已解决,发出来给大家共享下:
dll 中窗体类程序:
......
function TFrmInWin.ShowForm(App:TApplication;hParent:TWinControl):HWND;
begin
try
application:=App;
FrmInWin:=TFrmInWin.Create(app);
FrmInWin.parent:= hParent;
//FrmInWin.parent:= FindControl(hParent);
SetWindowLong(FrmInWin.Handle,GWL_STYLE,GetWindowLong(FrmInWin.Handle,GWL_STYLE) and not WS_CAPTION);
FrmInWin.Show;
//FrmInWin.Perform(CM_VISIBLECHANGED, ord(false), 0);
//FrmInWin.Perform(CM_VISIBLECHANGED, ord(true), 0);
result:=FrmInWin.Handle;
//FreeAndNil(FrmInWin);
except
on e:exception do
begin
showmessage(e.Message);
result:=0;
end;
end;
end;
dll的接口:
....
var g_hApp: TApplication;
....
procedure SaveApplication(App:TApplication);
begin
if not Assigned(g_hApp) then
begin
g_hApp := Application;
Application := App;
end;
end;
// GotTempletPage 专用
//function ShowForm(App:TApplication;hParent:HWND):HWND;stdcall;
function ShowForm(App:TApplication;hParent:TWinControl):HWND;stdcall;
begin
SaveApplication(app);
result:=FrmInWin.ShowForm(App,hParent);
//FrmInWin.parent:= hParent;
end;
procedure DllMainProc(Reason: integer);
begin
if Reason = DLL_PROCESS_DETACH then
if Assigned(g_hApp) then
begin
Application := g_hApp;
end;
end;
exports
ShowForm;
begin
DllProc := @DllMainProc;
end.
exe中程序:
// 定义
function Show_Test(App:TApplication;hParent:TWinControl):HWND;stdcall;external 'GpsCrkInter.dll' name 'ShowForm';
// 事件调用
procedure TForm1.Button1Click(Sender: TObject);
begin
if Panel1.ControlCount>0 then
begin
Panel1.Controls.Free;
end;
Show_Test(Application,Panel1);
self.Perform(CM_VISIBLECHANGED, ord(false), 0);
self.Perform(CM_VISIBLECHANGED, ord(true), 0);
end;
如有需要的朋友,可留邮件,我将完成源码发给大家
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。