[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 458
  • Last Modified:

Table of Contents - Like a Books

Hello All;

  I am trying to find the best solution for making a "Table of Contents" for the project that
I am currently on.
  The Pages are done using: TTabSheets.
  On each TabSheet, loads a "TFrame".

  Right now the "Table of Contents" is the use of:
TLabels.Align := alTop;

  Which this is fine, but does not take on the look of a Book's Table.

  I am open to any suggestions that you all have.

Basically this is what I am needing.

  The Example will have to be:

Looks Good - Simluates a Books "Table of Contents"
each content must open a particular TabSheet.

Example Table:

==============================
Chapter 1 (Movies)
      Horror  ..................pg 3-4--> TabSheet1
      Comedy  ................pg 5-6--> TabSheet2
      Romance ...............pg 7-8 --> TabSheet3
      Action ...................pg 9-10 --> TabSheet4
Chapter 2 (Jewelry)
      Watches  ...............pg 11-12--> TabSheet5
       Bracelets  .............pg 13-14--> TabSheet6
       Rings ...................pg 15-16 --> TabSheet7
==============================

This of course is by no means all of them.
The project will most likely climb to about around 200+ pages.
If not more, over its lifetime (Which hopefully will have a long lifeline).

As mentioned above, I am open to all suggestions.

500 Points to be example
(or)
Split points to all good Examples

Take Care All;
Carrzkiss
0
Wayne Barron
Asked:
Wayne Barron
  • 11
  • 7
1 Solution
 
calinutzCommented:
I suggest that you should use a ListView, TreeView or even a Virtual TreeView (Mike Lischke)-seems to be faster even though for 200-1000 pages or even more I think you should use TreeView for less complicated code.
If you are looking for an answer to show a nice interface  I recomend using Virtual TreeView with classes where you can assign to a node the text and the tabsheet number or name, so every node will have 2 properties: text and link (for example), and onClick you can simply make something like
PageControl1.Activepage:=node.link

Not enough time to make an example... maybe later





0
 
EddieShipmanCommented:
A formatted Treeview would be your best bet.
HTMLTreeview from TMS would be a very good choice as it let's you
format the text as well as have each item act as hyperlinks.
0
 
Wayne BarronAuthor Commented:
Hello Eddie;

I think that might work.
Was very easy to implement the demo to work with a WebBrowser.

Thanks for the information, I will post back my findings later on.

calinutz;
  Still interested in seeing a Demo (if you have the time).
But for now I am going to take a better look into the "HTMLTreeView"
And see what I can do with it.

Nice when you have the components already, makes things a lot nicer

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

 
Wayne BarronAuthor Commented:
Hello Eddie;

  I just ran into a situation here.
Could you take a look at this
http://www.carrz-fox-fire.com/1/ProjectCatalog.zip

The   FrameTable.TableFrame
I am having a problem with the following.

Adding this code to the

Form1.OnCreate;
var
  tn: TTreeNode;
begin
  htmltreeview1.Items.BeginUpdate;
  tn := htmltreeview1.Items.Add(nil,'Movies');
  htmltreeview1.Items.AddChild(tn,'<img src="ssys:word.doc"> <a href="tsMovieKids">Family Movies</a> ');
htmltreeview1.Items.EndUpdate;
end;


Cannot do it, with the "HTMLTreeView" setting on the:  FrameTable.

You will better understand when you see it.

Also in the

procedure TForm1.HTMLTreeview1AnchorClick(Sender: TObject; Node: TTreeNode;
  anchor: String);
begin
  //showmessage('anchor:'+anchor); //ShowMessage
 //WebBrowser1.Navigate(WideString(''+anchor)); // Open in WebBrowser
end;

How would I open the TabSheet.
tsMovieKids.Show;

And so on.

Any help that you can assist with will be great.
And thanks for the information on this component.
I like it very much, and that that it will work for what I am needing.
(I hope so anyway)
0
 
Wayne BarronAuthor Commented:
Oh Yea.
  I created that Demo earlier for someone else.
So the "THtmlTreeView" is not involved in it, so it will have to be added.
Preferably in the [FrameTable] is possible.
If not, then I will need to work on putting it on the Form1.
tsIndex <-- TabSheet
0
 
EddieShipmanCommented:
Ok. first, drop the HTMLTreeview on the TableFrame.
Then make this change to Unit1:

procedure TForm1.CreateFrame(ATabsheet: TTabSheet);
var
  frame: TFrame;
  intf: IFrame;
  tn: TTreeNode;
begin
  if GetFrame(ATabsheet) = nil then
    if ATabsheet.Tag <> 0 then
    begin
      frame := TFrameClass(ATabsheet.Tag).Create(Self, ATabsheet.Handle);
      frame.Parent := ATabsheet;
      frame.Align := alClient;
      if frame.Name = 'TableFrame' then
      begin
        TTableFrame(frame).htmltreeview1.Items.BeginUpdate;
        tn := TTableFrame(frame).htmltreeview1.Items.Add(nil,'Movies');
        TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="ssys:word.doc"> <a href="0">Children (Ice Age, Aladin and more)</a> ');
        TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="ssys:word.doc"> <a href="1">Suspense (The Butterfly Effect, Cellular and more)</a> ');
        TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="ssys:word.doc"> <a href="2">Comedy (Eight Legged Freaks, Happy Gilmore and more)</a> ');
        TTableFrame(frame).htmltreeview1.Items.EndUpdate;
        TTableFrame(frame).htmltreeview1.AutoExpand := True;
      end;
    end;
end;


Then make this change to FrameTable unit, adding an OnAnchorClick to the HTMLTreeview:

procedure TTableFrame.HTMLTreeview1AnchorClick(Sender: TObject;
  Node: TTreeNode; anchor: String);
begin
  case anchor[1] of
  '0': Form1.tsMovieKids.Show;
  '1': Form1.tsMovieSuspense.Show;
  '2':Form1.tsMovieComedy.Show;
  end;
end;
0
 
EddieShipmanCommented:
The HTMLTreeview doesn't have an ExpandAll procedure and I have found that  TTableFrame(frame).htmltreeview1.AutoExpand := True;
doesn't work properly.

So, do this instead:

        TTableFrame(frame).htmltreeview1.Items.Item[0].Expand(True);
0
 
Wayne BarronAuthor Commented:
where would I insert the:

TTableFrame(frame).htmltreeview1.Items.Item[0].Expand(True);

I tried putting it in the Unit1 (Form1OnCreate) but that did not work.
0
 
Wayne BarronAuthor Commented:
duhhhhhh

I found it ;-)

   Man, tired and sick not a good conbination for working.

