?
Solved

Closing Active Tab on PageControl

Posted on 2007-10-18
27
Medium Priority
?
1,024 Views
Last Modified: 2010-04-04
Hi all,

With a PageControl I am creating tabs at runtime and also a speedbutton to with I have assigned an Onclick event.

Right now I have assigned the event to Close but it closes the form.

I need it to close the active Tab instead.

Could you please help?

Thanks

ST3VO
0
Comment
Question by:ST3VO
  • 15
  • 12
27 Comments
 

Author Comment

by:ST3VO
ID: 20101565
Update:

I've tried:

 PageControl.ActivePage.Free;

and it works BUT I get an access violation error.

Any ideas on how to fix this?
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20101605
pagecontrol1.pages[pagecontrol1.ActivePageIndex].Free;
0
 

Author Comment

by:ST3VO
ID: 20101666
Hmmm...It works but when I re-create a tab I get an access violation.

Any ideas?

 
0
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!

 

Author Comment

by:ST3VO
ID: 20101671
I also get an access violation when trying to exit the application :o/

0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20101707
Please show source code of creating a pagetab at runtime.
i'm looking to see if you're creating something that should get freed and doesn't.
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20101782
When you free the active tab, set the active tab to a different tab

procedure TForm1.Button1Click(Sender: TObject);
var
ts: TTabSheet;
Lbl: TLabel;
begin
ts := TTabSheet.Create(Self);
ts.Name := 'DynamicTabSheet';
ts.PageControl := PageControl1;

Lbl := TLabel.Create(ts);
Lbl.Color := clRed;
Lbl.Align := alClient;
Lbl.Parent := ts;
end;

If you want to delete the tabsheet use ts.Free,
but before that make sure that you change the Active Page
to another TabSheet.


===

ALTERNATIVE METHOD

procedure TfrmDlgJob.SpeedButton1Click(Sender: TObject);
begin
  with TTabSheet.Create(Self) do
  begin
    {Assign PageControl1 to the newly created TTabSheet's PageControl
property}
    PageControl := PageControl1;
    Caption := 'Sheet ' + IntToStr(PageIndex + 1);
  end;
end;
0
 

Author Comment

by:ST3VO
ID: 20101798
OK:

OnCreate I add the button like this:

////////////////////////
 ///  Add Close Btn
 ///////////////////////

  Button := TSpeedButton.Create(pctrlWB);
  Button.Parent := pctrlWB;
  Button.Height:=20;
  Button.Width:=20;
  Button.Top := 0;
  Button.left := Screen.Width - Button.Width - 3;
  Button.Visible := True;
  Button.Caption:=('X');
  Button.Cursor:=crhandpoint;
  Button.Hint:=('Close Tab');
  Button.ShowHint:=True;
  Button.OnClick := ClickMe;

////////////////////////////////////////////////////

The Closing event:

procedure TfrmMain.ClickMe(Sender: TObject);

begin
   pctrlWB.pages[pctrlWB.ActivePageIndex].Free;
end;

//////////////////////////////////////////////////////////

Create the Tabs:

function TfrmMain.CreateNewTabBrowser(Url: string): TTabSheet;
begin
   NewTab := TTabSheet.Create(PageControl1);
   with NewTab do
      begin
         PageControl := PageControl1;
         Parent := PageControl1 ;
         Visible := true;
         PageIndex := PageControl1.ActivePageIndex;
      end;
   DesignTimeWB := TEmbeddedWB.Create(NewTab);
   TControl(DesignTimeWB).Parent := NewTab;
   with DesignTimeWB do
      begin
         EnableMessageHandler;
         LoadSettings;
         Align := alClient;
         OnStatusTextChange := NewWebStatusTextChange;
         OnNewWindow2 := NewWindowEvent;
         OnDownloadComplete := DownloadCompleteEvent;
         if (URL) <> '' then
            DesignTimeWB.Navigate(URL);
         DesignTimeWB.Wait;
      end;
   PageControl1.ActivePage := NewTab;
   Result := NewTab;
end;

Hope this help!!!

0
 
LVL 13

Accepted Solution

by:
rfwoolf earned 2000 total points
ID: 20101919
Okay, how about something like this:

