RT上图上代码。点击确定后确定后窗体是能正常显示,但是我窗体里面的动态树不见了。这个地方本来是动态树,现在空白。树的刷新功能也会出现类似图一的错误。
DLL代码
library ProInfoDll;uses
  Sharemem,
  Forms,
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  Dialogs,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2},
  Unit3 in 'Unit3.pas' {Form3},
  Unit4 in 'Unit4.pas' {Form4},
  Unit5 in 'Unit5.pas' {DataModule5: TDataModule},
  Unit6 in 'Unit6.pas' {Form6},
  Unit8 in 'Unit8.pas' {Form8},
  Unit9 in 'Unit9.pas' {Form9};{$R *.res}procedure ProvaChild(ParentApplication: TApplication; ParentForm: TForm); export; stdcall;
var
  Form1: TForm1;
  DllProc: Pointer;             { Called whenever DLL entry point is called }begin
   Application:=ParentApplication;   Form1:=TForm1.Create(ParentForm);
   Form1.MyParentForm:=ParentForm;
   Form1.MyParentApplication:=ParentApplication;
//   windows.SetParent(Form1.Handle,ParentForm.Handle);
//   Form1.FormStyle:=fsMDIChild;
   Form1.Show;
end;procedure DLLUnloadProc(Reason: Integer); register;
begin
  if Reason = DLL_PROCESS_DETACH then  Application:=DllApplication;
end;exports
   ProvaChild;begin
   DllApplication:=Application;
   DLLProc := @DLLUnloadProc;
end.
主窗体调用dll代码 
procedure TForm9.ToolButton2Click(Sender: TObject);
var
   DllHandle: THandle;
   ProcAddr: FarProc;
   ProvaChild: T_ProvaChild;
begin
  Panel1.Visible:=False;
  Panel2.Visible:=False;
  DllHandle := LoadLibrary('ProInfoDll');
   ProcAddr := GetProcAddress(DllHandle, 'ProvaChild');
   if ProcAddr <> nil then
   begin
      ProvaChild := ProcAddr;
      ProvaChild(Application,Self);
   end;end;

