線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1906
推到 Plurk!
推到 Facebook!

关于权限设置的代码问题

答題得分者是:malanlk
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-07-26 21:34:40 IP:222.184.xxx.xxx 未訂閱
我现在已经编好了两个数据表,一个是用户功能表,字段有用户名和功能号, 一个是功能表,字段有功能号和功能名(功能名包括菜单上的所有菜单项,并且一模一样)用户登录时检查密码等反正已做好了,我想要的功能是,用户登录后检查用户功能表,有这个功能号的,相对应的菜单就可用,反之则不能用,并且包括主窗口中的快捷按钮的限制。哪位大大能给出相应的代码指点小弟一下。谢谢!
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-07-27 08:48:19 IP:203.69.xxx.xxx 未訂閱
TheGlobalFunctionNameList: TStringList;
...
LoginForm.Create;
LoginForm.ShowModal
try 
  if LoginForm.Result=Pass then
  begin
    TheGlobalFunctionNameList.Clear;
    TheGlobalFunctionNameList.Assign(LoginForm.FunctionNameList);
    if Form001.Visible then
      PostMessage(Form001.Handle,WM_SET_MENU_BY_FUNCTION_NAME_LIST,0,0);
    if Form002.Visible then
      PostMessage(Form002.Handle,WM_SET_MENU_BY_FUNCTION_NAME_LIST,0,0);
    ....
  end
  else
    PostMessage(Application.Handle,WM_QUIT,0,0);
finally
  LoginForm.Free;
end;
上面提供一個初步的架構 解說如下: 1. TheGlobalFunctionNameList 是全域變數, 在 Initialization/Finalization中建立及釋放 2.Login 成功後, 將可以用的功能名稱放入TheGlobalFunctionNameList 3.在其他 Form 的 OnShow 中依TheGlobalFunctionNameList 決定各 MenuItem 是否可用 (如果用 TActionList 元件控管更簡單) 4.如果 其他 Form 出現後才進行 Login, LoginForm 就會送出 WM_SET_MENU_BY_FUNCTION_NAME_LIST 給各 Form, 而各Form收到訊息後就會依TheGlobalFunctionNameList 決定各 MenuItem 是否可用. WM_SET_MENU_BY_FUNCTION_NAME_LIST 是我隨意取的自訂訊息. 發表人 - malanlk 於 2005/07/27 08:53:35
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-07-27 12:20:10 IP:222.184.xxx.xxx 未訂閱
这样的方案小弟的理解是:数据表中的字段记录存不存在没有关系了,因为代码中没有查找数据表中的功能来结合显示相应的菜单,而是固定死了哪些窗口可以跳出,不知道我的理解是否正确,如果正确的话,我想要做一个动态的,就是数据表中有什么功能,相应的哪个菜单或按钮才好用。
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-07-27 12:51:55 IP:203.69.xxx.xxx 未訂閱
抱歉, 你的理解不正確..... 我只是提出個架構, 我是假設你應該可以自己實作 LoginForm, 在LoginForm 你就可以連接數據庫, 找出使用者可以用的功能, 放到FunctionNameList內給呼叫 LoginForm 的程序讀取這個使用者可以用哪些功能. 所以我的代碼將 FunctionNameList Copy 到 TheGlobalFunctionNameList, 希望 所有應該限制功能的 Form 都能看到 TheGlobalFunctionNameList. 而進一步做設定. "使用者可用的功能"(有依數據庫只選出可用的功能哦)-->LoginForm.FunctionNameList-->TheGlobalFunctionNameList LoginForm.FunctionNameList 可以不必這樣做, 我只是順便做個封裝, 這樣LoginForm 就不會跟 TheGlobalFunctionNameList 掛鉤, 自由度比較高....
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-07-27 14:51:55 IP:222.184.xxx.xxx 未訂閱
前辈的思路我明白了,但小弟实际操作因相关知识掌握不全而实现不了。
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-07-27 15:51:53 IP:203.69.xxx.xxx 未訂閱
八股一下, 知不知, 是知也. 慢慢做, 把做不出來的拆開來請教大家, 各位大大都會熱心回答的...
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-07-27 15:54:36 IP:222.184.xxx.xxx 未訂閱
小弟摸索了半天,发现很多文章推荐用ActionList做权限上面的设置。我现在已经将所有的菜单的按钮连到ActionList上了,下面我没掌握的就是如何从用户权限表中(含用户名和功能编号)找到相应的功能,然后让ActionList1中的相应的ITEM做相应操作。
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-07-27 16:18:43 IP:203.69.xxx.xxx 未訂閱
那你知道 PostMessage 自訂訊息是如何做的吧?
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-07-27 16:28:55 IP:222.184.xxx.xxx 未訂閱
引言: 那你知道 PostMessage 自訂訊息是如何做的吧?
小弟对这个不太懂,依我的想法,(当然我不知道是否对)我在用户登录窗口中做这样的操作:查找用户权限表中的用户名等于登录用户名的,后把把所有的功能号列出来。比如说查到了如下结果,功能号有11 13 22 42 ,那么ActionList和11 13 22 42 相对应的项目).Enable:=True;
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-07-27 17:03:13 IP:203.69.xxx.xxx 未訂閱
查到功能號就將功能號組成字串 sEnabledFunc := ',11,13,22,42,'; 然後將 各 ActionList中的 Action1.Tag=(Action1對應的功能號)    如此一來  Action1.Enabled := (Pos(','+IntToStr(Action1.Tag)+',',sEnabledFunc)>0); Action2.Enabled := (Pos(','+IntToStr(Action2.Tag)+',',sEnabledFunc)>0); .... 也可以用 For Loop:    
for i:=0 to ActionList.ActionCount-1 do
begin
    TAction(ActionList1.Actions[i]).Enabled := ....ActionList.Actions[i].Tag....