procedure TForm1.Button1Click(Sender: TObject);
begin
//If you want to free the active tabsheet, and there's only 1 tabsheet
//then create a tabsheet and free the first one
if pagecontrol1.PageCount = 1 then
  begin
    //PUT THE "CREATE AN EXTRA PAGE" CODE HERE
    pagecontrol1.Pages[0].Free;
    break; //leave this procedure
  end;

//If however you want to free the active tabsheet, and there's more than on tabsheet,
//and the active tabsheet is NOT the last tabsheet in the pagecontrol
if pagecontrol1.ActivePageIndex < (pagecontrol1.PageCount - 1) then
begin
pagecontrol1.ActivePageIndex := (pagecontrol1.ActivePageIndex + 1);
pagecontrol1.pages[pagecontrol1.ActivePageIndex - 1].Free;
end
else
//else if it IS the last tabsheet in the pagecontrol
begin
  pagecontrol1.ActivePageIndex := (pagecontrol1.ActivePageIndex - 1);
  pagecontrol1.pages[pagecontrol1.ActivePageIndex + 1].Free;
end;
end;
0
 

Author Comment

by:ST3VO
ID: 20102064
OK, I've tested it but I still get access violation when re-creating tabs and when trying to exit the application.

I got an error with Break so I changed it to exit.

See below:

procedure TfrmMain.ClickMe(Sender: TObject);

begin


  if PageControl1.PageCount = 1 then
  begin
    //PUT THE "CREATE AN EXTRA PAGE" CODE HERE
    PageControl1.Pages[0].Free;
    exit; //leave this procedure
  end;
       if PageControl1.ActivePageIndex < (PageControl1.PageCount - 1) then
          begin
             PageControl1.ActivePageIndex := (PageControl1.ActivePageIndex + 1);
             PageControl1.pages[PageControl1.ActivePageIndex - 1].Free;
          end
      else
        //else if it IS the last tabsheet in the pagecontrol
          begin
             PageControl1.ActivePageIndex := (PageControl1.ActivePageIndex - 1);
             PageControl1.pages[PageControl1.ActivePageIndex + 1].Free;
          end;
  end;

Why do I get this error anyway?
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20102435
Um, your procedure CreateNewTabBrowser - when and how does that get called?
and what is a TEmbeddedWB - I can't compile and test your code with this line and beyond
0
 

Author Comment

by:ST3VO
ID: 20102602
You can find information about this component here:

http://www.bsalsa.com/downloads.html

It's Free too!

The procedure is called on a buttonClick event!

0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20102703
There's  a major error in the sourcecode you gave me...

You are referring to two pagecontrols:
pctrlWB
and
PageControl1

This frees a tabpage on pctrlWB:
procedure TfrmMain.ClickMe(Sender: TObject);
begin
   pctrlWB.pages[pctrlWB.ActivePageIndex].Free;
end;

BUT this creates a tabpage on PageControl1
function TfrmMain.CreateNewTabBrowser(Url: string): TTabSheet;
begin
   NewTab := TTabSheet.Create(PageControl1);
   with NewTab do
      begin
         PageControl := PageControl1;
         Parent := PageControl1 ;
         Visible := true;
         PageIndex := PageControl1.ActivePageIndex;
      end;
   DesignTimeWB := TEmbeddedWB.Create(NewTab);
   TControl(DesignTimeWB).Parent := NewTab;
   with DesignTimeWB do
      begin
         EnableMessageHandler;
         LoadSettings;
         Align := alClient;
         OnStatusTextChange := NewWebStatusTextChange;
         OnNewWindow2 := NewWindowEvent;
         OnDownloadComplete := DownloadCompleteEvent;
         if (URL) <> '' then
            DesignTimeWB.Navigate(URL);
         DesignTimeWB.Wait;
      end;
   PageControl1.ActivePage := NewTab;
   Result := NewTab;
end;
0
 

Author Comment

by:ST3VO
ID: 20102752
Sorry, that was my own error when posting!

I renamed all (or I thought I did) pctrlWB to PageControl1 to make it easier for you to read!

Sorry about that!!! :o/

0
 

Author Comment

by:ST3VO
ID: 20102843
I really hate using Free :o/

It's always giving errors!!!!

