Container Performance problem
-----------------------------

There is a performance problem in the IVBContainerControl when you connect
the 'selectedElement' attribute to a variable on the free form surface. This
performance problem is mostly noticeable when there is a large number of
elements in the container. The performance hit occurs because of the way that
this variable gets updated.

Using an attribute-to-attribute connection from the container's
'selectedElement' to a variable on the free form surface causes many
notifications to fire. The number of notifications firing is the reason for
the performance problem in this scenario. In addition to this delay, many
exceptions are thrown.

There are a couple of ways to work around this performance problem.  The easiest
way, and perhaps the most common solution, is NOT to have an
attribute-to-attribute connection to the VisualBuilder variable on the free form
surface but instead to query the selected element only when needed. This
solution seems to meet most application needs.  However, there are circumstances
when this approach does not provide a solution. because the selected element
needs to be known at all times in other parts of the application.

The second work around to this problem involves some extra code, but the result
is that a VisualBuilder variable can be updated as the selected element in a
container changes.  Then the program can make use of the selected variable
without sacrificing much in terms of performance.

This sample demonstrates how to implement the second workaround.  The program
consists of a 1x1 multicellcanvas part that contains an IVBContainerControl
in the single cell.  This multicell canvas part is the client area of the main
window of the app.  The selected element of the container will be displayed in
another frame window that simply shows more info about the selected element.

The steps required to implement this work around are as follows:
1) Add an attribute of the container control element type to the window
   containing the container (CnrSelectedElement). The get and set member
   functions for this attribute are:
   [ContainerElement]* cnrSelectedElement()
   [OwnerWindow]&       setCnrSelectedElement([ContainerElement]*
                                                           aCnrSelectedElement)
   where:
   - 'ContainerElement' is the container element class name, ie. in this
     example it is NVPart
   - 'OwnerWindow' is the name of the window class that contains the container
     control, ie. in this example it is CanvasCnr

   The actual set and get member functions for the example are:
   virtual NVPart* cnrSelectedElement();
   virtual CanvasCnr& setCnrSelectedElement(NVPart* aCnrSelectedElement);

   In addition, an event notification is needed so that it can fire when the
   attribute changes. For the example it is:
     CnrSelectedElementId

2) Add a handler to the container that will update this attribute as the
   selected element in the container changes.  In this example the handler class
   is called 'CnrSelectedElemHandler'.  This handler is a template class which
   takes 2 arguments:
   (a) the name of the (IWindow) class that contains the container control.
       (In this example it is the CanvasCnr class).
   (b) the (VisualBuilder generated) name of the container element type.
       Visual Builder creates a container type that includes a reference to the
       actual element type specified in IVBContainerControl's setttings
       notebook.  The definition of this class is in the header file of the
       class specified in argument (a).  This name can also be found using the
       following rule:
                <Name of Owner class> +
                <Name of container object in composition editor> +
                'CnrObj'.
       Eg.:  For this example, the owner class is called 'CanvasCnr' and
             in the composition editor my IVBContainerControl object is
             called 'VBContainerControl1'.  So the VisualBuilder generated
             name will be: 'CanvasCnrVBContainerControl1CnrObj'.

   The handler is added to the 'Handlers' page of the IVBContainerControl's
   settings notebook.  You add it using the following:
        CnrSelectedElemHandler<CnrOwnerClass, CnrObjClass>(this)
   or for this example:
        CnrSelectedElemHandler<CanvasCnr,
                               CanvasCnrVBContainerControl1CnrObj>(this)

3) Add the header file for the handler to the 'Required Header files' entry
   in the Class Editor (CNRHDR.HPP)

4) Instead of making the attribute-to-attribute connection from the
   'selectedElement' of the container to the variable on the free form surface,
   make an attribute-to-attribute connection to the attribute created in step 1.
   (You can also 'tear-off' the attribute created in step 1 and use the torn off
   variable in the same way as you would use a regular variable).

The zip file contains files for both Windows and OS/2.  There are 2 zip files:
Each contain the same files but for the respective OSes:

MAINWIN.VBB:            The VBB for the sample program.  It contains 2 parts:
                        - NVPart:   a non-visual part which is the element type
                                    of the container.
                        - CanvasCnr: a 1x1 MultiCellCanvas derived part which
                                     contains a container control with 1000
                                     elements of type NVPart*
                        - MainWin : a visual part which has a CanvasCnr part
                                    as the client.
MAINWIN.HPV,
MAINWIN.CPV:            The user specified files which contain the
                        initialization code for the part.

NVPART.HPV,
NVPART.CPV:             The user specified files which contain the
                        initialization code for the part along with the code
                        for the part's attributes


CNRHDR.HPP:             The header file for the container handler that updates
                        the CnrSelectedElement attribute of the MainWin visual
                        part

NOTE: the CNRHDR.HPP file is the same for both OS/2 and windows.

To build the examples for both OS/2 and windows follow the steps below:
1) Start the visual builder
2) Load MAINWIN.VBB
3) Generate Part source for both NVPart and MainWin parts
4) Generate main() source for the MainWin part.
5) Build the main program by using the following command line:
        nmake /a mainwin.mak
6) Run MAINWIN.EXE to see the handler in action.


--

VisualAge for C++
http://www.software.ibm.com/ad/visualage_c++