Thanks, will give everything a test drive now
0
 
EddieShipmanCommented:
You replace
  TTableFrame(frame).htmltreeview1.AutoExpand := True;
with
  TTableFrame(frame).htmltreeview1.Items.Item[0].Expand(True);

0
 
Wayne BarronAuthor Commented:
:-)
  Yep, found it about 1-minute before posting :-)
0
 
Wayne BarronAuthor Commented:
I think this is going to be the tool to make it with.
Simple to setup and work with.

Take Care and thanks once again for your great coding skills.
Maybe one of these days I will have enough knowledge of these components.
To help out in these types of issues as well.

Take Care and Thanks once again.
Wayne
0
 
Wayne BarronAuthor Commented:
How many Anchors are you allowed to have?
It hits '10': and give me:
[Error] FrameTableofContents.pas(203): Incompatible types: 'Char' and 'String'

Is there a limit on the amount of Anchors or something?
There should not be.

Will do some more checking.
0
 
EddieShipmanCommented:
Let me take a look at it tomorrow morning.

I also have a litttle bitmap that you can use instead of that "word.doc"
I dropped a Imagelist on the main form and used the bitmap located here:
http://65.98.67.10/~austin1/movie.bmp

Then I set the HTMLImages property of the HTMLTreeview like this:
TTableFrame(frame).htmltreeview1.HTMLImages := ImageList1;

Then I changed the text inserted into the HTMLTreeview like this:

TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="idx:0"> <a href="0">Children (Ice Age, Aladin and more)</a> ');
TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="idx:0"> <a href="1">Suspense (The Butterfly Effect, Cellular and more)</a> ');
TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="idx:0"> <a href="2">Comedy (Eight Legged Freaks, Happy Gilmore and more)</a> ');
0
 
Wayne BarronAuthor Commented:
Hummmmm?

  OK, Just testing.
I changed the
'10':
with
'A':

And it compiled?

It seems that it will work like so.(My be mistaking, but this is what I have found)

'1': - '9':
'A': - 'Z':

Going back to do some more testing.
If this is the case, then if you run out of the Alphabets, Then
That is it, so
9 - Numbers
26 - Letters
--------------
35 - Anchors total.

