***菜单权限控制:源码奉送*** V1.0请参见:http://expert.csdn.net/Expert/topic/917/917914.xml?temp=.2989771代码版本现已升级 V2.0,公布源代码--------------------------------------------------------------------------
*****菜单权限分配源码奉送V2.0*****针对以前版本功能有所扩展,增加了模块单元的操作控制//使用ActionMainMenuBar、ActionManager、ActionToolBar效果更佳
//也可以MainMenu、ToolBar、ActionList的组合
数据库表:CREATE TABLE [操作员] (
[操作员ID] [varchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[姓名] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[口令] [varchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[级别] [tinyint] NOT NULL CONSTRAINT [DF_操作员_级别] DEFAULT (2),
[部门ID] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[标志] [bit] NOT NULL CONSTRAINT [DF_操作员_标志] DEFAULT (0),
CONSTRAINT [PK_操作员] PRIMARY KEY CLUSTERED
(
[操作员ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [操作员权限] (
[操作员ID] [char] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[Visible] [bit] NOT NULL CONSTRAINT [DF_操作员权限_Visible] DEFAULT (0),
[Enabled] [bit] NOT NULL CONSTRAINT [DF_操作员权限_Enabled] DEFAULT (0),
[权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [PK_操作员权限] PRIMARY KEY CLUSTERED
(
[操作员ID],
[功能ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [权限组] (
[权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[权限组名称] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[标志] [tinyint] NOT NULL CONSTRAINT [DF_权限组_标志] DEFAULT (0),
CONSTRAINT [PK_权限组] PRIMARY KEY CLUSTERED
(
[权限组ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [权限组功能分配] (
[权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [PK_权限组功能分配] PRIMARY KEY CLUSTERED
(
[权限组ID],
[功能ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [系统功能] (
[功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[菜单名] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[说明] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[分类] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [PK_系统功能] PRIMARY KEY CLUSTERED
(
[功能ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO--“分类”字段的类型改为varchar(50)//原版本为bit--增加了“操作标识”字段:由6位数字组成,
约定:第一位:无意义,以1表示,
第二位:增加,以1或0表示,
第三位:修改,以1或0表示,
第四位:删除,以1或0表示,
第五位:查询,以1或0表示,
第六位:打印,以1或0表示操作标识有两层含义:1、系统功能的“操作标识”,2、操作员的的“操作标识”操作员的的“操作标识”,例如:字符串‘110010’表示可以增加和查询,不能修改、删除和打印系统功能的“操作标识”:必须在设计期间定义Action的操作标识,表示有没有该项功能例如:字符串‘100011’表示该模块有查询、打印功能,没有增加、修改、删除
有效利用Action的各项属性:Name: 功能ID
Caption:菜单名
Hint:说明
Category:分类
Tag:操作标识
定义全局变量:var
ActName,OperaID:TStringList; //功能ID列表,操作标识列表。变量创建过程,这里省略
CurrentOperaID:String; //当前操作标识
//权限分配方法
procedure TMainFrm.AssignLimit;
var
i, j, k, TlbLen: integer;
Ks, Ms: Boolean;
begin for i := 0 to ActionList1.ActionCount - 1 do //所有功能不可用
begin
TAction(ActionList1.Actions[i]).Visible := False;
TAction(ActionList1.Actions[i]).Enabled := False;
end; ActName.Clear; //清除功能ID列表
OperaID.Clear; //清除操作标识列表 for i := 0 to ActionList1.ActionCount - 1 do //分配权限
begin
if LoginFrm.CDSLimit.Locate('功能ID', TAction(ActionList1.Actions[i]).Name, [loPartialKey]) then
begin
TAction(ActionList1.Actions[i]).Enabled := LoginFrm.CDSLimit.FieldByName('Enabled').AsBoolean;
TAction(ActionList1.Actions[i]).Visible := LoginFrm.CDSLimit.FieldByName('Visible').AsBoolean;
ActName.Add(TAction(ActionList1.Actions[i]).Name);//加入功能ID
OperaID.Add(LoginFrm.CDSLimit.FieldByName('操作标识').AsString);//加入操作标识
end;
end;//----------------------------菜单效果------------------------------------------ if LoginFrm.Grade = '0' then //超级管理员固定权限
begin
mmMenuInit.Visible := True; //功能初始化
mmPopGroup.Visible := True; //权限组功能分配
ActOperAssign.Visible := True; //操作员权限分配
ActOperAssign.Enabled := True;
ActSysLogQry.Visible := True; //操作员权限分配
ActSysLogQry.Enabled := True;
end else
begin
mmMenuInit.Visible := false;
mmPopGroup.Visible := false;
end; Ks := False;
Ms := False; for I := 0 to MainMenu.Items.Count - 1 do //一级菜单
begin
for J := 0 to MainMenu.items[I].count - 1 do //二级菜单
begin
if MainMenu.items[I].Items[J].Count > 0 then //若存在三级菜单
begin
for K := 0 to MainMenu.items[I].Items[J].Count - 1 do //三级菜单
begin
if (MainMenu.items[I].Items[J].Items[K].Visible) and
(MainMenu.items[I].Items[J].Items[K].Caption <> '-') then
begin
Ks := True;
Break; //在三级菜单中若存在Visible为True则跳出循环
end;
end;
MainMenu.items[I].Items[J].Visible := Ks;
if Ks then Ms := True;
Ks := False;
end else
if (MainMenu.items[I].Items[J].Visible) and
(MainMenu.items[I].Items[J].Caption <> '-') then
begin
Ms := True; //在二级菜单中若存在Visible为True则主菜单可见
end;
end;
MainMenu.items[I].Visible := Ms;
Ms := False;
end;//-------------------------------快捷菜单效果----------------------------------- TlbLen := 0;
j:=0;
k:=0;
for i := 0 to ToolBar1.ButtonCount - 1 do
begin
if ToolBar1.Buttons[i].Visible then
begin
if (j=0)and(ToolBar1.Buttons[i].Style=tbsSeparator) then
ToolBar1.Buttons[i].Visible:=false //屏蔽分割快捷按钮
else
begin
if ToolBar1.Buttons[i].Style=tbsSeparator then inc(k);
if k=2 then //如果连续排列两个分割快捷按钮
begin
ToolBar1.Buttons[i].Visible:=false; //屏蔽分割快捷按钮
k:=1;
end else
begin
TlbLen:=TlbLen+ToolBar1.Buttons[i].Width;
inc(j);
end;
end;
end;
end;
CoolBar1.Bands[0].Width := TlbLen + 15;//15这个值是个校正值,可能不适合你
//
end;在每个Action的执行代码中,额外加入以下代码procedure TMainFrm.ActWareBuyPlanExecute(Sender: TObject);
begin
CurrentOperaID:=OperaID[ActName.IndexOf(TAction(Sender).Name)];//取得当前操作员当前模块的操作标识
....
end;全局函数://解析操作标识
function ParseOperaID(const AoperaID:string;index:integer):Boolean;
var
TmpPos:integer;
begin
TmpPos:=Index+1;
if Index<1 then TmpPos:=2; //把Index固定在1..5之间
if Index>5 then TmpPos:=6;
Result:=Copy(AoperaID,TmpPos,1)=1;
end;使用方法例如:BtnAdd.Enable:=ParseOperaID(CurrentOperaID,1);//增加
BtnModi.Enable:=ParseOperaID(CurrentOperaID,2);//修改
BtnDel.Enable:=ParseOperaID(CurrentOperaID,3);//删除建议使用按钮的Tag属性-------------------------------------------------------------------------------------------------与之相关的功能列表:1、系统功能初始化:2、权限组功能分配:3、操作员功能分配:限于篇幅,源代码不再贴出,都是简单的数据库操作。注意一点: 操作标识的显示问题,//总不能把‘100110’显示出来吧
最后一段代码:
在数据集字段的OnGetText事件中:var
Str:string;
begin
if ParseO
*****菜单权限分配源码奉送V2.0*****针对以前版本功能有所扩展,增加了模块单元的操作控制//使用ActionMainMenuBar、ActionManager、ActionToolBar效果更佳
//也可以MainMenu、ToolBar、ActionList的组合
数据库表:CREATE TABLE [操作员] (
[操作员ID] [varchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[姓名] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[口令] [varchar] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[级别] [tinyint] NOT NULL CONSTRAINT [DF_操作员_级别] DEFAULT (2),
[部门ID] [varchar] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[标志] [bit] NOT NULL CONSTRAINT [DF_操作员_标志] DEFAULT (0),
CONSTRAINT [PK_操作员] PRIMARY KEY CLUSTERED
(
[操作员ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [操作员权限] (
[操作员ID] [char] (15) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[Visible] [bit] NOT NULL CONSTRAINT [DF_操作员权限_Visible] DEFAULT (0),
[Enabled] [bit] NOT NULL CONSTRAINT [DF_操作员权限_Enabled] DEFAULT (0),
[权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [PK_操作员权限] PRIMARY KEY CLUSTERED
(
[操作员ID],
[功能ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [权限组] (
[权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[权限组名称] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[标志] [tinyint] NOT NULL CONSTRAINT [DF_权限组_标志] DEFAULT (0),
CONSTRAINT [PK_权限组] PRIMARY KEY CLUSTERED
(
[权限组ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [权限组功能分配] (
[权限组ID] [char] (2) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [PK_权限组功能分配] PRIMARY KEY CLUSTERED
(
[权限组ID],
[功能ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [系统功能] (
[功能ID] [varchar] (30) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[菜单名] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[说明] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[分类] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[操作标识] [char] (6) COLLATE Chinese_PRC_CI_AS NOT NULL ,
CONSTRAINT [PK_系统功能] PRIMARY KEY CLUSTERED
(
[功能ID]
) ON [PRIMARY]
) ON [PRIMARY]
GO--“分类”字段的类型改为varchar(50)//原版本为bit--增加了“操作标识”字段:由6位数字组成,
约定:第一位:无意义,以1表示,
第二位:增加,以1或0表示,
第三位:修改,以1或0表示,
第四位:删除,以1或0表示,
第五位:查询,以1或0表示,
第六位:打印,以1或0表示操作标识有两层含义:1、系统功能的“操作标识”,2、操作员的的“操作标识”操作员的的“操作标识”,例如:字符串‘110010’表示可以增加和查询,不能修改、删除和打印系统功能的“操作标识”:必须在设计期间定义Action的操作标识,表示有没有该项功能例如:字符串‘100011’表示该模块有查询、打印功能,没有增加、修改、删除
有效利用Action的各项属性:Name: 功能ID
Caption:菜单名
Hint:说明
Category:分类
Tag:操作标识
定义全局变量:var
ActName,OperaID:TStringList; //功能ID列表,操作标识列表。变量创建过程,这里省略
CurrentOperaID:String; //当前操作标识
//权限分配方法
procedure TMainFrm.AssignLimit;
var
i, j, k, TlbLen: integer;
Ks, Ms: Boolean;
begin for i := 0 to ActionList1.ActionCount - 1 do //所有功能不可用
begin
TAction(ActionList1.Actions[i]).Visible := False;
TAction(ActionList1.Actions[i]).Enabled := False;
end; ActName.Clear; //清除功能ID列表
OperaID.Clear; //清除操作标识列表 for i := 0 to ActionList1.ActionCount - 1 do //分配权限
begin
if LoginFrm.CDSLimit.Locate('功能ID', TAction(ActionList1.Actions[i]).Name, [loPartialKey]) then
begin
TAction(ActionList1.Actions[i]).Enabled := LoginFrm.CDSLimit.FieldByName('Enabled').AsBoolean;
TAction(ActionList1.Actions[i]).Visible := LoginFrm.CDSLimit.FieldByName('Visible').AsBoolean;
ActName.Add(TAction(ActionList1.Actions[i]).Name);//加入功能ID
OperaID.Add(LoginFrm.CDSLimit.FieldByName('操作标识').AsString);//加入操作标识
end;
end;//----------------------------菜单效果------------------------------------------ if LoginFrm.Grade = '0' then //超级管理员固定权限
begin
mmMenuInit.Visible := True; //功能初始化
mmPopGroup.Visible := True; //权限组功能分配
ActOperAssign.Visible := True; //操作员权限分配
ActOperAssign.Enabled := True;
ActSysLogQry.Visible := True; //操作员权限分配
ActSysLogQry.Enabled := True;
end else
begin
mmMenuInit.Visible := false;
mmPopGroup.Visible := false;
end; Ks := False;
Ms := False; for I := 0 to MainMenu.Items.Count - 1 do //一级菜单
begin
for J := 0 to MainMenu.items[I].count - 1 do //二级菜单
begin
if MainMenu.items[I].Items[J].Count > 0 then //若存在三级菜单
begin
for K := 0 to MainMenu.items[I].Items[J].Count - 1 do //三级菜单
begin
if (MainMenu.items[I].Items[J].Items[K].Visible) and
(MainMenu.items[I].Items[J].Items[K].Caption <> '-') then
begin
Ks := True;
Break; //在三级菜单中若存在Visible为True则跳出循环
end;
end;
MainMenu.items[I].Items[J].Visible := Ks;
if Ks then Ms := True;
Ks := False;
end else
if (MainMenu.items[I].Items[J].Visible) and
(MainMenu.items[I].Items[J].Caption <> '-') then
begin
Ms := True; //在二级菜单中若存在Visible为True则主菜单可见
end;
end;
MainMenu.items[I].Visible := Ms;
Ms := False;
end;//-------------------------------快捷菜单效果----------------------------------- TlbLen := 0;
j:=0;
k:=0;
for i := 0 to ToolBar1.ButtonCount - 1 do
begin
if ToolBar1.Buttons[i].Visible then
begin
if (j=0)and(ToolBar1.Buttons[i].Style=tbsSeparator) then
ToolBar1.Buttons[i].Visible:=false //屏蔽分割快捷按钮
else
begin
if ToolBar1.Buttons[i].Style=tbsSeparator then inc(k);
if k=2 then //如果连续排列两个分割快捷按钮
begin
ToolBar1.Buttons[i].Visible:=false; //屏蔽分割快捷按钮
k:=1;
end else
begin
TlbLen:=TlbLen+ToolBar1.Buttons[i].Width;
inc(j);
end;
end;
end;
end;
CoolBar1.Bands[0].Width := TlbLen + 15;//15这个值是个校正值,可能不适合你
//
end;在每个Action的执行代码中,额外加入以下代码procedure TMainFrm.ActWareBuyPlanExecute(Sender: TObject);
begin
CurrentOperaID:=OperaID[ActName.IndexOf(TAction(Sender).Name)];//取得当前操作员当前模块的操作标识
....
end;全局函数://解析操作标识
function ParseOperaID(const AoperaID:string;index:integer):Boolean;
var
TmpPos:integer;
begin
TmpPos:=Index+1;
if Index<1 then TmpPos:=2; //把Index固定在1..5之间
if Index>5 then TmpPos:=6;
Result:=Copy(AoperaID,TmpPos,1)=1;
end;使用方法例如:BtnAdd.Enable:=ParseOperaID(CurrentOperaID,1);//增加
BtnModi.Enable:=ParseOperaID(CurrentOperaID,2);//修改
BtnDel.Enable:=ParseOperaID(CurrentOperaID,3);//删除建议使用按钮的Tag属性-------------------------------------------------------------------------------------------------与之相关的功能列表:1、系统功能初始化:2、权限组功能分配:3、操作员功能分配:限于篇幅,源代码不再贴出,都是简单的数据库操作。注意一点: 操作标识的显示问题,//总不能把‘100110’显示出来吧
最后一段代码:
在数据集字段的OnGetText事件中:var
Str:string;
begin
if ParseO
解决方案 »
- webservice客户端内存泄漏问题
- 应届毕业生求delphi工作
- 尋找打開UG\PROE\SOILDWORKS文件的方法,急用!!!
- 一个指针的问题,初学指针,请高人指教
- 怎么才能实现把excel表格导入到access数据库中,而且字段名最好也一块导入,请问各位高手有没有什么办法?
- 如何改变自绘制按纽的鼠标形状?
- DELPHI解释器问题
- 数据库与表格问题!急! 在线!
- 问题:异常类和自定义异常类构造函数的实现代码写在程序的什么部位?
- 想用DELPHI的内嵌汇编仿CIH做一个文件处理钩子!遇到难题!高手来看那!此问题极有价值。
- 为什么我用ADOQuery.Delete;删除当前记录后,再查询还是会出现那条删除了的记录,怎么回事?
- 打包问题?
[email protected]
谢谢了!
[email protected]
万分感谢!!
[email protected]
[email protected]
发布源码的主要目的是为了识别其中的缺陷,以及寻求更好的解决方案!
Str:string;
begin
if ParseOperaID(Sender.AsString,1) then Str:='增加';
if ParseOperaID(Sender.AsString,2) then
if Str='' then Str:='修改' else Str:=Str+',修改'; .... Text:=Str;
end;
等待中
[email protected]
[email protected]
另外我想看看你的窗体以及控件的配置,谢谢。
用户可以根据自已喜欢的方式组织自己的功能菜单结构,可以增加新的菜单,当然这个新的功能菜单可以由用户指定去调用外部的某个EXE文件.比何计算器等一些小工具,这样用户使用起来会更加方便!
谢谢~~~~~
E:[email protected]
我也要一份
[email protected]
[email protected]
[email protected]
我也要一份
[email protected]
[email protected]
能说明一下:
操作员权限中的“功能ID”和系統功能中的“功能ID”各是什么作用吗??
另其中的“标志”又是什么作用呢?
系統功能中的“功能ID”:所有系统的功能操作员中的“标志”:命名不太确切,确切的说应该是状态,“可用/作废”
权限组中的“标志”:“系统定义/用户定义”,我在程序中规定,系统定义
的权限组只可以更名,用户定义的权限组可任意操作,系统定义的权限组
是在初始化时生成的。
谢谢
谢谢!
[email protected]
[email protected]请楼主无比发给我一份,谢谢
[email protected]
谢谢
[email protected]
To: 407107() ;我正在做树型菜单的权限控制,你能给些参考或意见吗?
谢谢
您的1.0a出现的时候一定全力测试。
[email protected]