我用delphi写了一个带dll的窗体,
在主程序中通过动态调用DLL。
在先关闭DLL窗体再关闭主程序没什么问题,不会报错。
如果在打开DLL窗体的情况下,直接关闭主程序就会报错runtime error 216 ...
请问各位高手如何解决???
在主程序中通过动态调用DLL。
在先关闭DLL窗体再关闭主程序没什么问题,不会报错。
如果在打开DLL窗体的情况下,直接关闭主程序就会报错runtime error 216 ...
请问各位高手如何解决???
解决方案 »
- 帮忙看看下面这段update,为什么不能更新数据库呢?谢谢~!
- access 数据集 insert 问题 标准表达式…不匹配?
- 高手请看进来~~帮帮后来者吧~~
- Delphi应该怎么学?
- shellapi调用MS DOS 后怎么的到在dos中敲了那些命令呢???
- 现在我在执行一个程序怎么会出现一个错误别人给我说是有冲突,不知道该怎么办。up有分!!
- 我想用RegisterHotKey设置系统热键,但用THotKey控件来由用户自己定义要设置的热键,请问应该怎么办
- 请问什么是ERP
- (delphi6的websnap的少儿不宜)不会请别看!
- 请问Paradox数据库中BCD字段类型Size属性的具体含义?
- 用SPCOMM向串口发送数据失败,WriteCommData返回FALSE,GetLastError的结果是1444(无效的线程标识),究竟是什么问题啊???
- 如果将一个.pas文件加入到项目中呢?
procedure Newwgrk(H: THandle; AConn: Widestring; S: string; N: Integer);
begin
Application.Handle := H;
NewRk:=TNewRk.Create(Application);
with NewRk do
try{ 创建窗体 }
con1.ConnectionString:=aconn;
stat1.Panels[1].Text:=S;
if not showing then
Show; { 模式化显示窗体 }
except
con1.connected:=False;
free;
end;
end;主程序中是这样调用的:
type
TDll=procedure(H:THandle;AConn:WideString;S:string;N:Integer);register;{ 指定调用协议 }Procedure tmainfrm.shownewwgrk(sender:tobject);
var
Dll:TDllwg;
DllName:THandle;
begin
DllName:=LoadLibrary('jxwgrk.dll');// Dll的路径
try
if DllName<32 then
begin
messagebox(handle,'没有找到附带DLL文件,请确认程序是否完整!','加载DLL失败',MB_OK+MB_ICONEXCLAMATION);
exit;
end;
@Dll:=GetProcAddress(DllName,'Newwgrk');
if @dll <> nil then
try
Dll(Application.Handle,frmlog.Drugconn.ConnectionString,statusbar2.Panels[0].Text,256);
except
raise Exception.Create('不存在!');
end;
except
FreeLibrary(DllName);//
end;
end;
各位看看需要如何改进,才能避打开Dll的同时,直接关闭主程序后报错的问题???
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
rslt := spiMain.UnloadAllPlugins(FALSE);//那就在退出主程序前先Unload一下主程序中包含的所有DLL呗
end;
Undeclared identifier: 'unloadallplugins'
UnloadAllPlugIns(False)如何加,加在哪个地方??
改为ShowModal才是模态显示窗体如果不是模态显示,则关闭主程序前必须释放到DLL中的窗体资源.不然肯定报错.
var
DllApp : TApplication;
DLLScr: TScreen;procedure ExitDLL(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScr;
end;
end;begin
DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL; // DLLProc 在SysInit单元中
end.
然后把你的DLL函数改成
procedure Newwgrk(H: TApplication; HS: TScreen; AConn: Widestring; S: string; N: Integer);
begin
Application := H;
Screen := HS;
........
end;
最后把你的调用函数改成:
type
TDll=procedure Newwgrk(H: TApplication; HS: TScreen; AConn: Widestring; S: string; N: Integer);
var
DllName:THandle; // 要么单元全局, 要么放在MainForm成员里面 采用ShowModal则不用
Procedure tmainfrm.shownewwgrk(sender:tobject);
var
Dll:TDllwg;
begin
if DllName = 0 then
DllName:=LoadLibrary('jxwgrk.dll');// Dll的路径
try
if DllName <32 then
begin
messagebox(handle,'没有找到附带DLL文件,请确认程序是否完整!','加载DLL失败',MB_OK+MB_ICONEXCLAMATION);
exit;
end;
Dll:=GetProcAddress(DllName,'Newwgrk');
if Dll <> nil then
try
Dll(Application.Handle,frmlog.Drugconn.ConnectionString,statusbar2.Panels[0].Text,256);
except
raise Exception.Create('不存在!');
end;
except
// 这句不放这儿 FreeLibrary(DllName);
end;
end; finalization
FreeLibrary(DllName); // 改放这儿
procedure TThemeServices.UnloadThemeData;
var
Entry: TThemedElement;
begin
if not IsLibrary then//添加这句就好,但是这样dll是否使用主题就只能由exe决定了,对于全部窗口
//封装在dll的可能要再修改一点,例如为这个类加一个属性来控制开关就好了。
for Entry := Low(TThemeData) to High(TThemeData) do
if FThemeData[Entry] <> 0 then
begin
try
CloseThemeData(FThemeData[Entry]);
FThemeData[Entry] := 0;
except
end;
end;
end;