Please by all means, correct me if I am wrong on this one.
But I will work on it as if I am correct, and see what happens.
To see if it will run correctly.

Wayne
0
 
Wayne BarronAuthor Commented:
Yep that is how it works.
Aplanumrical characters.
Running a 1-9 and A-Z
You cannot use "Double Digit Numbers" with it. aka: 10,11,12,13 and so on.

So if you have more levels then what it allowed (seems to be 35 items deep).
Then I would suppose that adding another "HTMLTreeView" into the Project
Would probably be the only alternative.

So as it sets right now.
This is going to be the perfect interface for the "Table of Contents".
And it's ease of use, and quickness is going to make the rest of the Development
(Code wise) much faster and easier.

Thanks again Eddie for your assistance, and the Bitmap image as well.
I am going to see if I can find some for others area's of the project as well.

Take Care and off I go to get this thing off the ground.

Wayne
0
 
EddieShipmanCommented:
How many do you need?
The case statement in the HTMLTreeview1AnchorClick can
be modified to access full strings if you want.

To see how it's done...
Here's the entire FrameTable unit:

unit FrameTable;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, ComCtrls, htmltv;

type
  TTableFrame = class(TFrame)
    Panel1: TPanel;
    Label3: TLabel;
    Label30: TLabel;
    Panel2: TPanel;
    HTMLTreeview1: THTMLTreeview;
    procedure Label12Click(Sender: TObject);
    procedure Label2Click(Sender: TObject);
    procedure Label4Click(Sender: TObject);
    procedure HTMLTreeview1AnchorClick(Sender: TObject; Node: TTreeNode;
      anchor: String);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

uses Unit1;

{$R *.dfm}

procedure TTableFrame.Label12Click(Sender: TObject);
begin
  Form1.tsMovieKids.Show;
end;

procedure TTableFrame.Label2Click(Sender: TObject);
begin
  Form1.tsMovieSuspense.Show;
end;

procedure TTableFrame.Label4Click(Sender: TObject);
begin
  Form1.tsMovieComedy.Show;
end;

function StringToCaseSelect(Selector: String;
                            CaseList: array of String): Integer;
var
  cnt: Integer;
begin
  Result := -1;
  for cnt := 0 to Length(CaseList)-1 do
  begin
    if CompareText(Selector, CaseList[cnt]) = 0 then
    begin
      Result := cnt;
      Break;
    end;
  end;
end;

procedure TTableFrame.HTMLTreeview1AnchorClick(Sender: TObject;
  Node: TTreeNode; anchor: String);
begin
  case StringToCaseSelect(anchor, TopicsList) of
  0: Form1.tsMovieKids.Show;
  1: Form1.tsMovieSuspense.Show;
  2: Form1.tsMovieComedy.Show;
  end; {case}
end;

end.

and Unit1:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, OleCtrls, SHDocVw_TLB, StdCtrls, ExtCtrls, SHDocVw,
  htmltv, ImgList;

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    tsBrowser: TTabSheet;
    tsIndex: TTabSheet;
    tsMovieKids: TTabSheet;
    tsMovieSuspense: TTabSheet;
    tsMovieComedy: TTabSheet;
    WebBrowser1: TWebBrowser;
    Panel1: TPanel;
    Label3: TLabel;
    ImageList1: TImageList;
    procedure tsBrowserHide(Sender: TObject);
    procedure tsBrowserShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Label3Click(Sender: TObject);
  private
  FAutoFreeFrame: boolean;
  procedure CreateFrame(ATabsheet: TTabSheet);
  function GetFrame(ATabsheet: TTabsheet): TFrame;
  procedure DestroyFrame(ATabsheet: TTabsheet);
    { Private declarations }
  public
  property AutoFreeFrame: boolean read FAutoFreeFrame write FAutoFreeFrame;
    { Public declarations }
  end;

var
  Form1: TForm1;
  Topicslist: array[0..2] of String;

implementation

