****高手同志们!DLL函数动态申明的问题来是没搞懂********(100分)

  • 主题发起人 主题发起人 todayisthursday
  • 开始时间 开始时间
T

todayisthursday

Unregistered / Unconfirmed
GUEST, unregistred user!
原问题:
我想把DLL中的过程名称放在数据库中!
如何在程序中动态申明这些过程?
例如:在数据库中有read,write两个过程名称(这只是举例,实际中有几个过程,每个过程的名称都要到库里读取)
如何动态能申明成:
read:procedure;stdcall;
write:procedure;stdcall;
并把这两个过程给于右键菜单: item.OnClick:=XXX;
请附有原代码,谢谢
 
不懂你要做什么.
 
“我想把DLL中的过程放在数据库中!”什么意思?
 
我想把DLL中的过程名称放在数据库中!
就是动态申明DLL中的过程,并赋给右键菜单的事件中.
 
明白你的意思了,但是我不会做!!!
就像用javaScriot 写 html 一样!!
但是这里不知道用 什么来写 pascal!

关注!我菜鸟一只!
 
但是好象没必要要这样做吧?
 
帮顶的也谢谢了
 
问题: 这代码应怎么写? ( 积分: 50 )
分类: 数据库-文件型

来自: ykjt, 时间: 2004-09-24 13:38:00, ID: 2823033
表js中存放的分别是
tj(条件) ys(运算公式)
xj>20 bm='hhhhh'
................
表ybbdy中存放被计算的数据
字段有xj,bm,name,....
下面代码adoquery1从表js中取出条件,放到变量中
adoquery2利用条件计算,在SQL语句中,允许使用ktj,但不允许kys,系统提示“应用程序定义paramter对象的方式不适当”,请教,我如何实现我的计算?

procedure TForm1.Button1Click(Sender: TObject);
var
ktj,kys:String;
begin
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from js');
ADOQuery1.Open;
ktj:=ADOQuery1.FieldValues['tj']; //ktj值是'xj>20'
kys:=ADOQuery1.Fieldvalues['ys']; //ksy值是'bm='hhhhh''
ADOQuery2.Close;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Add('update ybbdy set '+kys+' where '+ktj);//这句不行
ADOQuery2.ExecSQL;
end;

来自: maplesw, 时间: 2004-09-24 13:43:16, ID: 2823051
see

