我在主表单中自定义了一个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;
请大家帮忙解决,这个问题已经烦了我好多天了
主程序中的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;
请大家帮忙解决,这个问题已经烦了我好多天了
form1有什麼代碼麼?
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的话那就调用失败
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.