需求:在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中,请各位出手帮忙看看

解决方案 »

  1.   

    试试在Form2的创建前,保存Application.Handle,然后将Application.Handle设置为app.Handle试试在退出前最好恢复DLL的Application.Handle
      

  2.   

    多谢 minjunw(minjunw) ,你说的方法,试过,但没成,与之前报一样错
      

  3.   

    该问题已解决,发出来给大家共享下:
    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;如有需要的朋友,可留邮件,我将完成源码发给大家