Guaranteed order TTabsheets are read from TPageControl thru Controls[]

Posted on 2011-09-28
Last Modified: 2012-06-27
HELP! I asked a similiar question awhile back and am still frustrated with the same issue. I'm writing a generic function that will be used in many forms.

Actually I'm reading all Controls on a form in order (i hope). However, when I get to a certain TPageControl and read it's child controls thru PageContolPtr->Controls(i) I DO NOT get the TTabSheets in order. The PageControl has 4 TTabSheets. For any individual TabSheet I've verified that TabOrder = TabIndex = PageIndex. It is. However using PageContolPtr->Controls(i) it reads Tab0, Tab2, Tab3 and then Tab1. How do I read them Tab0, Tab1, Tab2, Tab3?

Please, can anyone help on this.

Question by:flins
  • 3
  • 3
LVL 16

Accepted Solution

George Tokas earned 500 total points
ID: 36813317
Hello there,
Again a question belongs to C++ Builder topic area.
I don't know if my post will help you but I will mention AGAIN that if this question doesn't attracted my attention as "Neglected Question Alert" I wouldn't post this.
All of us (developers using C++ Builder or Delphi) AND I AM NOT AN EXCEPTION tend to forget very useful properties of the controls we are using.
One of them is the "Tag" property and it is of integer type.
Check out that by default ALL controls you use in the form has Tag = 0.
So "Guaranteed order TTabsheets .."
Set the Tag property of the first TTabSheet a number and increment by one in the next and so on...
It will be good NOT to start with a 0(zero) in order not to mess with other controls, try 100 as a base or whatever number you decide.
Check the Tag property of the tabsheet and you will know which tabsheet it is.

George Tokas.

Author Closing Comment

ID: 36903355
I'm accepting this solution since effort wasn't made by anyone else. The actual solution, and eiither something I don't understand in Borland or a Borland bug, is to save the Form with TabSheet 0 as the active TabSheet. I've since found that if any TabSheet other than TS 0 is active at save time, the TabOrder, TabIndex, etc are meaningless.

Author Comment

ID: 36903413
I'd like to add an additional comment. The Form in question has one PageControl with 4 TabSheets. The TabSheets were created in order TabSheet1, TabSheet2, TabSheet3 and TabSheet4. If TabSheet1 is the active TabSheet when the form is saved, the TabOrder, TabIndex and PageIndex are precisely 0,1,2 and 3 as I would expect. When TabSheet 2 is the active TabSheet at save time, the TabOrder, etc are 0, 3, 1, 2. It makes no sense to me.
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

LVL 16

Expert Comment

by:George Tokas
ID: 36903863
>>It makes no sense to me.
Unfortunately it MAKES SENSE to me...
Thanks for accepting the answer by the way.
The order of tabsheets inside the page control depending on the active page in design phase.
By "default" BCB assumes that YOU WANT this particular tabsheet as the default active one and enumerates the rest in incremental order.
Except the proposal I made to be SURE about the order using the tag property, you can use the following at TForm constructor:
PageControlx->ActivePage = TabSheet1;
This way regardless of the active page is set in design time allways will use TabSheet1 at runtime.
The SAME problem I had some years ago and to tell the true I allways set the first as default in designtime since I didn't use the method you are using.
One more thing: There are not many people here knowing how to use the VCL with C++ Builder but the safer way to get an answer - fast - is to post in C++ Builder topic area..
AT LEAST I will try to help you and I hope and more people.
This question was "Neglected Question Alert" for me via email, but I am monitoring every day the C++ Builder topic area.

George Tokas.

Author Comment

ID: 36906004

I understand your explanation above. However, let me ask the following. Let's call the 4 TabSheets T1 - T4. When T1 is the active page on save, the TabSheet (TabOrder) is T1 = 0. T2 = 1, T3 = 2 and T4 =  3. When T2 is the active page the TabOrder is T1 = 0, T2 = 3, T3 = 2 and T4 = 2. Why? The TabSheets were definifely and absolutely created in the exact order of T1, T2, T3 and T4.
LVL 16

Expert Comment

by:George Tokas
ID: 36908544
Hello again,
I have to dig a bit about this.
I told you that I am not using the method you are using.
I assume that all tabsheets inside the pagecontrol is meant to be used for one task so that is the reason you are "circling" through controls.
This problem appeared to me back in 2005 when a colegue of mine used this way and solved using the tag the way I proposed before. There was a huge mess happened before we realise where was the problem because the application created a data file depending with the order and there were many pagecontrols and tabsheets mostly created at runtime.
Imagine an application controls multiple clients and creates configuration and report files for each one at runtime in a LAN depending on a kind of database.
To save coding space this colegue used circling through controls to find out what group the control had to respond and called the handler. Imagine 100 buttons because that was one of the cases.
So intead of the method he used we set the tag property and retrieve it from "Sender" and used it as parameter. Same used and to pagecontrols panels and more the application had.
This way saved us from using loops when they don't needed and the code was less - and faster -after eliminated check loops.
Now for the tabsheet order I have to dig a bit at the magazine and I will be back.

George Tokas.

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now