4

(特別な条件に基づいて)ユーザーがページコントロールでタブを開くかどうかを制限したい。つまり、ユーザーはタブをクリックできますが、表示されません。代わりに、メッセージが彼に「he don't have the access right to see such tab」と表示されます。

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

4

4 に答える 4

7

理想的な世界では、ページの変更をブロックするためにイベントから設定AllowChangeします。ただし、ユーザーが選択しようとしているページを内部から見分ける方法が見つからないため、これは実行可能ではないようです。FalseOnChangingOnChanging

基礎となる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;

私が知っているかなり厄介ですが、それは働くことの美徳を持っています!

于 2011-12-05T11:06:48.617 に答える
3

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

于 2011-12-05T19:29:40.580 に答える
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;
于 2011-12-05T10:57:02.897 に答える
0

場合によっては、次のような方法で不要な TabSheet を非表示にすることをお勧めします。

TabSheetNN.TabVisible:=Somecondition;

これらのタブへの切り替えを防止しようとするよりも。確かに、OnChanging イベントの Sender が TPageControl ではなく TabSheet である方がよいでしょう。

于 2014-07-24T16:38:17.493 に答える