我在主表单中自定义了一个loaddll函数,在被调用的dll所包含的pas文件中有个showform函数,而且在调用的表单中创建了一个线程.调用后可以正常显示,但是当关闭调用的窗口时总是出现can change visible in  onshow or in onhide.源代码如下
主程序中的showform
procedure Tform1.LoadDll(dllFile :string);
var
//  libhandle: Thandle;
  ShowForm: TShowForm;
begin
      libhandle :=loadlibrary(pchar(dllFile));
      try
        if libhandle=0 then
          raise EdllLoadError.Create('调用功能模块失败!');
        @ShowForm := getprocaddress(libhandle,'ShowForm');
        if not( @showForm=nil) then
           ShowForm(Application)
        else
         //raiseLastwin32Error;
      finally
       // FreeLibrary(libhandle);
      end;
end;
dll中包含的pas 中的showform
procedure ShowForm(mainApp: TApplication);stdcall;
var
    ptr:PLongInt;
begin
  application.Handle:=mainApp.Handle;
  ptr:=@(Application.mainform);
  ptr^:=LongInt(mainApp.MainForm);
  form1:=Tform1.Create(mainApp.MainForm);   try
    begin
      form1.Show;
      form1.Visible:=true;
      form1.SetFocus;
    end
  finally
  end;
end;
请大家帮忙解决,这个问题已经烦了我好多天了

