如何在页面控制中允许或禁止用户输入选项卡?

发布于 2024-12-19 16:23:26 字数 185 浏览 1 评论 0原文

我想限制用户(基于特殊条件)在页面控件中打开或不打开选项卡。即,用户可以单击该选项卡,但不会向他显示该选项卡。相反,一条消息将向他显示“他没有查看此类选项卡的访问权限”。

在什么情况下我应该编写检查代码,以及什么选项卡属性(TPageControl 组件)将允许/阻止用户进入此类选项卡?

I want to restrict users (based on special condition) to open a tab or not in a page control. ie, the user can click on the tab but it will not be displayed to him. Instead, a message will show to him that "he don't have the access right to see such tab".

On what event I should write the checking code, and what tab property (of TPageControl component) will allow/block user to enter such tab?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

终止放荡 2024-12-26 16:23:26

在理想情况下,您可以从 OnChanging 事件将 AllowChange 设置为 False 以阻止页面更改。然而,这似乎并不可行,因为我无法从 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;

我知道相当混乱,但它有工作的优点!

In an ideal world you would set AllowChange to False from theOnChanging event to block a page change. However, this does not appear to be viable because I can find no way of discerning, from within OnChanging, which page the user is trying to select.

Even looking at the underlying Windows notification seems to offer little hope. The TCN_SELCHANGING notification identifies the control, but not says nothing about the pages involved, so far as I can tell.

The best I can come up with is to use OnChanging to note the current active page and then do the hard work in OnChange. If the selected page has been changed to something undesirable, then just change it back.

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;

Rather messy I know, but it has the virtue of working!

給妳壹絲溫柔 2024-12-26 16:23:26

OnChanging 事件不允许您确定正在选择哪个选项卡,因为 Windows 本身不报告该信息。但是,您可以做的是,子类化 TPageControl.WindowProc 属性,以在处理发送到 TPageControl 之前拦截消息。使用鼠标消息来确定哪个选项卡被直接单击(查看 TPageControl.IndexOfTabAt() 方法),并使用键盘消息来检测左/右箭头按下以确定哪个选项卡与该选项卡相邻。活动选项卡(查看 TPageControl.FindNextPage() 方法)。

The OnChanging event does not allow you to determine which tab is being selected, because Windows itself does not report that information. What you can do, however, is subclass the TPageControl.WindowProc property to intercept messages that are sent to the TPageControl before it processes them. Use mouse messages to determine which tab is being clicked on directly (look at the TPageControl.IndexOfTabAt() method), and use keyboard messages to detect left/right arrow presses to determine which tab is adjacent to the active tab (look at the TPageControl.FindNextPage() method).

当爱已成负担 2024-12-26 16:23:26

使用页面控件的 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;

好的,PageControle1.TabIndex 是活动页面索引,而不是我想要选择的页面索引。
我怎样才能获得点击的页面。

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;

Use the OnChanging event of the page control.

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, the PageControle1.TabIndex is the activepageindex and not the one i want to select.
How can i get the clicked Page.

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;

New Attempt

 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;
坏尐絯 2024-12-26 16:23:26

有时,最好用这样的东西隐藏不需要的选项卡:

TabSheetNN.TabVisible:=Somecondition;

比试图阻止切换到这些选项卡更好。
当然,如果 OnChanging 事件中的 Sender 是 TabSheet 而不是 TPageControl 会更好。

Sometimes it is better just to hide unwanted TabSheets with something like this:

TabSheetNN.TabVisible:=Somecondition;

than trying to prevent switching to these tabs.
Sure, it would be better if Sender in OnChanging event will be TabSheet , not TPageControl.

青萝楚歌 2024-12-26 16:23:26

您可以在 TPageControl 的 OnChanging 事件中显示选项卡并有效禁用更改。您需要做的就是将AllowChange var 设置为False。

procedure TForm1.PageControl1(Sender: TObject; var AllowChange: Boolean); 
begin
    AllowChange := MyCondition;
    if MyCondition
        ShowMessage('User doesn''t have permission to see this tab.');
end

You can show tab and effectively disable changing in OnChanging event of TPageControl. All you need to do is set AllowChange var to False.

procedure TForm1.PageControl1(Sender: TObject; var AllowChange: Boolean); 
begin
    AllowChange := MyCondition;
    if MyCondition
        ShowMessage('User doesn''t have permission to see this tab.');
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文