norgepaul / TChromeTabs

Comprehensive Delphi implementation of Chrome's tab system
Other
215 stars 78 forks source link

ChromeTabsActiveTabChanging Event works Wrong #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
So, the problem is that, what ChromeTabsActiveTabChanging Event works Wrong, 
why?
Because ANewTab var contains wrong value.
Try to create an easy project with this TABS, and put this code on this EVENT:
ShowMessage(inttostr(ANewTab.Index));

---
Now, try to create 2 Tabs, then focus on First Tab and close it!
You will get "Argument not in range" error, if try to hide OldTab and show 
NewTab, because NewTab contains wrong value.
The code i posted, will show 1 after doing operations, i said, so that will 
cause an error, bad error.
ANewTab must be 0, not 1, because Tab With Index 0 is exactly closed and if 
ANewTab contains of 1, we trying to show this Tab and we get an Range Error, 
because Tab With index 1 doesn't exist as it is!
So in case of that, you need to edit your code and make it work correctly, 
because ANewTab must be 0, but not 1.

For maximum understand, what i just said, please, compile or just look at this 
code and try to make what i sad about 2 tabs and focusing on first tab with 
index 0 and closing it.

Here is the code:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  System.Generics.Collections, ChromeTabs, ChromeTabsClasses, cefvcl;

type
  TForm1 = class(TForm)
    ChromeTabs1: TChromeTabs;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ChromeTabs1ButtonAddClick(Sender: TObject;
      var Handled: Boolean);
    procedure ChromeTabs1ButtonCloseTabClick(Sender: TObject;
      ATab: TChromeTab; var Close: Boolean);
    procedure ChromeTabs1ActiveTabChanging(Sender: TObject; AOldTab,
      ANewTab: TChromeTab; var Allow: Boolean);
  private
    FBrowsers: TObjectList<TChromium>;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  // create instance of the object list and let it manage
  // lifetime of the inserted objects
  FBrowsers := TObjectList<TChromium>.Create;
  FBrowsers.OwnsObjects := True;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // release the object list
  FBrowsers.Free;
end;

procedure TForm1.ChromeTabs1ButtonAddClick(Sender: TObject;
  var Handled: Boolean);
var
  ChromiumInstance: TChromium;
begin
  // create an instance of the browser component and
  // initiliaze its properties - here it's simplified
  ChromiumInstance := TChromium.Create(nil);
  ChromiumInstance.Parent := Self;
  ChromiumInstance.SetBounds(8, 8, 150, 150);
  // now add the new browser instance to the collection
  FBrowsers.Add(ChromiumInstance);
end;

procedure TForm1.ChromeTabs1ButtonCloseTabClick(Sender: TObject;
  ATab: TChromeTab; var Close: Boolean);
begin
  // delete the browser instance from the collection; since we've
  // assigned True to the OwnsObjects property of the collection,
  // we don't need to care of freeing the browser instance
  FBrowsers.Delete(ATab.Index);
  // allow the tab to close
  Close := True;
end;

procedure TForm1.ChromeTabs1ActiveTabChanging(Sender: TObject; AOldTab,
  ANewTab: TChromeTab; var Allow: Boolean);
begin
  // check if there's an "old tab" and if so, check also if we have its
  // index in the range of our collection; if so, then hide the browser
  if Assigned(AOldTab) and (AOldTab.Index < FBrowsers.Count) then
    FBrowsers[AOldTab.Index].Visible := False;
  // and show the activated tab browser
  FBrowsers[ANewTab.Index].Visible := True;
end;

end.

REGARDS, Tugalov Abdurahman(nikname Priler).

Original issue reported on code.google.com by WEB2rb...@gmail.com on 19 Jul 2013 at 9:22

GoogleCodeExporter commented 9 years ago
And exactly here is my FIX :

procedure TForm1.ChromeTabsActiveTabChanging(Sender: TObject; AOldTab,
  ANewTab: TChromeTab; var Allow: Boolean);
begin
      // check if there's an "old tab" and if so, check also if we have its
      // index in the range of our collection; if so, then hide the browser
      if Assigned(AOldTab) and (AOldTab.Index < FBrowsers.Count) then
        FBrowsers[AOldTab.Index].Visible := False;
      // and show the activated tab browser
      If((ChromeTabs.Tabs.Count<>1)) Then
      Begin
      If((ANewTab.Index=(ChromeTabs.Tabs.Count-1)) AND Tab_Closed=True) Then
      FBrowsers[AOldTab.Index].Visible := True
      Else
      FBrowsers[ANewTab.Index].Visible := True;
      End
      Else FBrowsers[ANewTab.Index].Visible := True;
      //Now Tab is not closed
      Tab_Closed:=False;
end;

procedure TForm1.ChromeTabsButtonCloseTabClick(Sender: TObject;
  ATab: TChromeTab; var Close: Boolean);
begin
  // delete the browser instance from the collection; since we've
  // assigned True to the OwnsObjects property of the collection,
  // we don't need to care of freeing the browser instance
  FBrowsers.Delete(ATab.Index);
  Tab_Closed:=True;
  // allow the tab to close
  Close := True;
end;

The point is that, what on CloseTab EVENT we checking, that is closing the 
last_one-1 tab or not, and checking was a CloseTab EVENT executed before.

Exactly the problem is that, what Changing Procedure Starts Before Closing 
Procedure.

---

REGARDS, Tugalov Abdurahman(nikname Priler).

Original comment by WEB2rb...@gmail.com on 19 Jul 2013 at 10:04

GoogleCodeExporter commented 9 years ago
I can't use your demo code as I don't have TChromium installed.

If I run the standard TChromeTabs demo then close the first tab everything 
works as expected. Can you provide an example that uses the standard demo 
without TChromium?

Original comment by paul.tho...@easy-ip.net on 20 Jun 2014 at 8:07

GoogleCodeExporter commented 9 years ago
Unable to reproduce. Please re-open if you can provide more details.

Original comment by paul.tho...@easy-ip.net on 3 Sep 2014 at 7:40