2011-12-05 4 views
4

特殊な条件に基づいてユーザーを制限して、ページコントロール内のタブを開くかどうかを決めたいとします。すなわち、ユーザはタブをクリックすることができるが、タブには表示されない。代わりに、 "he don't have the access right to see such tab"というメッセージが表示されます。pagecontrolにタブを入力するのを許可または禁止するにはどうすればいいですか?

どのような場合にチェックコードを書く必要がありますか、どのタブのプロパティ(TPageControlコンポーネント)でユーザーがそのようなタブに入ることを許可/ブロックするのですか?

+4

ユーザーがコンテンツをとにかく見ることができない場合、最初にタブを表示する理由は何ですか? – whosrdaddy

+0

発生しているシナリオをより詳しく説明できますか?次に、セキュリティとGUI標準のベストプラクティスをあなたのタスクに提案することができます。 –

+0

確かに、個人情報、契約情報、家族情報がdiffrenetタブにある従業員画面を設計しています。権限を持つスーパーユーザーは契約情報を見ることができますが、権限の少ない別のユーザーはfamily infのみを表示し、契約のinf(salary、allowancesなど)は編集しないでください。私の人生(そして私の仕事)を救います。ありがとうございました。 – Amanda

答えて

1

ページコントロールのOnChangingイベントを使用してください。

procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean); 
begin 
    if (self.PageControl1.TabIndex= 1)and 
    (NotAllowUser = 'SomePerson') then 
    begin 
    AllowChange:= False; 
    ShowMessage('Person not allow for this Tab'); 
    end; 
end; 

[OK]を、PageControle1.TabIndexはactivepageindexはなく、私が選択したいものです。 クリックしたページはどうすれば入手できますか?理想的な世界では

procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean); 
var 
    P: TPoint; 
    NewTabIndex: Integer; 
begin 

    P := PageControl1.ScreenToClient(Mouse.CursorPos); 
    NewTabIndex := PageControl1.IndexOfTabAt(P.X, P.y); 

    if (NewTabIndex= 1) then 
    begin 
    AllowChange:= false; 
    Beep 
    end; 
end; 

新しい試み

TMyPageControl = Class(TPageControl) 
private 
    FNewTabSheet: TTabSheet; 
    FOnMyChanging: TMyTabChangingEvent; 
    procedure SetOnMyChanging(const Value: TMyTabChangingEvent); 
    procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY; 
    procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY; 
protected 
    function CanChange: Boolean; Override; 
public 
    property OnMyChanging: TMyTabChangingEvent read FOnMyChanging write SetOnMyChanging; 
End; 



{ TMyPageControl } 




function TMyPageControl.CanChange: Boolean; 
begin 
    Result := True; 
    if Assigned(FOnMyChanging) then FOnMyChanging(Self, FNewTabSheet ,Result); 
end; 



procedure TMyPageControl.CMDialogKey(var Message: TCMDialogKey); 
begin 
    if (Focused or Windows.IsChild(Handle, Windows.GetFocus)) and 
     (Message.CharCode = VK_TAB) and (GetKeyState(VK_CONTROL) < 0) then 
    begin 
    FNewTabSheet := FindNextPage(ActivePage, GetKeyState(VK_SHIFT) >= 0,True); 
    SelectNextPage(GetKeyState(VK_SHIFT) >= 0); 
    Message.Result := 1; 
    end else 
    inherited; 
end; 

procedure TMyPageControl.CNNotify(var Message: TWMNotify); 
var 
    P: TPoint; 
    NewTabIndex: Integer; 
begin 
    with Message do 
    case NMHdr.code of 
     TCN_SELCHANGE: 
     Change; 
     TCN_SELCHANGING: 
     begin 
      Result := 1; 
      P := self.ScreenToClient(Mouse.CursorPos); 
      NewTabIndex := self.IndexOfTabAt(P.X, P.y); 
      FNewTabSheet:= self.Pages[NewTabIndex]; 
      if CanChange then Result := 0; 
     end; 
    end; 
end; 

procedure TMyPageControl.SetOnMyChanging(const Value: TMyTabChangingEvent); 
begin 
    FOnMyChanging := Value; 
end; 
+0

TabIndexプロパティは、新しく選択したタブではなく、OnChangingイベント中に現在アクティブなタブのインデックスを提供するため、要求どおりに機能しません。 –

+1

悲しいことに、TabIndexはユーザーが選択しようとしているページではなく、現在選択されているページであるため、これは機能しません。 –

+0

ユーザーが望む選択されたPageIndexを取得するようにコードを変更します。 – Ravaut123

7

、ページの変更をブロックするためにOnChangingイベントからFalseAllowChangeを設定します。しかし、ユーザーが選択しようとしているページがOnChangingの範囲内にあるため、わかりやすく見つけることができないため、これは実行可能ではありません。

基本的なWindowsの通知を見てもほとんど希望がないようです。 TCN_SELCHANGING通知はコントロールを識別しますが、私が知る限り、関連するページは何も表示しません。

私が思いつくのは、OnChangingを使って現在のアクティブなページを書き留めてから、OnChangeで頑張ってください。選択したページが望ましくないものに変更された場合は、それを元に戻してください。

procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean); 
begin 
    FPreviousPageIndex := PageControl1.ActivePageIndex; 
end; 

procedure TForm1.PageControl1Change(Sender: TObject); 
begin 
    if PageControl1.ActivePageIndex=1 then begin 
    PageControl1.ActivePageIndex := FPreviousPageIndex; 
    Beep; 
    end; 
end; 

私は知っていますが、それは働くことの美徳を持っています!

+0

self.PageControl1.ActivePageIndex:= 1;のようなコードでdeactPageIndexを変更すると動作しません。 – Ravaut123

+4

@ Ravaut123確かにそうではありません。あなたが書いたコードを制御するので、このようなエラーを避けるのは簡単です。 –

2

イベントでは、Windows自体がその情報を報告しないため、どのタブが選択されているかを判断することはできません。ただし、処理する前にTPageControlに送信されたメッセージを傍受するには、TPageControl.WindowProcプロパティをサブクラス化してください。マウスメッセージを使用してどのタブが直接クリックされたかを確認し(TPageControl.IndexOfTabAt()メソッドを参照)、キーボードメッセージを使用して左右の矢印キーを検出してアクティブなタブに隣接するタブを確認します(TPageControl.FindNextPage()の方法を参照)。

0

時にはそれだけでこのようなものと不要なタブシート隠す方が良いです。これらのタブに切り替えることを防止しようとするよりも、

TabSheetNN.TabVisible:=Somecondition; 

を。 OnChangingイベントのSenderがTPageControlではなくTabSheetになる方が良いでしょう。

関連する問題