visitor (0 QPoints)
  • FR
  • EN
  • NL
  • DE
  • ES
315 experts, 1193 registered users, 1659 questions already answered
European Experts Exchange, the very best site for high-quality IT solutions

New Improved Search!

 


05/10/2011 1h30 : Steve Jobs is dead, the father of Apple ][ is gone, we are all orphaned.

Languages :: Delphi :: TPageControl click


By: VB guy Canada  Date: 07/02/2003 00:00:00  English  Points: 25 Status: Answered
Quality : Excellent
How can I find out what tab was clicked in the
OnChanging event so I can determine if I want to allow access to that
page?

Thanks.
VBG
By: VGR Date: 07/02/2003 08:28:00 English  Type : Answer
PageControl1.ActivePage.TabIndex

(I guess it starts from 0)
By: sumotimor Date: 07/02/2003 08:51:00 English  Type : Comment

VGR,
That will give the current page, not the page that is going to be active next.

Avi,
Unfortunately,
the OnChanging event (which got fired from a WM_NOTIFY message
containing TCN_SELCHANGING) does not contain the index of the tab that
WILL BE made active. It won't be until after the OnChange fires that
the ActiveTabIndex can tell you this, then it's too late. You might
rethink this; perhaps by disabling the tabs that should not be allowed
to be made active at the current state in your program.

sumotimor


By: VB guy Date: 08/02/2003 16:00:00 English  Type : Comment
The problem is that when a TabSheet enabled property is set to false,
its content is still displayed when the user selects the disabled tab.
The only way around that is to set the Visible property of a TabSheet
to False, but that looks rather strange. It would have been much nicer
if it was possible to trap the click event for the tab the user is
trying to access and at that point make the decision. or better yet if
the enabled state of the tab simply grayed it out and not respond to
user clicks...
Any suggestions?

VBG
By: VGR Date: 08/02/2003 18:12:00 English  Type : Comment
I don't agree

in my program (D4.01), in the OnChanging event handler of the TPageControl component, I do :
-memory operation of the current "page"(tab) to save it With gPages[locNumPage] Do.
-loading the desired page(tab) via LoadPage(PageControl1.ActivePage.TabIndex+1)

and it works, so...


I'll just show you the procedure that does LoadPage(index), perhaps it'll help you :

Procedure ChargePage(index : Word); // numéro DE LA PAGE (=index +1)
Var j : Byte;
i : Integer; //VGR25082002 fond en clair
Begin
If (index=0) Then locNumPage:=1 Else locNumPage:=index;
If locNumPage>gPnb Then // initialisation page locNumPage
Begin
//traces
// ShowMessage('initialisation page '+IntToStr(locNumPage));
//
With gPages[locNumPage] Do
Begin
NbImages:=0;
codetype:=gAtype;
nbi:=gAnbi;
nbl:=gAnbl;
codecadre:=gAvalcadre;
codefond:=gAvalfond;
For j:=1 to cMaxImgPage Do indexFichiers[j]:=0;
End;
Inc(gPnb);
locNumPage:=gPnb;
If (locNumPage<>1) Then // cas particulier (onglet toujours créé à l'init.)
Begin
With TTabSheet.Create(Etape3.PageControl1) do
Begin
PageControl := Etape3.PageControl1;
Name := 'ts' + IntToStr(locNumPage);
Caption := 'page' + IntToStr(locNumPage);
PopUpMenu := Etape3.PopupMenu2;
End;
Inc(globNbTabs);
//traces
// ShowMessage('ajout page '+IntToStr(locNumPage));
//
End; // création nouvel onglet
Etape3.PageControl1.ActivePage:=Etape3.PageControl1.Pages[locNumPage-1];
Etape3.Panel1.Parent:=Etape3.PageControl1.ActivePage;
End
Else Begin // chargement normal
//traces
// ShowMessage('mémorisation de page '+IntToStr(locNumPage));
//
//VGR070602 ADDed code de non-création si existe en mémoire
If locNumPage>globNbTabs Then
Begin
With TTabSheet.Create(Etape3.PageControl1) do
Begin
PageControl := Etape3.PageControl1;
Name := 'ts' + IntToStr(locNumPage);
Caption := 'page' + IntToStr(locNumPage);
PopUpMenu := Etape3.PopupMenu2;
End;
Inc(globNbTabs);
End;
Etape3.PageControl1.ActivePage:=Etape3.PageControl1.Pages[locNumPage-1];
Etape3.Panel1.Parent:=Etape3.PageControl1.ActivePage;
End; // init ou chargement
// positionnement des contrôles (si modifiable ;-)
Etape3.ListBox2.ItemIndex:=gPages[locNumPage].codetype;
cSpinChange:=False;
Etape3.SpinEdit1.Value:=gPages[locNumPage].nbl;
Etape3.SpinEdit2.Value:=gPages[locNumPage].nbi;
cSpinChange:=True;
//VGR25082002 MODification des fonds, plus d'index (noms de fichier en clair)
//was : Etape3.ComboBox1.ItemIndex:=gPages[locNumPage].codefond;
i:=-1;
Repeat Inc (i); Until Etape3.ComboBox1.Items=TrueFileName(gPages[locNumPage].codefond);
Etape3.ComboBox1.ItemIndex:=i;
//EoMod
Etape3.ComboBox2.ItemIndex:=gPages[locNumPage].codecadre;
If gPages[locNumPage].codetype=0 Then
Begin
Etape3.SpinEdit1.Enabled:=True;
Etape3.SpinEdit2.Enabled:=True;
Etape3.Label7.Enabled:=True;
Etape3.Label8.Enabled:=True;
Etape3.Label1.Enabled:=True;
Etape3.SpinEdit1.SetFocus;
End
Else Begin
Etape3.SpinEdit1.Enabled:=False;
Etape3.SpinEdit2.Enabled:=False;
Etape3.Label7.Enabled:=False;
Etape3.Label8.Enabled:=False;
Etape3.Label1.Enabled:=False;
End;
// retracé
Retrace;
End; // ChargePage Procedure

By: sumotimor Date: 10/02/2003 09:41:00 English  Type : Comment

VGR,

On D3, the following code

procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean);
begin

