如何在DLL文件中使用ADOConnection和ADOQuery控件???(50分)

  • 主题发起人 主题发起人 ql
  • 开始时间 开始时间
Q

ql

Unregistered / Unconfirmed
GUEST, unregistred user!
各位师兄晚上好,在下有个困扰许久的问题,最近本人在学习DLL文件的编写,但遇到这样的问题:<br>我想用DLL文件的形式写个登录窗口,在DLL文件加入了ADOConnection和ADOQuery这样两个控件,但在调用时总是有问题,不知道是什么原因,请高手指点一下谢谢,附带原代码:<br>DLL文件部分:<br>library DLL;<br>uses<br>&nbsp; ShareMem,<br>&nbsp; SysUtils,<br>&nbsp; Classes,<br>&nbsp; FDLL in 'FDLL.pas' {Form1};<br>exports<br>&nbsp; GetDLL; &nbsp;<br>{$R *.res}<br>begin<br>end.<br>——————————————————————————————————<br>unit FDLL;<br>interface<br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls, DB, ADODB;<br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Edit1: TEdit;<br>&nbsp; &nbsp; Edit2: TEdit;<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; Label1: TLabel;<br>&nbsp; &nbsp; Label2: TLabel;<br>&nbsp; &nbsp; ADOConnection1: TADOConnection;<br>&nbsp; &nbsp; ADOQuery1: TADOQuery;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br>&nbsp; procedure GetDLL(var Op,Pass : string);export;<br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; TmpOp,TmpPass : string;<br>&nbsp; switch : boolean;<br>implementation<br>{$R *.dfm}<br>procedure GetDLL(var Op,Pass : string);<br>begin<br>&nbsp; if switch = false then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; switch := true;<br>&nbsp; &nbsp; &nbsp; form1 := tform1.Create(application);<br>&nbsp; &nbsp; end;<br>&nbsp; if form1.ShowModal = IdOk then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; Op := TmpOp;<br>&nbsp; &nbsp; &nbsp; Pass := TmpPass;<br>&nbsp; &nbsp; &nbsp; switch := false;<br>&nbsp; &nbsp; end;<br>end;<br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; adoconnection1.Close;<br>&nbsp; &nbsp; &nbsp; adoconnection1.ConnectionString := 'Provider=MSDASQL.1;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Persist Security Info=False;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'User ID=sa;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Data Source=QL;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Mode=ReadWrite;' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Initial Catalog=traffic';<br>&nbsp; &nbsp; &nbsp; adoconnection1.LoginPrompt := false;<br>&nbsp; &nbsp; &nbsp; adoconnection1.KeepConnection := true;<br>&nbsp; &nbsp; &nbsp; adoconnection1.Connected &nbsp;:= true;<br>&nbsp; &nbsp; &nbsp; adoconnection1.Open;<br>&nbsp; &nbsp; &nbsp; adoquery1.Connection := adoconnection1;<br>&nbsp; &nbsp; &nbsp; with adoquery1 do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Close;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SQL.Clear;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SQL.Add('select * from sczy');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Open;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; if adoquery1.Bof and adoquery1.Eof then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; application.MessageBox('数据库中无可用信息!','系统信息',16);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; application.Terminate;<br>&nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; else switch := true;<br>&nbsp; &nbsp; end<br>&nbsp; except<br>&nbsp; &nbsp; application.Terminate;<br>&nbsp; end;<br>end;<br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; switch := true;<br>&nbsp; if edit1.Text &lt;&gt; '' then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; TmpOp := edit1.Text;<br>&nbsp; &nbsp; &nbsp; TmpPass := edit2.Text;<br>&nbsp; &nbsp; &nbsp; with adoquery1 do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Close;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SQL.Clear;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SQL.Add('select * from sczy where');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SQL.Add('(工号 = ' + '''' + trim(TmpOp) + '''' + ') and');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SQL.Add('(密码 = ' + '''' + trim(TmpPass) + '''' + ')');<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Open;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; if adoquery1.Bof and adoquery1.Eof then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; application.MessageBox('数据库中无此工号!','系统信息',16);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; edit1.Text := '';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; edit2.Text := '';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TmpOp := '';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TmpPass := '';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; edit1.SetFocus;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ModalResult := IdNo;<br>&nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; else ModalResult := IdOk;<br>&nbsp; &nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; application.MessageBox('工号窗口不能为空!','系统信息',32);<br>&nbsp; &nbsp; &nbsp; edit1.SetFocus;<br>&nbsp; &nbsp; &nbsp; ModalResult := IdNo;<br>&nbsp; &nbsp; end;<br>end;<br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp; switch := true;<br>&nbsp; ModalResult := IdOk;<br>end;<br>end.<br><br>调用程序部分:<br>program ShowDLL;<br>uses<br>&nbsp; ShareMem,<br>&nbsp; Forms,<br>&nbsp; FShowDLL in 'FShowDLL.pas' {Form1};<br>{$R *.res}<br>begin<br>&nbsp; Application.Initialize;<br>&nbsp; Application.CreateForm(TForm1, Form1);<br>&nbsp; Application.Run;<br>end.<br>——————————————————————————————————<br>unit FShowDLL;<br>interface<br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls, DB, ADODB;<br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Label1: TLabel;<br>&nbsp; &nbsp; Label2: TLabel;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br>&nbsp; TMultiplyNum = procedure(var Op,Pass : string);<br>&nbsp; procedure MyGetDLL;export;<br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; StrOp,StrPass : string;<br>&nbsp; MyMultiplyNum : TMultiplyNum;<br>&nbsp; MyHandle : THandle;<br>implementation<br>{$R *.dfm}<br>procedure MyGetDLL;<br>begin<br>&nbsp; MyHandle := LoadLibrary('DLL.dll');<br>&nbsp; if MyHandle &lt;&gt; 0 then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; @MyMultiplyNum := GetProcAddress(MyHandle,'GetDLL');<br>&nbsp; &nbsp; &nbsp; if (@MyMultiplyNum) &lt;&gt; nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MyMultiplyNum(StrOp,StrPass);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FreeLibrary(MyHandle);//此处好像有问题<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>end;<br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; MyGetDLL;<br>&nbsp; label1.Caption := '工号:' + StrOp;<br>&nbsp; label2.Caption := '密码:' + StrPass;<br>end;<br>procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);<br>begin<br>&nbsp; if application.MessageBox('是否要退出系统?','系统信息',32 + MB_YesNo) = IDYes then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; application.Terminate;<br>&nbsp; &nbsp; end;<br>end;<br>end.<br>——————————————————————————————————<br>以上代码需要实现的功能是:<br>1、由应用程序调用DLL文件。<br>2、在DLL文件中输入工号和密码,如果数据库中存在则登录成功。<br>3、将在DLL文件中输入的工号和密码传给可执行文件,并在‘Label1’和‘Label2’中显示。<br>需要达到的要求:<br>1、在DLL文件判断所输入的工号和密码正确前不能返回。<br>2、在数据库没打开或不存在时可以关闭整个程序,包括可执行文件。<br>3、本例采用的是动态调用DLL方式。<br>请高手指点迷津,在下先谢谢了!!!<br>另外小弟也是初学,不知道现在水平到底如何,通过这段程序请大家评判一下。<br>虚心向各位师兄请教。
 
