Solved

Access Tabsheet components by name

Posted on 2000-05-11
9
305 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
9 Comments
 
LVL 3

Expert Comment

by:sburck
ID: 2799747
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
ID: 2799775
Hi, dcl.

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

----
Igor.

PS: still thinking...
0
 
LVL 9

Expert Comment

by:ITugay
ID: 2799790
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:dcl
ID: 2802927
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
 
LVL 1

Author Comment

by:dcl
ID: 2803066
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
ID: 2803614
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
ID: 2806674
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
ID: 2841451
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
ID: 2853827
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Printing problem 2 111
select query - oracle 16 101
Find and Replace Stream with 0s 8 73
Get monday of current week where a week always starts on monday 2 21
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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

726 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