delphi 如何允许或禁止用户在页面控件中输入制表符?

rmbxnbpk  于 2023-01-20  发布在  其他
关注(0)|答案(5)|浏览(144)

我想限制用户(基于特殊条件)打开一个标签或不在一个页面控件。即,用户可以点击标签,但它不会显示给他。相反,一条消息将显示给他,“he don't have the access right to see such tab“。
在什么情况下,我应该编写检查代码,什么选项卡属性(TPageControl组件)将允许/阻止用户进入这样的选项卡?

62lalag4

62lalag41#

在理想情况下,您可以从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;

我知道很乱,但它有工作的好处!

ndasle7k

ndasle7k2#

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

krugob8w

krugob8w3#

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

好的,PageControl1.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;
0ejtzxu1

0ejtzxu14#

有时候,最好使用以下方法隐藏不需要的TabSheets:

TabSheetNN.TabVisible:=Somecondition;

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

ukdjmx9f

ukdjmx9f5#

你可以在TPageControl的OnChanging事件中显示tab并有效地禁止更改。你所需要做的就是将AllowChangevar设置为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

相关问题