我也不熟,提供思路<br>1.用BPL,动态调用不会<br>2.点确定时发消息给主程序,在主程序里判断<br>我想第2个应该比较合适,<br>要不然[blue][在数据库没打开或不存在时可以关闭整个程序,包括可执行文件。][/blue]<br>比较麻烦,不知道会出现什么问题
 
在dll中使用ADO的解答:<br><br>在 unit FDLL 中 uses ActiveX ,在最后(end.之前)加上:<br>initialization<br>&nbsp; &nbsp; CoInitialize(nil);<br>finalization<br>&nbsp; &nbsp; CoUninitialize;<br><br>1、在DLL文件判断所输入的工号和密码正确前不能返回。<br>答:过程没有结束之前自然不会返回;<br><br>2、在数据库没打开或不存在时可以关闭整个程序,包括可执行文件。<br>答:没试过,不过好像有好多方法,比如通过返回值在调用程序中判断是否退出等;<br><br>3、本例采用的是动态调用DLL方式。<br>答:用 LoadLibrary、FreeLibrary ,用法看帮助或在delphibbs中搜索一下。
 
还是不行啊,还有问题,和原来一样。<br>我再描述一下我现在问题的状况:<br>DLL文件可以启动,也能判断输入的内容是否正确,但点确定后可以即退出DLL,不管正确与否都退出该DLL,并未实现只有正确才退出。<br>在主程序中可以启动DLL文件,也能获得由DLL文件传出的参数变量,但无法正常关闭主程序,总是报错。
 
在调用dll的程序的.dpr文件的第一个uses的单元也必须是 ShareMem 。<br>
 
我上面的程序里有的。应该不是这个问题。
 
我用得好好的啊,<br>只要单元里面加上<br>initialization<br>&nbsp; &nbsp; CoInitialize(nil);<br>finalization<br>&nbsp; &nbsp; CoUninitialize;<br>就没问题了
 
为何关闭主程序时会出现:<br>"0x1c027b05"指令引用的"0x1c027b05"内存。该内存不能"read"。要终止程序,请单击“确定”。<br>然后是:<br>Runtime error 216 at 1c027b05<br>为什么有这样的提示???<br>请指教!!!
 
两个凡是:凡是new的都要dispose,凡是create的都要free。<br><br>你再调试调试吧。
 
要我做的话,这样的功能分开好了,我总觉得在DLL中作这样的事情不好<br>.点确定时发消息给主程序,在主程序里判断<br>我想第2个应该比较合适,<br>要不然[在数据库没打开或不存在时可以关闭整个程序,包括可执行文件。]<br>比较麻烦,不知道会出现什么问题
 
根据DLL的编写法则,建议不要在DLL中使用控件,我以前在DLL中也使用ADO,如果不在单元里面加上<br>initialization<br>&nbsp; &nbsp; CoInitialize(nil);<br>finalization<br>&nbsp; &nbsp; CoUninitialize;<br>肯定报错为何关闭主程序时会出现:<br>"0x1c027b05"指令引用的"0x1c027b05"内存。该内存不能"read"。要终止程序,请单击“确定”。<br>然后是:<br>Runtime error 216 at 1c027b05<br>后来我把ADO放到子程序里去用就一点问题都没有.<br>
 
多人接受答案了。
 
后退
顶部