ShowMessage(IntToStr(PageControl1.ActivePage.TabIndex));

end;

ends up showing the current page index, not the newly selected page index. On D5,

procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean);
begin

ShowMessage(IntToStr(PageControl1.ActivePage.TabIndex));
ShowMessage(IntToStr(PageControl1.ActivePageIndex));

end;

both return the current page as well. I can't say with D4 as I don't have that version...

Avi,
One
"hack" around this is to allow the OnChanging to fire (allow the
change), and then you can determine if the change should be allowed in
the OnChange event. But, you don't want the user to see the tabs change
back/forth during this, so perform a lockwindowupdate() on the page
control (WM_SETREDRAW would be preferred, but unfortunately does not
work on this control).

The key to this working is the fact
that setting ActivePageIndex does NOT fire an OnChanging/OnChange
event, so setting the ActivePageIndex to the old page will not cause
this to fire recursively.

Note: In the example below I used the Tag property to store the old page index, keep it or use your own state variable.

procedure TForm1.PageControl1Changing(Sender: TObject; var AllowChange: Boolean);
begin

// Save off state and allow change to go through
with (Sender as TPageControl) do
begin
Tag:=ActivePage.TabIndex;
LockWindowUpdate(Handle);
end;

end;

procedure TForm1.PageControl1Change(Sender: TObject);
begin

// Determine if we should allow change
with (Sender as TPageControl) do
begin
// Example of disallowing change when the selected
// page index was 0 or 2
if (ActivePage.TabIndex in [0, 2]) then ActivePage:=Pages[Tag];
// Update the page control
LockWindowUpdate(0);
Invalidate;
end;

end;

The
last note in regards to handling tabs this way is that keyboard tab
page switching gets broken. Meaning, using the right/left arrow key
will work until it hits a tab that you don't allow access on. Remember,
the OnChanging was actually designed to stop focus from leaving a tab,
not for determining if focus should/should not be allowed on a specific
tab.

sumotimor


By: VGR Date: 10/02/2003 09:48:00 English  Type : Comment
I'm using D4 for that project. Did not test it under an other compiler. Strange that such things do vary ;-)

Do register to be able to answer

EContact
browser fav
page generated in 295.135970 milliseconds

Why Google AdSense ads ?

compteur
 Ranking-Hits PageRank for this page