uses ufraBaseFrame, FrameTable, FrameComedy, FrameKids, FrameSuspense;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  TopicsList[0] := 'Children';
  TopicsList[1] := 'Suspense';
  TopicsList[2] := 'Comedy';
  tsIndex.Tag := Integer(TTableFrame);
  tsMovieKids.Tag := Integer(TKidsFrame);
  tsMovieSuspense.Tag := Integer(TSuspenseFrame);
  tsMovieComedy.Tag := Integer (TComedyFrame);
  CreateFrame(tsIndex);

  Form1.Height := 578;
  Form1.Width := 834;

  // Need to hide all Tabs on the MainForm.
  // We will only show the Tabs that are needed.
  // And this will only be done through. TabSheet1.Show;

  tsBrowser.TabVisible := False;
  tsIndex.TabVisible := False;
  tsMovieKids.TabVisible := False;
  tsMovieSuspense.TabVisible := False;
  tsMovieComedy.TabVisible := False;

  // We will need to show the tsIndex at the beginning.
  // if not, then we will get a blank form.

  tsIndex.Show;
end;

procedure TForm1.DestroyFrame(ATabsheet: TTabsheet);
var
  frame: TFrame;
begin
  frame := GetFrame(ATabsheet);
  if frame <> nil then
    frame.Free;
end;

procedure TForm1.CreateFrame(ATabsheet: TTabSheet);
var
  frame: TFrame;
  intf: IFrame;
  tn: TTreeNode;
begin
  if GetFrame(ATabsheet) = nil then
    if ATabsheet.Tag <> 0 then
    begin
      frame := TFrameClass(ATabsheet.Tag).Create(Self, ATabsheet.Handle);
      frame.Parent := ATabsheet;
      frame.Align := alClient;
      if frame.Name = 'TableFrame' then
      begin
        TTableFrame(frame).htmltreeview1.Items.BeginUpdate;
        tn := TTableFrame(frame).htmltreeview1.Items.Add(nil,'Movies');
        TTableFrame(frame).htmltreeview1.HTMLImages := ImageList1;
        TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="idx:0"> <a href="Children">Children (Ice Age, Aladin and more)</a> ');
        TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="idx:0"> <a href="Suspense">Suspense (The Butterfly Effect, Cellular and more)</a> ');
        TTableFrame(frame).htmltreeview1.Items.AddChild(tn,'<img src="idx:0"> <a href="Comedy">Comedy (Eight Legged Freaks, Happy Gilmore and more)</a> ');
        TTableFrame(frame).htmltreeview1.Items.EndUpdate;
        TTableFrame(frame).htmltreeview1.Items.Item[0].Expand(True);
      end;
    end;
end;

function TForm1.GetFrame(ATabsheet: TTabSheet): TFrame;
begin
  if not Assigned(ATabsheet) then
    ATabsheet := PageControl1.ActivePage;
  Result := nil;
  if Assigned(ATabsheet) and (ATabsheet.ControlCount > 0) and (ATabsheet.Controls[0] is TFrame) then
    Result := TFrame(ATabsheet.Controls[0]);
end;


procedure TForm1.tsBrowserHide(Sender: TObject);
var
  frame: TFrame;
  intf: IFrame;
begin
  frame := GetFrame(Sender as TTabSheet);
  if Supports(frame, IFrame, intf) then
    intf.OnHide;

  // You can get AVs due to Tabsheet.OnHide destroying the frame and code relying
  // on the frame to still be there in e.g. PageControl1.OnChange/OnChanging
  if AutoFreeFrame then
    DestroyFrame(Sender as TTabSheet);

end;

procedure TForm1.tsBrowserShow(Sender: TObject);
var
  frame: TFrame;
  intf: IFrame;
begin
  SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
  CreateFrame(Sender as TTabSheet);  // Ensure that the frame is created. Helpful when we are calling TabsheetEnter(tsXXX) directly
  frame := GetFrame(Sender as TTabSheet);
  if Supports(frame, IFrame, intf) then
    intf.OnShow;

end;

procedure TForm1.Label3Click(Sender: TObject);
begin
  tsIndex.Show;
end;

end.
0
 
EddieShipmanCommented:
[quote]
'1': - '9':
'A': - 'Z':

Going back to do some more testing.
If this is the case, then if you run out of the Alphabets, Then
That is it, so
9 - Numbers
26 - Letters
--------------
35 - Anchors total.
[/quote]

Actually, you can add another 27:

'0'..'9':
'A'..'Z':
'a'..'z'

10 - Numbers
52 - Letters
--------------
62 - Anchors total {not including punctuation, too}
0
 
Wayne BarronAuthor Commented:
O.K.

   That will help out alot.
   Will have to see after the project is completed on exactly how many
   Anchors the project will actually have.
   It is not a small project.

Take Care
0

Featured Post

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!

  • 11
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now