需求:在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中,请各位出手帮忙看看
然后在调用这个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中,请各位出手帮忙看看
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[0].Free;
end;
Show_Test(Application,Panel1);
self.Perform(CM_VISIBLECHANGED, ord(false), 0);
self.Perform(CM_VISIBLECHANGED, ord(true), 0);
end;如有需要的朋友,可留邮件,我将完成源码发给大家