end;
這應該可以自己完成吧? 發表人 - malanlk 於 2005/07/27 17:09:18
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-07-27 17:37:11 IP:222.184.xxx.xxx 未訂閱
因小弟初学入门,所以还是只能一知半解,我再慢慢摸索
------
我的编程起步于ktop,我将永远支持ktop
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-07-27 17:58:44 IP:222.184.xxx.xxx 未訂閱
我登录时的第一步查询代码如下: ADOQuery1.Close; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('select 功能号 from tb_yhgnb where 用户名=:用户名'); ADOQuery1.Parameters.ParamByName('用户名').Value:=ComboBOX.Text; ADOQuery1.Open; 然后不知道下一步如何利用该结果和ACTIONLIST去比较。 我用文字讲一下我的构思,哪位前辈用代码帮我表达出来: ADOQuery1.Open; if adoquery1.recordcount>0 then begin while not adoquery1.eof do if adoquey1查出的功能号:=11 then actionlist中的相对应的某项目:=可用 if adoquey1查出的功能号:=12 then actionlist中的相对应的某项目:=可用 ........ 把所有可能的功能号都写上。 不知构思是否对,对的话完整的代码如何写? 發表人 - ntjrr 於 2005/07/27 18:22:49
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-07-27 18:43:49 IP:203.69.xxx.xxx 未訂閱
ActionList.Actions[0]...[n] 就是 ActionList之內的項目, 每個 ActionList內的項目都有 Tag 這個 property 可以供設計者自由運用, 我就是利用 Tag 來記下對應的功能號.    如此ㄧ來 TAction(ActionList.Actions[i]).Tag 就對應到唯一的功能號    所以依你的方式來寫:
for i:=0 to  ActionList.ActionCount-1 do
begin //所有功能都關掉
  TAction(ActionList.Actions[i]).Enable := False;
end;    if adoquery1.recordcount>0 then
begin
  while not adoquery1.eof do
  begin
    for i:=0 to ActionList.ActionCount-1 do
    begin
      if TAction(ActionList.Actions[i]).Tag=adoquey1查出的功能号 then
      begin //找到對應的功能項目了
        TAction(ActionList.Actions[i]).Enable := True;
        break;
      end;
    end;
    adoquery1.Next;
  end;
end;
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-07-27 21:00:29 IP:222.184.xxx.xxx 未訂閱
begin ADOQuery1.Close; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('select 功能号 from tb_yhgnb where 用户名=:用户名'); ADOQuery1.Parameters.ParamByName('用户名').Value:=ComboBOX.Text; ADOQuery1.Open; if ADOQUery1.RecordCount>0 then begin while not ADOQUery1.Eof do begin for i:=0 to zjmform.ActionList1.ActionCount-1 do begin if TAction(zjmform.ActionList1.Actions[i]).Tag :=adoquey1查出的功能号 then begin TAction(zjmform.ActionList.Actions[i]).Enable := True; break; end; end; ADOQuery1.Next; end; end; [/quote] 就差在这一句过不了关了,其它基本理解了 if TAction(zjmform.ActionList1.Actions[i]).Tag :=adoquey1查出的功能 问题1. 显示Undeclared identifier: 'TAction' 问题2. adoquey1查出的功能这一句到底写什么,是我所说的11 12 13 之类的一个一个写吗,还是ADOQUERY1.什么的,怎么个写法呢
------
我的编程起步于ktop,我将永远支持ktop
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-07-27 21:23:03 IP:61.219.xxx.xxx 未訂閱
在檔案前面的 uses 裡面加一個 ActnList 就是 
uses 
   Windows, Messages, SysUtils....., ActnList;
因為 TAction 這個 Class 是在 ActnList.pas 這個檔案定義的, 欲得知 Class 在何處定義可以 用 Help 查 TAction , 查到的內容前面會有粗體字 Unit xxxxx 就是表示你查的東東 是在 xxxxx 中定義. TAction(zjmform.ActionList1.Actions[i]).Tag :=adoquey1.FieldByName('功能號').AsInteger; 應該說. 差ㄧ行啊, 我就幫你寫完了....
ntjrr
高階會員


發表:240
回覆:312
積分:110
註冊:2005-04-24

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-07-27 21:33:05 IP:222.184.xxx.xxx 未訂閱
感谢malanlk前辈耐心的指点,由于小弟技术没学到家,麻烦您指点了这么细,再一次感谢您!
------
我的编程起步于ktop,我将永远支持ktop
系統時間:2024-04-25 21:47:55
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!