Solved

Access Tabsheet components by name

Posted on 2000-05-11
9
297 Views
Last Modified: 2010-04-04
I need to make a page control class I can re-use in several places.  It will also have several very similar pages on it, so I am tryng to make a TabSheet class for the page control.

The only difference between copies of the tabsheet on the page control is the numbering of some labels.  The first page contains labels 1-32, the second 33-64 etc.

I tried this code to access the labels & change their captions.
{pintOffSet is an integer parameter.
 intLabelRight is defined earlier, used to align the right-hand side of all the labels}

for intLoop := 1 to 32 do
begin
  lblThislabel := FindComponent('lblSession' + IntToStr(intLoop));
    with lblThislabel do
    begin
      caption := IntToStr(intLoop + pintOffSet) + ':';
      left    := intLabelRight - width;
    end;

Instead of changing the captions of the label controls, it is changing the TabSheet caption. What am I doing wrong?

Here is more details code if you want it.  First is the complete method that changes the captions, & second is the method on the pagecontrol that adds the tab sheets

New method on TabSheet:
-----------------------

procedure tbsTreatmentPage.SetLabelOffset(pintOffSet: integer);
{Assigns the labels new captions, based on the OffSet specified
 eg to start at 33, pass pintOffSet = 32}
var intLoop, intLabelRight: integer;
    lblThislabel: TComponent;
    {intLoop:        Loop counter
     intLabelRight:  .Right value for this label
     lblDCLLabel:    Reference to the label we are working with}
begin
  for intLoop := 1 to 32 do
  begin
    case intLoop of
       1..8:  intLabelRight := kLabelCol1Right;
       9..16: intLabelRight := kLabelCol2Right;
      17..24: intLabelRight := kLabelCol3Right;
      25..32: intLabelRight := kLabelCol4Right;
    end;
    lblThislabel := FindComponent('lblSession' + IntToStr(intLoop));
    with lblThislabel do
    begin
      caption := IntToStr(intLoop + pintOffSet) + ':';
      left    := intLabelRight - width;
    end;
  end;        
end;

Called from this method on Page Control
---------------------------------------
procedure pgcTreatment.WndProc(var MSG : TMessage);
begin
  inherited;
  if (MSG.MSG = CM_PARENTCTL3DCHANGED)
     and (tbsPage1 = nil) then  // prevent duplicate initialization
  begin
    tbsPage1 := tbsTreatmentPage.create(Self);
    with tbsPage1 do
      begin
        PageControl := Self;
        Caption     := 'Sessions 1 - 32';
       end;
    tbsPage2 := tbsTreatmentPage.create(Self);
    with tbsPage2 do
      begin
        PageControl := Self;
        Caption     := 'Sessions 33 - 64';
        SetLabelOffset(32);  // Change labels to 33-64
       end;
  end;    // If we want to add the pages
end;

0
Comment
Question by:dcl
  • 4
  • 4
9 Comments
 
LVL 3

Expert Comment

by:sburck
Comment Utility
I tried running your code, it was even worse - just disappeared.  But I fixed the line which read:

with lblThisLabel do

to

with (lblThisLabel as TLabel) do

It should probably work for your problem as well.  I'm actually surprised it compiles - TComponent.Caption isn't well defined.
0
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
Hi, dcl.

At first look FindComponent('lblSession' + IntToStr(intLoop)) returns TTabSheet instead TLabel.  

----
Igor.

PS: still thinking...
0
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
OK, I get it. The problem is:

 lblThislabel: TComponent;

TComponent has no Caption and WITH operator doesn't work like you expect. It change caption for your TabSheet.

-----
Igor.
0
 
LVL 1

Author Comment

by:dcl
Comment Utility
Igor,

I also have a problem with this code you gave me for my last question.

if (MSG.MSG = CM_PARENTCTL3DCHANGED)
     and (tbsPage1 = nil) then  // prevent duplicate initialization
  begin
    tbsPage1 := tbsTreatmentPage.create(Self);
    with tbsPage1 do
      begin
        PageControl := Self;
        Caption     := 'Sessions 1 - 32';
       end;
   
Each time I open the form to modify it, another page appears, so I end up with 3 or 4 identical pages
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:dcl
Comment Utility
sburck

I tried your suggestion, but now I get an Access Violation when I add the PageControl compoent to the form.
0
 
LVL 9

Expert Comment

