
        Extended PageControl and Extended TabControl v2.3
        for Delphi and Borland C++Builder
        ------------------------------------------------------

        ExtPageControl and ExtTabControl are enhancements of
        component TPageControl and TTabControl in Delphi 2,
        Delphi 3 and Borland C++Builder.


        What are the enhancements of these components?
        ==============================================

         - You can change the color of active and inactive
           tabs

         - Each tab can have a bitmap

         - You can select different font for active and inactive
           tabs

         - Give the TabSheets another background color

         - Tabs can be placed on top, bottom, the left or
           right side of the component

         - A button mode is available if tabs are placed on
           top. In button mode the components becomes borderless.
           That can be usefully if you want to write wizard-like
           programs (set property TabVisible to false on all
           TabSheets).

         - Define a different Hint for each tab

         - Disabled TabSheets/Tabs get a grayed tab-text (as
           everyone expects on a disabled control)

         - A new OwnerDraw style is established (event OnDrawTab).
           Using this event you can draw the contents of the tabs
           yourself.

         - Support for accelerator keys (ALT + hotkey) to switch
           between the tabs/pages

         - New: Hottrack
           If hot-tracking is enabled then the item under the
           pointer will be automatically highlighted

         - New: Public methods BeginUpdate and EndUpdate
           BeginUpdate prevents the control from being repainted
           until the EndUpdate method is called (usefully when
           Tabs are dynamically added or deleted at runtime).

         - New: Events OnDrawBkgnd to draw on the background of
           the control



        Note:
        To place tabs on left, right or bottom of the component you may
        need an updated version of Microsofts Common Controls library
        ComCtl32.DLL. A new version of ComCtl32.DLL  ships with Windows
        NT 4 and Internet Explorer 3. You can download Internet Explorer
        from Microsofts Web-Site http://www.microsoft.com/ie/download/



        Files
        =====

          EXTPAGE.DC2  ->  component for Delphi 2
          EXTPAGE.DCR  ->  component image for Delphi and C++Builder
          EXTPAGE.DCU  ->  component for Delphi 3
          EXTPAGE.HPP  ->  include file for C++Builder
          EXTPAGE.OBJ  ->  component for C++Builder
          FILE_ID.DIZ  ->  short information for user
          
          EXTPAGE.INT  ->  interface file for user
          ORDER.TXT    ->  order information for user
          README.TXT   ->  this file

          SAMPLE.DPR   ->  sample project for Delphi
          SAMPLE.EXE   ->  running sample program
          SAMPLE1.DFM  ->  sample form 1 for Delphi and C++Builder
          SAMPLE1.PAS  ->  sample file 1 for Delphi and C++Builder
          SAMPLE2.DFM  ->  sample form 2 for Delphi and C++Builder
          SAMPLE2.PAS  ->  sample file 2 for Delphi and C++Builder



        Installation
        ============


          Installation in Delphi 2
          ========================

          1. Copy files EXTPAGE.DCR and EXTPAGE.DC2 into a directory,
             where your components reside, for instance
             C:\Programs\Delphi2\Lib

          2. Open this component directory with Explorer or a File
             Manager and rename file EXTPAGE.DC2 to EXTPAGE.DCU .

          3. From the Delphi menu select
             Component | Install ...

          4. Press the Add button, and select the path and filename of
             EXTPAGE.DCU. In the browse dialog pull down the 'Files of
             Type' combo box at the bottom and select file type (*.DCU).

          5. Back on the Install Components screen press OK.

          If installation succeeds you should see the ExtPageControl
          and ExtTabControl appear on the Win95 palette. If you have any
          difficulty installing the components refer to the Delphi 2 Help
          system.


          Installation in Delphi 3
          ========================

          1. Copy files EXTPAGE.DCR and EXTPAGE.DCU into a directory,
             where your components reside, for instance
             C:\Programs\Delphi3\Lib

          2. From the Delphi menu select
             Component | Install Component...

          3. Click Button "Browse..." beside "Unit file name" and select
             the path and filename of EXTPAGE.DCU. In the browse dialog
             pull down the 'Files of Type' combo box at the bottom and
             select file type (*.DCU).

          4. Back on the Install Components screen select an existing
             package in "Package file name" and press "OK" button.

          5. Confirm the rebuild dialog. Delphi compiles and adds ExtPage
             to the component library. When installation is complete, two
             items "ExtPageControl" and "ExtTabControl" can be found at
             palette tab "Win32".

          If you have any difficulty installing the components refer to
          the Delphi 3 Help system.


          Installation in Borland C++Builder
          ==================================

          1. Copy files EXTPAGE.DCR and EXTPAGE.OBJ into the Lib directory
             of C++Builder, for instance 
             C:\Programs\Borland\CBuilder\Lib\Obj

          2. Copy file EXTPAGE.HPP into C++Builder Include directory, for 
             instance C:\Programs\Borland\CBuilder\Include\VCL

          3. From the Borland C++Builder menu select
             Component | Install ...

          4. Press the Add button and select the path and filename of
             your EXTPAGE.OBJ file. In the browse dialog pull down the
             'Files of Type' combo box at the bottom and select file
             type (*.OBJ).

          5. Back on the Install Components screen press OK.

          If installation succeeds you should see the ExtPageControl
          and ExtTabControl appear on the Win95 palette. If you have any
          difficulty installing the components refer to the Borland
          C++Builder Help system.



        Registration
        ============

        ExtPageControl and ExtTabControl are Shareware. A free Trial
        version gives you the opportunity to try these native components.
        They have the full functionality of the registered version, but
        can run only when Delphi or Borland C++Builder is also running
        on the PC.

        To deliver an application using these components, you must purchase
        the applicable version. The registration fee is US $39.95. You get

         - both components with full source code via e-mail
         - coming updates for free
         - lifetime technical support via Internet e-mail.

        Please see file Order.txt for details.

        ExtPageControl & ExtTabControl are royalty free. That means that you
        may distribute your programs compiled with ExtPage/Tab code incurring
        no royalty fee. You may not distribute ExtPage/Tab source code or
        ExtPage/Tab compiled components.




        FAQ
        ====

         Q: Is ExtPageControl a subclass of TCustomTabControl?

         A: ExtPageControl and ExtTabControl are indirect subclasses
            of TCustomTabControl. That's the class tree:

                   TCustomTabControl         (Delphi VCL)
                     |           |
               TPageControl   TTabControl    (Delphi VCL)
                     |           |
            TExtPageControl   TExtTabControl



         Q: Why have a uniform tab width? Can tabs be different widths?
            I need this functionality.

         A: Tabs can have different width if they are on top or on
            bottom of the control. Set property TabWidth to zero.
            Only if the tabs are on the left or right side of the
            control they must have the same (fixed) width.



         Q: Is it possible to have each tab a different color?

         A: Yes, simply insert some code in event OnDrawTab. In Delphi
            write:


            with TExtPageControl(Control) do begin
              Case Index Of
                // color of Tab 1
                0: Canvas.Brush.Color:= RGB(192, 220, 192);

                // color of Tab 2
                1: Canvas.Brush.Color:= clYellow;

                // color of Tab 3
                2: Canvas.Brush.Color:= RGB(166, 202, 240);
              End;
              Canvas.FillRect(RectBg);
              DefaultDrawTab(Index, RectFg, State);
            end;


            Check if unit StdCtrls is included in the uses clause of your
            file. In C++Builder you can write:


            TExtPageControl *ExtPgCtrol = (TExtPageControl*)Control;
            switch(Index)
            {
              case 0: // color of Tab 1
                ExtPgCtrol->Canvas->Brush->Color = RGB(192, 220, 192);
                break;
              case 1: // color of Tab 2
                ExtPgCtrol->Canvas->Brush->Color = clYellow;
                break;
              case 2: // color of Tab 3
                ExtPgCtrol->Canvas->Brush->Color = RGB(166, 202, 240);
                break;
            };
            ExtPgCtrol->Canvas->FillRect(RectBg);
            ExtPgCtrol->DefaultDrawTab(Index, RectFg, State);



         Q: How do you go about changing the lettering color of one tab?
            Lets say you have five tabs, all the tabs have gray background
            and black lettering which is the norm.  One of the tabs need to
            stand out and be a different color (just for the letters), the
            background would remain the same.

         A: In Delphi insert this code in event OnDrawTab:


            with TExtPageControl(Control) do begin
              Case Index Of
                0: Canvas.Font.Color:= clNavy;  // blue text on Tab 1
                1: Canvas.Font.Color:= clRed;   // red text on Tab 2
                2: Canvas.Font.Color:= clGreen; // green text on Tab 3
              End;
              DefaultDrawTab(Index, RectFg, State);
            end;


            Check if unit StdCtrls is included in the uses clause of your
            file. In C++Builder insert this code in event OnDrawTab:


            TExtPageControl *ExtPgCtrol = (TExtPageControl*)Control;
            switch(Index)
            {
              case 0: // blue text on Tab 1
                ExtPgCtrol->Canvas->Font->Color = clNavy;
                break;
              case 1: // red text on Tab 2
                ExtPgCtrol->Canvas->Font->Color = clRed;
                break;
              case 2: // green text on Tab 3
                ExtPgCtrol->Canvas->Font->Color = clGreen;
                break;
            };
            ExtPgCtrol->DefaultDrawTab(Index, RectFg, State);



         Q: I currently have a PageControl that is about 8 pages
            big with a lot of controls on each page. Is it possible to
            substitute ExtPageControl with PageControl without
            starting from scratch. I tried the cut and paste routine
            along with all the source but its a real pain and not
            working to well.

         A: Select your form in design-mode. Press keys ALT+F12 -> you
            should be in form-edit mode now. Search for your TPageControl
            and replace it by TExtPageControl. Press ALT+F12 again and
            save your work. This works the same way in Delphi and Borland
            C++Builder.



         Q: How do I get bitmaps into the tabs? How do I use property
            TabGlyphs?

         A: All images for the different tabs are stored in one large
            bitmap (property TabGlyphs.Glyph). All images must be the same
            size and next to each other in a horizontal row. You must
            specify the number of images that are in the bitmap with the
            TabGlyphs.NumGlyphs property. If you have for instance 5 tabs
            in your control and each tab image has a height of 18
            pixel and a width of 16 pixel, then the bitmap must be 18 pixel
            high and 5*16 = 80 pixel wide. Set property TabGlyphs.NumGlyphs
            to 5.

            You can create the bitmap with any bitmap editor. With Delphi
            and Borland C++Builder comes an ImageEditor (imagedit.exe).
            Property TabGlyphs.TransparentColor determines partial
            transparent parts in the image.

            Property TabGlyphs.Spacing determines the number of pixels
            between the image (specified in the Glyph property) and the text
            (specified in the Caption property of each TabSheet for Ext-
            PageControl and specified in property Tabs for ExtTabControl).
            The default value is 5 pixels.



         Q: What is largest Glyph size that can be used? (21x21, OK?)

         A: I'm not aware of any glyph size limitation. So, 21x21 should
            work without problems.



         Q: Is there a way to change what bitmap (glyph) is shown on a
            tab at run time? Our application uses folders to organize a
            transaction work flow and we put a check mark in the tab
            after a folder has been opened and properly processed. We
            want to modify the tab image to graphically indicate folders
            that have been "reviewed". This means that the image
            displayed in the tab must be modified on the fly.

         A: Extended PageControl & TabControl use an image list of type
            TImageList (-> see Delphi or C++Builder help file) to segregate
            the images for each tab. You have access to this list by pro-
            perty TabGlyphs.ImageList.

            To replace the glyph of the second tab you could write in
            Delphi:

            var
              MyBmp: TBitmap;
            begin
              MyBmp:= TBitmap.Create;
              try
                MyBmp.LoadFromFile('c:\Test.bmp');
                ExtPageControl1.TabGlyphs.ImageList.Replace(1, MyBmp, nil);
                ExtPageControl1.Invalidate;
              finally
                MyBmp.Free;
              end;
            end;


            In In C++Builder you could the same with this:

            Graphics::TBitmap* MyBmp = new Graphics::TBitmap;
            try
            {
              MyBmp->LoadFromFile("c:\\Test.bmp");
              ExtPageControl1->TabGlyphs->ImageList->Replace(1, MyBmp, NULL);
              ExtPageControl1->Invalidate();
            }
            catch(...)
            {
              delete MyBmp;
              throw;
            }
            delete MyBmp;



         Q: Some Pagecontrols offer system resource reduction by freeing
            window handles for all pages except the current one.  I now
            have so many controls in my Extpage2 that I really need a
            feature like that. Can you add such a feature to Extpage2?

         A: Yes, the public procedure DestroyAllOtherSheetHandles in
            ExtPageControl frees the resources of all TabSheets except
            the current one. If you call this procedure in event OnChange
            of the PageControl then only the current Sheet uses system
            resources.

            In Delphi you may write:

            procedure TForm1.ExtPageControl1Change(Sender: TObject);
            begin
              TExtPageControl(Sender).DestroyAllOtherSheetHandles;
            end;


            In Borland C++Builder write:

            void __fastcall TForm1::ExtPageControl1Change(TObject *Sender)
            {
              ((TExtPageControl*)Sender)->DestroyAllOtherSheetHandles();
            }



         Q: Is there a difference in when OnChange event is fired between
            Delphi's PageControl and your ExtPageControl?

         A: Yes. Let's say you are on page TabSheet1. A function call like

              ExtPageControl1.ActivePage:= TabSheet2;

            selects page TabSheet2 and fires the events OnChanging and On-
            Change. The same function call does not fire OnChanging / On-
            Change events in Delphi's PageControl.

            OnChanging and OnChange events are also fired if property Tab-
            Index is changed in ExtTabControl.



         Q: How can I disable a Tab in ExtTabControl?

         A: You can disable a Tab at run-time only. To disable the third
            Tab write in Delphi:

              ExtTabControl1.TabEnabled[2]:= False;

            In C++Builder write:

              ExtTabControl1->TabEnabled[2] = false;



         Q: How can I disable a Tab in ExtPageControl?

         A: A Tab is disabled if the corresponding Page is disabled.
            Example for Delphi:

              TabSheet3.Enabled:= False;
              ExtTabControl1.Invalidate;

            In C++Builder you do the same with:

              TabSheet3->Enabled = false;
              ExtTabControl1->Invalidate();



          Q: I have a suggestion for a new property in your ExtTabControl:
             DisplayTabs. When this property is false the defined tabs
             shouldn't be visible anymore.

          A: It's already possible to hide Tabs in a TabControl and also in
             PageControl. In a TabControl remove/insert the Tab at runtime
             from the Tabs Stringlist:

               TabControl1.Tabs.Delete(1);  // remove Tab 2
               TabControl1.Tabs.Insert(0, 'New Tab'); // insert Tab 1

             In a PageControl set property TabVisible of the corresponding
             TabSheet to False.



         Q: How can I add pages to Extended PageControl on the fly
            (at runtime)?

         A: This example adds 5 pages to a PageControl. In each
            page is a Memo control inserted.

            var
              i: Integer;
              NewSheet: TTabSheet;
            begin
              ExtPageControl1.BeginUpdate;
              try
                for i:= 1 to 5 do begin
                  NewSheet:= TTabSheet.Create(Self);
                  with NewSheet do begin
                    Parent:= ExtPageControl1;
                    PageControl:= ExtPageControl1;
                    Caption:= 'Page #' + IntToStr(PageIndex);

                    // create a Memo on each page
                    with TMemo.Create(NewSheet) do begin
                      Parent:= NewSheet;
                      Text:= 'Memo at Page ' + IntToStr(PageIndex);
                      Left:= 25;
                      Top:= 25;
                    end;
                  end;
                end;
                ExtPageControl1.ReAlignTabSheets;
              finally
                ExtPageControl1.EndUpdate;
              end;
            end;



        Q: Is it possible to have a background in the blank part of the
           tab area?  Say I've got 3 tabs on this Form and there is
           space for 3 more tabs... I would like to fill that space with
           some type of textured background... is that possible??

        A: Yes, use event 'On Draw Background Outside'. With unit ExtPage
           comes a special procedure ExtDrawBkgndImageRgn. Put a TImage
           control (Image1 in this sample) with your textured background
           under Page-/TabControl and insert this code in event OnDraw-
           BkgndOutside:

           procedure TForm1.ExtTabControl1DrawBkgndOutside(Control:
             TWinControl; DC, RgnBg: Integer);
           begin
             ExtDrawBkgndImageRgn(Control, DC, RgnBg, Image1);
           end;

           In C++Builder write:

           void __fastcall TForm1::ExtPageControl1DrawBkgndOutside(TWinControl 
              *Control, HDC DC, HRGN RgnBg)
           {
             ExtDrawBkgndImageRgn(Control, int(DC), int(RgnBg), Image1);        
           }

           The Picture of the Image now appears in the free space of Page-/
           TabControl.



        Q: Is it possible to draw some text in the blank part of the
           tab area?

        A: Here's a sample for Delphi (Tabs should be on top or
           bottom of the control in this example):

           procedure TForm1.ExtPageControl1DrawBkgndOutside(Control:
                         TWinControl; DC, RgnBg: Integer);
           var
             OldFont: HFont;
             R: TRect;
           begin
             GetRgnBox(RgnBg, R);
             with TExtPageControl(Control) do
               R.Left:= GetTabRect(Tabs.Count-1).Right + 3;
             SetBkMode(DC, TRANSPARENT);
             OldFont:= SelectObject(DC, Font.Handle);
             DrawText(DC, 'Hello World', -1, R, DT_CENTER or DT_WORDBREAK);
             SelectObject(DC, OldFont);
           end;




        By the way, you can always switch between the pages of a PageControl
        by pressing the keys CTRL + TAB. Pressing CTRL + SHIFT + TAB switches
        back. These shortcuts work system wide with all PageControls.



        Jan - Michael Strube
        e-mail: 100333.2744@compuserve.com
        WWW: http://ourworld.compuserve.com/homepages/praxisservice/


                                 -*- EOF -*-