来自: woshisunyi, 时间: 2004-09-24 13:56:01, ID: 2823081
你的sql本来就有问题
update table set 字段1= where 字段2=
而且在sql中引用变量要这样 '''+kys+'''
('update ybbdy set kys= '''+kys+''' where ktj='''+ktj+'''')

来自: ykjt, 时间: 2004-09-24 14:06:25, ID: 2823119
我这里:ktj,kys是变量,其值是一个表达式。

来自: newyorker, 时间: 2004-09-24 14:18:21, ID: 2823150
ktj:=ADOQuery1.FindField('tj').AsString;
kys:=ADOQuery1.FindField('ys').AsString;
改一下试试

来自: ykjt, 时间: 2004-09-24 14:27:32, ID: 2823175
ADOQuery2.SQL.Add('update ybbdy set xj=xj*4 where '+ ktj);
这样的句子能执行,如果xj=xj*4放在变量里就不行了

来自: ykjt, 时间: 2004-09-24 14:30:24, ID: 2823180
to newyorker
你的代码不能执行,提示参数不足。


来自: woshisunyi, 时间: 2004-09-24 14:36:31, ID: 2823202
('update ybbdy set '''+kys+''' where 'ktj)
这样可以吗

来自: wwa, 时间: 2004-09-24 14:38:00, ID: 2823209
程序本身没有错,可能是字段YS有是内容不对!
可以将SQL.text显示出来后再分析!

来自: ykjt, 时间: 2004-09-24 14:41:58, ID: 2823221
ADOQuery2.SQL.Add('update ybbdy set '''+kys+''' where'+ ktj);
系统提示:update语法错误

来自: newyorker, 时间: 2004-09-24 14:46:41, ID: 2823237
主要是要把一个带引号的字符串放到字段里面。
把字符串 'aaa' 放进去容易,要放 ' 'aaa' '就出错了。

来自: newyorker, 时间: 2004-09-24 14:50:36, ID: 2823255
知道了。你把 ys 字段的内容改一下,改成:bm=''hhhhh''
两个引号

来自: ykjt, 时间: 2004-09-25 8:09:16, ID: 2824257
知道了。你把 ys 字段的内容改一下,改成:bm=''hhhhh''
两个引号
===========================================
系统提示“应用程序定义paramter对象的方式不适当”

来自: chinaandys, 时间: 2004-09-25 8:49:53, ID: 2824292
你的sql本来就有问题, update后面是跟着表名的
update table set 字段1= where 字段2=
而且在sql中引用变量要这样 '''+kys+'''
('update ybbdy set kys= '''+kys+''' where ktj='''+ktj+'''')


来自: ykjt, 时间: 2004-09-25 15:27:08, ID: 2824904
('update ybbdy set kys= '''+kys+''' where ktj='''+ktj+'''')
===========================
kys的值是一个计算式,不能设为kys='''+kys+'''.....,这样达不到我的目的。
我想实现的功能类似vfp中的宏代换,把不同的计算式放至变量kys中,代入update语句中以实现对数据库不同的运算。至于计算式的内容由用户在专用的模块中编写,这样无论怎样变化,程序都能适应,不用维护程序源码,以增加程序的灵活性.
各位高手,如何实现?

来自: yayongm, 时间: 2004-09-25 22:49:22, ID: 2824950
ADOQuery2.Close;
ADOQuery2.SQL.Clear;
sTemp := 'update ybbdy set '+kys+' where '+ktj;
ShowMessage(sTemp);
ADOQuery2.SQL.Add(sTemp);//这句不行
ADOQuery2.ExecSQL;
拿sTemp到企业管理器中调试.


来自: ykjt, 时间: 2004-09-27 11:12:37, ID: 2826358
拿sTemp到企业管理器中调试.
////
不懂。
各位大侠,给想想办法吧!!!


来自: moralist, 时间: 2004-09-27 13:15:57, ID: 2826596
运算公式中引号引起的问题

来自: ysx192, 时间: 2004-09-28 13:37:36, ID: 2828475
ADOQuery2.SQL.Add(format('update ybbdy set %s where %s,[kys,ktj]));

来自: ykjt, 时间: 2004-09-28 14:10:54, ID: 2828549
ADOQuery2.SQL.Add(format('update ybbdy set %s where %s,[kys,ktj]));
========================================================
系统提示“应用程序定义paramter对象的方式不适当”

来自: 老香子, 时间: 2004-09-28 14:34:32, ID: 2828589
我想实现的功能类似vfp中的宏代换,把不同的计算式放至变量kys中,代入update语句中以实现对数据库不同的运算。至于计算式的内容由用户在专用的模块中编写,这样无论怎样变化,程序都能适应,不用维护程序源码,以增加程序的灵活性.
===========================================
哪位大侠有解决这类问题的整体方案?或别的思路。
这个问题对高手来说应不难。

来自: ykjt, 时间: 2004-09-30 9:55:16, ID: 2831191
各位大侠,是不是我这么做根据行不通?如果你们做这样的系统(MDB数据库),你们怎么办?

来自: ykjt, 时间: 2004-10-01 13:13:34, ID: 2832545
已解决,谢谢大家

得分大富翁: chinaandys-5,maplesw-5,moralist-5,newyorker-5,woshisunyi-5,wwa-5,yayongm-5,ysx192-5,老香子-10,
 
weiliu[:D]也帮我找找
 
例子:
//------------------------

unit UnitMenu;

interface

uses
controls,comctrls,classes,windows,sysutils,
menus,dialogs, UnitAppConfig,forms;
type
TActionCmd = procedure (handle:Thandle;loginInf:PloginInfo);stdcall;

procedure MenuClick(Sender:TObject);


implementation

uses dmunit;

procedure MenuClick(Sender:TObject);
var
menuID:string;
actcmd:string;

dllName:string;
dllH:THandle;
appPath:string;

ActionCmd:TActionCmd;
begin

appPath := extractFilePath(application.ExeName);
appPath := appPath+'Dll/';

menuID := (Sender as TMenuItem).Name; // name 保存的是 MenuID 的值

with DM.adoqryTemp do
begin
if active then close;
sql.Clear;
sql.Add('select actcmd,dllName,isexit from menu where menuID='''+Menuid+'''');
open;

if FieldByName('isExit').AsBoolean then
begin
application.Terminate;
exit;
end;
if FieldByName('actcmd').IsNull or FieldByName('dllName').IsNull then
begin
messagebox(0,pchar('无法找到要执行的命令,请与管理员联系'),pchar('错误'),
mb_ok+Mb_iconerror);
exit;
end;

actcmd:=FieldByName('actcmd').AsString;
dllName:=FieldByName('dllname').AsString;
close;
if (actcmd='') or (dllname='') then
begin
messagebox(0,pchar('无法找到要执行的命令,请与管理员联系'),pchar('错误'),
mb_ok+Mb_iconerror);
exit;
end;
dllH := loadlibrary(pchar(appPath+dllname));
if dllH = 0 then
begin
messagebox(0,pchar('无法找到动态链接库'),pchar('错误'),
mb_ok+Mb_iconerror);
exit;
end;
try
@ActionCmd := windows.getProcAddress(dllH,pchar(actcmd));
if @ActionCmd = nil then
begin
messagebox(0,pchar('无效的执行命令'),pchar('错误'),
mb_ok+Mb_iconerror);
exit;
end;
//showmessage(loginInfo^.constr);
try
ActionCmd(application.Handle,LoginInfo);
finally
actionCmd := nil;
end;

finally
FreeLibrary(dllH);
end;
end;
end;




end.


我的例子是从数据库中读数据,然后动态创建菜单,给每个菜单动态添加事件,所有的事件
是根据 菜单项的 Name(保存的是数据库里的 id),来读数据库中的 dll 文件名,以及导出的函数名,来执行该 dll 的函数

主程序就是一个框架,程序具体的实现都是由 dll 一实现
 
所有的 dll 里导出的函数都要声明成下面这样
TActionCmd = procedure (handle:Thandle;loginInf:PloginInfo);stdcall;
 
请问如何动态定义一组过程,并对右键附于事件
 
来自:qi_jianzhou, 时间:2006-7-18 14:16:12, ID:3509027
所有的 dll 里导出的函数都要声明成下面这样
TActionCmd = procedure (handle:Thandle;loginInf:PloginInfo);stdcall;

讲的很对,对于请问如何动态定义一组过程,并对右键附于事件
只需要就一个具有相同参数的过程赋予一个实践即可
 
右键也是菜单,道理和我上面说的一样,你可以做一个小例子实验一下,表也很简单
ID Dll CMD

dllH := loadlibrary(pchar(appPath+dllname));
@ActionCmd := windows.getProcAddress(dllH,pchar(actcmd));

这两句是主要的
其它就是操作数据库了
 
对不起,创建一个过程,并赋值右键事件我理解的,但能举个用一个TActionCmd = procedure (handle:Thandle;loginInf:PloginInfo);stdcall;
创建两个过程的事例并赋值右键(两项菜单以上)事件
谢谢
 
ActionCmd := windows.getProcAddress(dllH,pchar(actcmd));
这只是得到一个过程,下一个过程如何用一个ActionCmd 获得地址指针,谢谢您了
 
例如:
dllname := 'Project1.dll';
actcmd := 'Createform1'还有一个叫'Createform2'的
 
哎,好人做到底吧

procedure MenuClick(Sender:TObject);

我为什么要这么定义这一个过程呢?

请仔细看下面这段代码

-----------------------------------------
function TFormMain.createItem(MenuID:string;parentItem:TMenuItem):TmenuItem;
var
item:TMenuItem;
begin
item := TMenuItem.Create(self.MainMenu1);
with dm.adoqryTemp do
begin
if active then close;
sql.Clear;
if LoginInfo^.roleID = SYS then
sql.Add('select * from Menu where MenuId='''+menuid+''' and isShow ')
else
sql.Add('select * from Menu where MenuId='''+menuid+''''
+' and MenuID in(select MenuID from Role where RoleID='''
+LoginInfo^.roleID+''') and isShow ');
try
open;
except
application.Terminate;
exit;
end;
first;
item.Caption := FieldByName('caption').AsString;
item.Name := FieldByName('MenuId').Asstring;

// 设定执行的事件
if FieldByName('isAction').AsBoolean then
item.OnClick := FMenuclick -->> 就是这里
else
item.OnClick := nil;

close;
result := item;
end;
if (item.Caption = '配置') then
if LoginInfo^.roleID=sys then
parentItem.Add(item)
else
begin
exit;
end
else
parentItem.Add(item);

end;

procedure TformMain.FMenuclick(sender:Tobject);
begin
Menuclick(sender); -->> 调用 unitMenu 里的过程
end;


// 每一个菜单都是根据 name 来在数据库里找 dll 以及 actioncmd 的
根本就不用管下一个过程的
只要有 name 里存的 ID 就可以了
 
多人接受答案了。
 
后退
顶部