我希望能够根据特定条件限制用户是否可以打开页面控件中的选项卡。也就是说,用户可以点击选项卡,但是不会显示给他。相反,会向他显示一个消息,提示“他没有权限查看此选项卡”。
在哪个事件中编写检查代码?TPageControl
组件的哪个选项卡属性可以允许/阻止用户进入该选项卡?
我希望能够根据特定条件限制用户是否可以打开页面控件中的选项卡。也就是说,用户可以点击选项卡,但是不会显示给他。相反,会向他显示一个消息,提示“他没有权限查看此选项卡”。
在哪个事件中编写检查代码?TPageControl
组件的哪个选项卡属性可以允许/阻止用户进入该选项卡?
OnChanging
事件中将 AllowChange
设置为 False
以阻止页面更改。 但是,这似乎不可行,因为我找不到任何方法可以从 OnChanging
中确定用户正在尝试选择哪个页面。 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;
OnChanging
事件无法确定哪个选项卡正在被选择,因为Windows本身不会报告该信息。但是,您可以子类化TPageControl.WindowProc
属性以拦截发送到TPageControl
的消息,然后再处理它们。使用鼠标消息直接确定点击了哪个选项卡(查看TPageControl.IndexOfTabAt()
方法),并使用键盘消息检测左/右箭头按键以确定活动选项卡旁边的选项卡(查看TPageControl.FindNextPage()
方法)。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;
procedure TForm1.PageControl1(Sender: TObject; var AllowChange: Boolean);
begin
AllowChange := MyCondition;
if MyCondition
ShowMessage('User doesn''t have permission to see this tab.');
end
TabSheetNN.TabVisible:=Somecondition;
与其试图阻止切换到这些选项卡,不如将OnChanging事件中的Sender设置为TabSheet,而非TPageControl,这样会更好。