0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20102944
Okay, ignore my procedure that checks how many pages there are before it decides which one to free.
--just use this line:
pagecontrol1.pages[pagecontrol1.ActivePageIndex].Free;

The access violation error seems to come from this line:
   DesignTimeWB.Wait;
Is there any way we can get around using that?
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20102957
When I say the access violation errror seems to come from this line:
   DesignTimeWB.Wait;
I mean, I don't get access violation errors when I remove this line and try to free the tabpages.
I also have trouble closing the application when you use that line.
Check the help file for what the Wait method does - maybe there's something you have to do to cancel it or maybe you don't need it.
0
 

Author Comment

by:ST3VO
ID: 20103046
I commented that line of as I can do without it.

Although I don't get the error when closing tabs I get the error what closing the application and when re-creating tabs :o/

Any ideas? Sorry to be such a pain :o)

0
 

Author Comment

by:ST3VO
ID: 20103102
Have you installed the components then?

0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20103129
When I try it I don't get any access violation errors.

One thing I'm not sure about is your form's OnCreate event...
  Button := TSpeedButton.Create(PageControl1);
  Button.Parent := PageControl1;
The button will not appear because only TTabSheet will appear as a child of a PageControl.
In other words you should make Tbutton the child of a TTabsheet which will be the child of a PageControl.
MY POINT IS, take it out -- see if that is causing an access violation

Like I say I'm not getting an access violation, here is all my source code...
==I add a PageControl and Button onto the form...

function TfrmMain.CreateNewTabBrowser(Url: string): TTabSheet;
var
NewTab : TTabSheet;
DesignTimeWB : TEmbeddedWB;
begin
   NewTab := TTabSheet.Create(PageControl1);
   with NewTab do
      begin
         PageControl := PageControl1;
        Parent := PageControl1 ;
         Visible := true;
    PageIndex := PageControl1.ActivePageIndex;
      end;
   DesignTimeWB := TEmbeddedWB.Create(NewTab);
   TControl(DesignTimeWB).Parent := NewTab;
   with DesignTimeWB do
      begin
         EnableMessageHandler;
         LoadSettings;
        Align := alClient;
{         OnStatusTextChange := NewWebStatusTextChange;
         OnNewWindow2 := NewWindowEvent;
         OnDownloadComplete := DownloadCompleteEvent;}
         if (URL) <> '' then
            DesignTimeWB.Navigate(URL);
//         DesignTimeWB.Wait;
      end;
   PageControl1.ActivePage := NewTab;
   Result := NewTab;
end;

procedure Tfrmmain.Button1Click(Sender: TObject);
begin
   pagecontrol1.Pages[pagecontrol1.ActivePageIndex].Free;
end;

0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20103139
Have you installed the components then?
--yes, I had already had the components installed, but I had never used EmbeddedWB before - I had used TWebUpdater.
0
 

Author Comment

by:ST3VO
ID: 20103166
I can upload the code and send you the link if you like!!!

0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20103207
No I have EmbeddedWB installed and everything. I am able to use it.
Or do you mean upload all of YOUR code to get it working? Well you can do that if you like and we can see what the problem is.
0
 

Author Comment

by:ST3VO
ID: 20103213
What I'm trying to do is a merge between the Main Demo and the Tabbed 2 Demo that comes with the demo downloads.

I have just started using these components today and I wanted to give a shot at adding Tabs at runtime to their demo browser :o/

0
 

Author Comment

by:ST3VO
ID: 20103222
OK...give me one minute! I'll upload the code the the server.
0
 

Author Comment

by:ST3VO
ID: 20103250
OK, Here it is :o)

http://www.st3vo.net/demo/BrowserTest1.zip

Thanks a million!!!

0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 20103483
Here's a problem...
Look at TfrmMain.FormCloseQuery
It says:
   EmbeddedWB1.SaveLastVisitedPage;
   EmbeddedWB1.SaveApplicationFormSize;

The first line tries to save the URL that the browser "EmbeddedWB1" is currently showing. But you've gone and freed it.
That would cause an access violation.
0
 

Author Comment

by:ST3VO
ID: 20104241
Wow...Perfect Thanks a million for all your help :o)

Cheers

ST3VO
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

840 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