Как разрешить или запретить пользователю входить на вкладку в pagecontrol? - PullRequest
4 голосов
/ 05 декабря 2011

Я хочу ограничить пользователей (в зависимости от особых условий), чтобы открывать вкладки или нет в элементе управления страницы. пользователь может нажать на вкладку, но она не будет отображаться для него. Вместо этого ему будет показано сообщение "he don't have the access right to see such tab".

По какому событию я должен написать проверочный код, и какое свойство вкладки (из компонента TPageControl) позволит / заблокирует пользователя войти в такую ​​вкладку?

Ответы [ 4 ]

7 голосов
/ 05 декабря 2011

В идеальном мире вы должны установить AllowChange на False из события OnChanging, чтобы заблокировать изменение страницы.Тем не менее, это не представляется жизнеспособным, потому что я не могу найти, в пределах 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;

Довольно грязно, я знаю, но она имеет силу работы!

2 голосов
/ 05 декабря 2011

Событие OnChanging не позволяет определить, какая вкладка выбирается, поскольку сама Windows не сообщает эту информацию. Однако вы можете создать подкласс свойства TPageControl.WindowProc для перехвата сообщений, отправляемых на TPageControl до их обработки. Используйте сообщения мыши, чтобы определить, на какой вкладке щелкают напрямую (см. Метод TPageControl.IndexOfTabAt()), и используйте сообщения клавиатуры, чтобы обнаружить нажатие стрелок влево / вправо, чтобы определить, какая вкладка находится рядом с активной вкладкой (посмотрите на TPageControl.FindNextPage() метод).

1 голос
/ 05 декабря 2011

Используйте событие 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;
0 голосов
/ 24 июля 2014

Иногда лучше просто спрятать нежелательные Таблицы с чем-то вроде этого:

TabSheetNN.TabVisible:=Somecondition;

, чем пытаться предотвратить переключение на эти вкладки. Конечно, было бы лучше, если бы Отправитель в событии OnChanging был TabSheet, а не TPageControl.

...