解决方案 »

  1.   

    DLL内子窗体部分代码
      private
        { Private declarations }
        procedure AddClass(AId:integer;FatherNode:TTreeNode);//添加分类过程
        procedure AddDataToDB(CurrNode,FatherNode:TTreeNode);//添加实际数据到数据库
      public
        { Public declarations }
        MyParentForm: TForm;
        MyParentApplication: TApplication;
        procedure FillTreeView(TreeView: TTreeView);  end;var
      Form1: TForm1;
            //CurrentTreeNode: TTreeNode;
        // AddChildeTreeNode: TTreeNode;
        // flag:boolean; //用于标识是否需要在重命名树结点时更新数据
         DllApplication: TApplication;
    procedure TForm1.AddClass(AId: integer; FatherNode: TTreeNode);
    var
        QryTmp:TADOQuery;
        myNode:TTreeNode;
        myLabel:TLabel;
    begin
        QryTmp:=TADOQuery.Create(self);
        QryTmp.Connection:=ADOConnection2;
        QryTmp.SQL.Add('select * from Type');
        QryTmp.SQL.Add('where ParentID='+inttostr(AId));
        QryTmp.Open;
        while not QryTmp.Eof do
        begin
            myNode:=Treeview1.Items.AddChild(FatherNode,QryTmp.fieldbyname('Name').AsString);        //创建标签,caption存放各分支的AutoId表识
            myLabel:=TLabel.Create(self);
            myLabel.Visible:=false;
            myLabel.Caption:=QryTmp.fieldbyname('ID').AsString;
            myNode.Data:=myLabel;        AddClass(QryTmp.fieldbyname('ID').AsInteger,myNode); //递归调用过程
            QryTmp.Next;
        end;
        QryTmp.Free;
    end;procedure TForm1.AddDataToDB(CurrNode, FatherNode: TTreeNode);
    var
        myLabel:TLabel;
        QryTmp:TADOQuery;
        AId:integer;
    begin
        if not assigned(FatherNode) then
            AId:=0
        else if not assigned(FatherNode.Data) then
            AId:=0
        else
            AId:=strtoint(TLabel(FatherNode.Data).caption);
        QryTmp:=TADOQuery.Create(self);
        QryTmp.Connection:=ADOConnection2;
        QryTmp.SQL.Add('select * from Type');
        QryTmp.SQL.Add('where ParentID ='+inttostr(AId));
        QryTmp.Open;
        QryTmp.Append;
        QryTmp['ParentID']:=AId;
        QryTmp['Name']:=CurrNode.Text;
        QryTmp.Post;    //创建记录currNode的AutoId表识标
        myLabel:=TLabel.Create(self);
        myLabel.Visible:=False;
        MyLabel.Caption:=QryTmp.fieldbyname('ID').AsString;
        CurrNode.Data:=myLabel;    QryTmp.Free;end;procedure TForm1.FillTreeView(TreeView: TTreeView);
      procedure CreateSubTree(FNodeName: string; Node: TTreeNode = nil);
      var
        mLocalName: string;
        TreeNode: TTreeNode;
        Ads_Tmp: TADODataSet;
      begin
        ADS_Tmp := TADODataSet.Create(Self);
        ADS_Tmp.Connection := DataModule5.ADOConnection2;
        with ADS_Tmp do
        try
          Close;
          CommandText := 'Select * from Type Where ParentID =' + FNodeName;
          Open;
          First;
          while not Eof do
          begin
            mLocalName := FieldbyName('ID').Asstring;
            TreeNode := TreeView.Items.AddChild(Node, FieldByName('Name').AsString);
            CreateSubTree(mLocalName, TreeNode); // 此处循环递归
            Next;
          end;
        finally
          ADS_Tmp.Free;
        end;
      end;
    begin
      TreeView.Items.BeginUpdate;
      TreeView.Items.Clear;
      with TreeView.Items.Add(nil, '所有种类') do
      begin
        SelectedIndex := 1;
      end;
       with TreeView.Items.Add(nil, '未分类产品') do
      begin
        SelectedIndex := 2;
      end;
       with TreeView.Items.Add(nil, '优势产品') do
      begin
        SelectedIndex := 3;
      end;
      CreateSubTree('0', TreeView.Items[0]);
      TreeView.Items.EndUpdate;
      TreeView.Items[1].Selected := True;
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action:=caFree;
      ADOQuery2.Close;
      Form9.Panel1.Visible:=True;
      Form9.Panel2.Visible:=True;
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ADOQUERY1.RecordCount;
      StatusBar1.Panels[2].Text:='共'+ InttoStr(ADOQUERY1.RecordCount) +'条';
      StatusBar1.Panels[4].Text:='录入时间:'+DBEdit34.Text;
      ADOQuery2.Open;
      with TreeView1 do
    begin
      Items.BeginUpdate;
      Items.Clear;
      FillTreeView(TreeView1);
      Items.EndUpdate;
    end;
    procedure TForm1.N1Click(Sender: TObject);
    var
        //strName:string;
        myNode:TTreeNode;
    begin
        Form2:=TForm2.Create(nil);
        if (Form2.ShowModal = mrYes) then   
        myNode:=treeview1.Items.AddChild(treeview1.Selected,Form2.Edit1.Text);
        AddDataToDB(myNode,treeview1.Selected);
        myNode.selected:=true;
    end;
    procedure TForm1.N2Click(Sender: TObject);
    begin
        if MessageDlg('确定要删除种类【'+TreeView1.Selected.Text+'】吗?',mtInformation,[mbYes, mbNo],0)= mryes then
        begin
        ADOQuery2.Close;
        ADOQuery2.SQL.Clear;
        ADOQuery2.SQL.Text:='Delete  from Type where Name=:a';
        ADOQuery2.Parameters.ParamByName('a').Value:=TreeView1.Selected.Text;
        //ADOQuery2.Open;
        ADOQuery2.ExecSQL;
        Treeview1.Selected.Delete;
        end;
    end;procedure TForm1.N3Click(Sender: TObject);
    begin
      with TreeView1 do
    begin
      Items.BeginUpdate;
      Items.Clear;
      FillTreeView(TreeView1);
      Items.EndUpdate;
    end;
    end;
    procedure TForm1.TTreeView1(Sender: TObject);
    begin
      if TreeView1.Selected.Text='0001 电动车' then
         begin
          ADOQuery1.Close;
          ADOQuery1.SQL.Clear;
          ADOQuery1.SQL.Add('SELECT * FROM pro_electrombile');
          ADOQuery1.Prepared;
          ADOQuery1.Open;
         end;
      if TreeView1.Selected.Text='0002 四驱车' then
         begin
          ADOQuery1.Close;
          ADOQuery1.SQL.Clear;
          ADOQuery1.SQL.Add('SELECT * FROM pro_Signigobius_biocellatus');
          ADOQuery1.Prepared;
          ADOQuery1.Open;
         end;
    end;end.
      

  2.   

    子窗体的主要功能应该没有错的。如果直接用from调用是没问题的。
      

  3.   

    ProcAddr: FarProc;  函数声明和函数原型不对应
    一个是FarProc
    一个是procedure (ParentApplication: TApplication; ParentForm: TForm); export; stdcall;