解决方案 »

  1.   

    問題可能出在你的form1裡。
    form1有什麼代碼麼?
      

  2.   

    我 在form1里面有一个 线程,是 用来进行初始化的,这个线程我只写了execute方法,那问题会不会是我的线程销毁问题,或者表单释放的问题??请问线程销毁和表单释放应该是 怎么 个顺序,用那些代码来写,还有我是不是用写下destroy方法??明天我把form1的代码贴上来,楼上的帮我看看 ,谢谢你了
      

  3.   

    我帮你加了两句释放的 试试dll中包含的pas 中的showform
    procedure ShowForm(mainApp: TApplication);stdcall;
    var
        ptr:PLongInt;
    begin
      application.Handle:=mainApp.Handle;
      ptr:=@(Application.mainform);
      ptr^:=LongInt(mainApp.MainForm);
      form1:=Tform1.Create(mainApp.MainForm);
       try
        begin
          form1.Show;
          form1.Visible:=true;
          form1.SetFocus;
        end
      finally
        form1.free;
      end;
    end;主程序中的showform
    procedure Tform1.LoadDll(dllFile :string);
    var
      libhandle: Integer;
      ShowForm: TShowForm;
    begin
          libhandle :=loadlibrary(pchar(dllFile));
          try
            if libhandle=0 then
              raise EdllLoadError.Create('调用功能模块失败!');
            @ShowForm := getprocaddress(libhandle,'ShowForm');
            if not( @showForm=nil) then
               ShowForm(Application)
            else
             raiseLastwin32Error;
          finally
            FreeLibrary(libhandle);
          end;
    end;这个DLL创建了就必须释放的,和前面的窗体一样 你动态生成了就释放掉
    这样不容易构成异常 libhandle 定义成整型 如果为0的话那就调用失败
      

  4.   

    我的程序中的form1中的代码是这样的,大家帮看看吧
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls, DB, ADODB;type
    MyThread=class(TThread)
    procedure Execute;override;
    end;
      TForm1 = class(TForm)
        Memo1: TMemo;
        Label1: TLabel;
        Edit1: TEdit;
        Button1: TButton;
        ADODataSet1: TADODataSet;
        ADOConnection1: TADOConnection;
        Edit2: TEdit;
        Button2: TButton;
        Button3: TButton;
        Button4: TButton;
        Label2: TLabel;
        Label3: TLabel;
        Button5: TButton;
        Button6: TButton;
        Button7: TButton;
        Button8: TButton;
        Button9: TButton;
        Button10: TButton;
        Button11: TButton;
        Button12: TButton;
        Button13: TButton;
        Label4: TLabel;
        Timer1: TTimer;
        procedure FormActivate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure Button1Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure Edit2Click(Sender: TObject);
        procedure Edit1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
        procedure Button5Click(Sender: TObject);
        procedure Button6Click(Sender: TObject);
        procedure Button7Click(Sender: TObject);
        procedure Button8Click(Sender: TObject);
        procedure Button9Click(Sender: TObject);
        procedure Button10Click(Sender: TObject);
        procedure Button11Click(Sender: TObject);
        procedure Button12Click(Sender: TObject);
        procedure Button13Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
        procedure FormCreate(Sender: TObject);  private
        { Private declarations }
      public
        { Public declarations }
      end;
      procedure ShowForm(mainApp:TApplication);stdcall;
      var
        hwn:Thandle; //用于控制edit的句柄
        isready:boolean; //读卡器状态
        canQuery:boolean; //根据查询条件状态判断是否可以进行查询
        runTime:integer; //表单的存在时间
        CardInit:MyThread;
        Form1: TForm1;
      function checkCardReaderValid(iport:PByte):PChar;stdcall;external 'cardapi.dll';
      function getPersonMsg(iport:PByte):PChar;stdcall;external 'cardapi.dll';
      function resetCardReader(iport:PByte):PChar;stdcall;external 'cardapi.dll';
    implementation{$R *.dfm}
    procedure ShowForm(mainApp: TApplication);stdcall;
    var
        ptr:PLongInt;
    begin
      application.Handle:=mainApp.Handle;
      ptr:=@(Application.mainform);
      ptr^:=LongInt(mainApp.MainForm);
      form1:=Tform1.Create(mainApp.MainForm);   try
        begin
          form1.Show;
          form1.Visible:=true;
          form1.SetFocus;
        end
      finally
      end;
    end;
    procedure TForm1.FormActivate(Sender: TObject);
    begin
        hwn:=edit1.Handle;
      if not edit1.Focused then edit1.SetFocus;  //输入焦点为edit1
      runTime:=20;
      timer1.Enabled:=true;
      CardInit:=MyThread.Create(true);
      CardInit.Execute;    canQuery:=false;//初始化后无输入条件时不可查询end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      isready:=false;
      runTime:=20;
      CardInit.Terminate;
      cardinit.Destroy;end;procedure TForm1.Button1Click(Sender: TObject);
    var
      t:SystemTime;
      a:string;
    begin
      if (canQuery<>true) then
      begin
        if (not (edit1.Text='')) and (not (edit2.Text='')) then
        canQuery:= true;
      end;if not canQuery then
    showmessage('查询条件不足,请完善!')
    else
    begin
    //保存查询日志到Access数据库
      windows.GetLocalTime(t);
      a:=(Format('%d-%d-%d   %d:%d:%d.%d',[t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond,t.wMilliseconds]));
      adodataset1.Active:=true;
      adodataset1.Edit;
      adodataset1.Append;
      try
        adodataset1.FieldByName('DATE_TIME').AsString:=a;
        adodataset1.FieldByName('User').AsString:=edit1.text;
        adodataset1.FieldByName('Successful').AsBoolean:=false;
        adodataset1.Post;
      finally
        adodataset1.Active:=false;
      end;
      end;end;procedure TForm1.Button3Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 50, 0);
    end;procedure TForm1.Edit2Click(Sender: TObject);
    begin
    hwn:=edit2.Handle;
    end;procedure TForm1.Edit1Click(Sender: TObject);
    begin
    hwn:=edit1.Handle;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 49, 0);
    end;procedure TForm1.Button4Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 51, 0);
    end;procedure TForm1.Button5Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 52, 0);
    end;procedure TForm1.Button6Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 53, 0);
    end;procedure TForm1.Button7Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 54, 0);
    end;procedure TForm1.Button8Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 55, 0);
    end;procedure TForm1.Button9Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 56, 0);
    end;procedure TForm1.Button10Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 57, 0);
    end;procedure TForm1.Button11Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 48, 0);
    end;procedure TForm1.Button12Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, 88, 0);
    end;procedure TForm1.Button13Click(Sender: TObject);
    begin
    postmessage(hwn, WM_KEYDOWN, VK_BACK, 0);
    end;procedure Tform1.Timer1Timer(Sender: TObject);
    var
      b:string;
    begin
        runTime:=runTime-1;
        b:=inttostr(runTime);
        label4.Caption:='为保证信息安全该页将于'+b+'秒后关闭';
        if runTime=0 then
        begin      //timer1.Enabled:=false;
          //CardInit.Terminate;
          //CardInit.Destroy;
          form1.Close;
        end;
    end;procedure MyThread.Execute;
    var
       s,p:string;
       i,num:integer;
    begin
      isready:=true;
      try
        //初始化设备
        s:= checkCardReaderValid(0);
        if Copy(s,0,1)='1' then
          form1.Memo1.Lines.Add('### 请放卡.......')
        else
          form1.Memo1.Lines.Add('*** 初始化错误......');    //开始读卡
        while  isready do
          begin
            Application.ProcessMessages;
            p:= getPersonMsg(0);
            if Copy(p,0,1)='1' then
             begin
             form1.Memo1.Lines.Add(p);
             num:=0;
             for i:=1 to length(p) do
             begin
                if copy(p,i,1)='|' then num:=num+1;
                if num=3 then
                begin
                  form1.edit1.Text:=copy(p,i+2,18);
                  canquery:=true; //通过读卡获取身份信息后查询可进行
                  //button1.Enabled:=true;
                end;
             end;
    //复位设备,准备下一次阅读
              resetCardReader(0);
             end;
             Sleep(1000);
          end;
      except
      end;end;procedure TForm1.FormCreate(Sender: TObject);
    begin
    //  CardInit:=MyThread.Create(true);
    //  CardInit.Execute;
    end;end.
      

  5.   

    我的这个程序是在调用完form1关闭后出现错误,错误的地方我想应该在线程的释放和表单的释放问题上,但是不知道怎么改,希望大家帮忙,小弟在这里先谢了