by:ITugay
Comment Utility
dcl,
Ok, let me some time, I should try work out your points today;)
-----
Igor.
0
 
LVL 9

Accepted Solution

by:
ITugay earned 100 total points
Comment Utility
Hi dcl,
It seems to me I found the way. To check this you need to drop this control on form. Then drop TLabel : label1 on first or second page. The small part of code how to change label caption included. Use Parent.FindComponent instead simply FindComponent.

unit MYPAGCTRL;

interface

uses windows, classes, comctrls, messages, dialogs, stdctrls;

type
  TMyTabControl = class(TPageControl)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
    procedure WMCreate(var Message: TWMCreate); message WM_CREATE;
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure TMyTabControl.WMCreate(var Message: TWMCreate);
var T : TComponent;
begin
   Inherited;
   if PageCount = 0 then
   begin
     with TTabSheet.Create(Self) do
     begin
       Parent := Self;
       PageControl := Self;
       Caption := '1';
       Name    := 'page1';


       InsertControl(TLabel.Create(self));
     end;
     with TTabSheet.Create(Self) do
       begin
       Parent := Self;
       PageControl := Self;
       Caption := '2';
       Name    := 'page2';
     end;
   end;

   // how to change label caption which is in one of page
   T:=Parent.FindComponent('label1');
   if T <> nil
      then (T as TLabel).Caption:='-1-';
end;

procedure Register;
begin
  RegisterComponents('Samples', [TMyTabControl]);
end;


// remove this section if you have dropped down pages
// on your page control in design mode.
initialization
  RegisterClass(TTabSheet);  
end.

----
Igor.
0
 
LVL 1

Author Comment

by:dcl
Comment Utility
Hi there

Good & Bad news.

First, I have fixed my original problem myself, after trying your sugestions.  
I have given you the points for the WMCreate() part, which fixed the problem I mentioned, & also for the note about the initialize section, which I was about to ask you about.

For my original problem, FindComponent() was not locating the labels I wanted to modify because I had not assigned them names.  I thought that declaring them as var's of the class was the same as giving them names, but it is not, so now I set the name property it works fine.  (I also put all the controls onto a panel instead of directly on the Tab Sheet, but I don't think that is relevant now I have found the name problem.)

Problem:  I changed the PageControl to use WMCreate() to add the pages.  It has fixed the problem of pages appearing twice, but I have another problem.  When I drop the pagecontrol on the form, page 2 renumbers nicely, but the next time I open (or run) the form, the renumbering does not occur, & the captions have reverted to their original values.


It now looks like this.

procedure pgcTreatment.WMCreate(var Message: TWMCreate);
begin
  inherited;
  if PageCount = 0 then
  begin
    tbsPage1 := tbsTreatmentPage.Create(Self);
    with tbsPage1 do
    begin
      {Parent      := Self;}
      PageControl := Self;
      Caption     := 'Sessions 1 - 32';
    end;
    tbsPage2 := tbsTreatmentPage.Create(Self);
    with tbsPage2 do
    begin
      {Parent      := Self;}
      PageControl := Self;
      Caption     := 'Sessions 33 - 64';
      SetLabelOffset(32);  // Change labels to 33-64
    end;
end;


SetLabelOffset works fine when I drop the pagecontrol on the form, but it's affect has vanished when I reopen the form, or run it.
0
 
LVL 1

Author Comment

by:dcl
Comment Utility
Hi again.

I have fixed the problem of the renumbering not working properly.  I created a "Page 2" class, which was identical to the normal "Page" class, except it ran SetLabelOffset() in it's constructor.  I used this in the page control as follows.

The PageControl looks like this:

  pgcTreatment = class(pgcDCLPageControl)
    tbsPage1: tbsTreatmentPage;
    tbsPage2: tbsTreatment2ndPage;

WMCreate is like this...
    tbsPage1 := tbsTreatmentPage.Create(Self);
....
    tbsPage2 := tbsTreatment2ndPage.Create(Self);
....

The Page 2 class is like this:
type
  tbsTreatment2ndPage = class(tbsTreatmentPage)
....
constructor tbsTreatment2ndPage.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  SetlabelOffset(32);
end;         // Create()

So this is working fine now.
But don't relax - I'm sure I will find heaps more problems very soon!


0

Featured Post

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

Join & Write a Comment

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

762 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

9 Experts available now in Live!

Get 1:1 Help Now