/****************************************************************************\
*                                                                            *
*                            WinWidgets Version 3.0                          *
*                                                                            *
\****************************************************************************/

Congratulations on your purchase of WinWidgets 3.0!
                                     
This file contains information regarding:

  1)  New Features
  
      1.  New wrapper classes for XTable (the spreadsheet control)
      2.  Tab control classes.
      3.  New classes for subclassing VBX controls in forms.
      4.  New Directory structure and library names.
      5.  Miscellaneous new features/bug fixes
      
  2)  Documentation Changes
  3)  Errata and Updates
  4)  Planned Product Releases


Current users will find version 3.0 contains some terrific new controls such as:  
a tab control, spin control and a full-featured spreadsheet.  We have also 
improved the core controls, particularly the grid and edit control.  

Tech support questions and product feedback should be sent via fax to tech 
support at (718) 965-1740 or our CompuServe address 71542,1502.  Thank you for 
choosing WinWidgets/VBX!

************************************************************************
                          New Features/Bug Fixes
************************************************************************

/********************* 1. XTable Wrapper Classes*******************/
 
XTable, our spreadsheet control, is a highly capable and flexible 
spreadsheet that can be embedded in an application.  We have developed
three MFC-derived classes that will allow programmers to take full 
advantage of the XTable under MFC.

  Class                             BaseClass 

  CXTable,CXRecsetTable             CWnd
  CXTableView, CXRecsetTableView    CView
  CXTableVBX, CXRecsetTableVBX      CVBClone

Each of these classes contains an identical set of XTable API wrapper
member functions so once you are experienced with one of class, you
will already know how to use the other two.  The wrapper functions
are documented in the help file.  The differences among the three
classes are in the way they are treated by the rest of MFC.

CXTable is derived from CWnd.  It is a good class to use if you are
creating an XTable window on the fly from an existing object(use the
Create member function).  It is also useful if you wish to bind to an
item in a dialog that is not a VBX, a dialog created outside of
AppStudio, for instance (use the SubclassWindow member function).

CXTableView is derived from the CView class and can be used by MFC's
Document/View architecture similarly to any ordinary CView-derived
class. Using this class, you can create spreadsheets in MDI windows,
Splitter windows, or any other dynamically created view.  For those
familiar with our wrappers under WinWidgets version 2.01, please note
that unlike our CHGridView class where the View window contains a
separate Grid window, the XTableView window is, itself, an XTable so
the wrapper functions are member functions of the CXTableView
object.  If you used the CGridView object and were frustrated by
having to remember to access the m_pGrid member when making calls to 
our API, you will appreciate CXTableView.

CXTableVBX is derived from CVBClone.  CVBClone is a new class that we
are including with this version of WinWidgets for the first time. 
Originally released as a sample by Microsoft, CVBClone allows you to
actually subclass a VBX control using a C++ object, something that
was never possible using the CWnd class as a base class.  You should
use CXTableVBX when binding to an XTable in a dialog that was
designed using AppStudio (use the SubclassVBControl member
function).  Under previous versions of the wrappers, you would have
had to use our AttachToVBX member function, which only allowed access
to the wrapper API, but not to full MFC functionality.  CVBClone is
discussed in detail below.

All three classes handle event notifications from their associated
window.  Virtual functions are provided in each class.  You can
process events by simply deriving from CXTable, CXTableView, or
CXTableVBX and overriding these functions.  The table in the
SubclassVBX dialog in XTTEST.EXE contains an example of this.

Like the Grid, XTable provides record buffering capabilities.  Unlike
the Grid classes, CXTable and its View and VBX variants allow you to
access this functionality directly through virtual functions in the
classes, themselves.  There is no buffer object for XTable (Loud
cheers!).  The virtual functions are detailed in the "Using a Record
Buffer" topic under the XTable portion of the help file.  They are
also documeented inividually as XTable Events.  One late addition to
the buffering functions that is not in Record Buffer topic but IS
documented under XTable events is the RecInitFieldProps.  This is a
really cool function that lets you override the default field
creation entirely or in part when the XTable is associated with a
CRecordSet object.

Yes, thats right.  By using the CXRecsetTable and related objects,
you can associate the XTable objects with a CRecordSet object that 
you create using ClassWizard and XTable will create the fields for 
you and buffer records from the data set automatically.  See the XTTest 
sample we've included for an example of how this is done.  The key is 
to use the EnableBuffer menber function (sorry, it's not documented yet.)


  BOOL EnableBuffer(CRecordset* pSet, BOOL bEnable);
  
  
/********** Tab Dialog / Tab Child Dialog Classes **************/
/************** 2. Tab Control Wrapper Classes *****************/

Many people have asked if our Tab control can allow you to place
children directly onto the various tabs inside of AppStudio. 
Unfortunately, this is not possible until MFC and AppStudio can
emulate Visual Basic at a version 3.0 level.  We have provided an
reasonable alternative, however, in the form of two classes derived
from CDialog that will allow you to create a tabbed dialog from
existing dialogs that you create using AppStudio.  

The CTabDlg class is derived from CDialog.  CTabDialog owns a child
Tab control that it creates on the fly to "hold" other dialogs that 
you design.  CTabDlg manages the creation of the "inner dialogs" and
the processing of events generated by the Tab control, itself.  The
CTabDlgChild is also derived from CDialog.  It is used to create the
"inner dialogs" and manage their interaction with the Tab and the
TabDlg object.  Putting all this together in an application can be
summarized in a straight forward, step-by-step process:

1.  Inside AppStudio, design each page of the tab as a separate
dialog.  Make sure that the Child style is defined for these
dialogs.  It is also a good idea to turn OFF the Visible style in
order to minimize flash when these dialogs are created.  Also design
a separate dialog to hold the tab control.  We recommend that you
include OK and Cancel buttons on this dialog and not on the inner
dialogs, but you are free to do as you wish as long as you handle
the proper events.

2.  ClassWizard in AppStudio, derive classes for all of the dialogs
that you have created using CDialog as a base class.

3.  In your code, decide which object you want to initiate the tabbed
dialog.  This could be a view or perhaps the main application
window.  Inside this object's class declaration, declare the following
types of member variables:

	CMyTabDlg	m_TabDlg;   //Derived from CTabDlg

	CInnerDlg1	m_InnerDlg1 //Derived from CTabDlgChild
	CInnerDlg2	m_InnerDlg2
		    .
		    .
		    .

	CInnerDlgN	m_InnerDlgN
	 
In the example above, the tab dialog will contain N inner dialogs.

4.  Open each source and header file that you generated with
ClassWizard for your dialogs and REPLACE EVERY INSTANCE OF "CDialog"
with either "CTabDlg" (for the outer dialog) or "CTabDlgChild" for
the inner dialogs.  After doing this you can delete the *.CLW file in
your project's directory and bring up ClassWizard inside of
AppStudio. ClassWizard will generate a new CLW file that recognizes
your new base classes.   NOTE: You must bring up ClassWizard from
AppStudio and not from MSVC.  If you try to start ClassWizard from
MSVC, it will complain and fail to run. (Sometimes Visual C++ will
give you an incorrect message box telling you to open up ClassWizard
inside Visual C++ instead of AppStudio.  This is wrong.  Only in 
AppStudio can you regenerate a .CLW file.)  

5.  Override CTabDlg::PreCreateTabCtrlInit() to set certain
characteristics about the dynamically created tab control.  Use the
PreSetTabCtrl???() member functions to set values that will be passed
into the Create statement for the tab control.  Any other
initialization for the tab dialog should be done in OnInitDialog() of
your CTabDlg-derived class.

  void PreSetTabCtrlRect(const CRect& tabRect);	 
  void PreSetTabCtrlRect(const RECT tabRect);	 
  void PreSetTabCtrlText(const CString& tabText);
  void PreSetTabCtrlText(LPCSTR tabText);	 
  void PreSetTabCtrlStyle(const DWORD dwStyle);	 

6.  Handle any processing by the inner dialogs within the classes you
derived from CTabDlgChild.

7.  When you want to execute the Tabbed dialog from within your code,
you must first add the inner dialogs to the outer dialog's internal
list.  Then you can call CTabDlg::DoModeless.  For example,

   // add child tabs to tab dialog internal list
   m_MyTabDlg.AddChildDialog(CInnerDlg1::IDD, (CTabDlgChild*)&m_InnerDlg1);
   m_MyTabDlg.AddChildDialog(CInnerDlg2::IDD, (CTabDlgChild*)&m_InnerDlg2);
				.
				.
				.
   m_MyTabDlg.AddChildDialog(CInnerDlgN::IDD, (CTabDlgChild*)&m_InnerDlgN);

   // fire off tab dialog
   m_MyTabDlg.DoModeless(CMyTabDlg::IDD, this);  //second arg is the parent
	
	
Note that the tab dialog is executed as a modeless dialog so that it
can provide access to its inner dialogs.  The outer dialog does
disable its parent so as to appear modal within the application.  The
upshot is that you do not have direct knowledge of when the tab dialog
has been destroyed.

The CTabDlg object will send a message HAM_TABDLG_DONE (defined in
TABDLG.H) to its parent just prior to destruction. Each CTabDlgChild
object has a boolean member variable m_bActivated that is set to
FALSE when instantiated and then set to TRUE when the user first
activates the tab corresponding to that dialog.  If a tab is never
chosen, it's inner dialog is never created.

8.  CTabDlg does also provide a "modal" tab dialog which simulates
a normal modal dialog by disabling its ancestors and running its own
message loop.  The DoModal() member function has been overridden and
will not return until the tab dialog has been dismissed.  In reality,
the dialog is still being destroyed with DestroyWindow() since it
still is a modeless dialog, but to the programmer, it will behave
very similarly to the DoModal() member function of the CDialog class.


9.  There are also three notifications that the CTabDlg class gets
from its dynamically created tab control: HAN_INITIALIZE,
HAN_ACTIVATE, HAN_DEACTIVATE.  Member functions have been set up

   BEGIN_MESSAGE_MAP(CTabDlg, CDialog)
     //{{AFX_MSG_MAP(CTabDlg)
     //}}AFX_MSG_MAP
     ON_CONTROL(HAN_INITIALIZE,IDC_SS_TABCTRL, OnTabInitialize)
     ON_CONTROL(HAN_ACTIVATE,  IDC_SS_TABCTRL, OnTabActivate)
     ON_CONTROL(HAN_DEACTIVATE,IDC_SS_TABCTRL, OnTabDeactivate)
   END_MESSAGE_MAP()

for each of these notifications in CTabDlg which handle the
creation/activation/deactivation of its child dialogs.  Before
actually creating/activating/deactivating any child dialog, each
member function calls a virtual "notify" function which passes in the
tab number and a pointer to a CTabDlgChild object. If your
CTabDlg-derived class overrides these member functions, you have a
chance to respond to these event notifications.  Returning FALSE will
cancel that particular event and all subsequent events that are
triggered by it.


    afx_msg void OnTabInitialize();
    virtual BOOL OnTabInitializeNotify(int iTab, CTabDlgChild* pChild);
    afx_msg void OnTabActivate();                                    
    virtual BOOL OnTabActivateNotify(int iTab, CTabDlgChild* pChild);  
    afx_msg void OnTabDeactivate();                                  
    virtual BOOL OnTabDeactivateNotify(int iTab, CTabDlgChild* pChild);
 
 
10. To get a sense of how this is all put together, please take a
look at the TABDEMO sample in \WIDGETS\SAMPLES\TABDEMO.  It brings
up a sample tab dialog with three tabs as a modeless and as a modal
dialog.  In both cases the tab dialog is the child of the view class. 
Data is exchanged between the first tab child dialog and the view
class which updates the values in the view using plain TextOut
function calls in OnDraw().  When the tab dialog is modeless, the
data is updated every time the first tab is deactivated.  When the
tab dialog is modal, the data is not updated until the dialog is
dismissed with the OK button.  If the user presses the Cancel button,
the data changes are ignored.
  

/****************** 3. CVBClone Classes ****************************/

The CVBClone class is taken from an example released this year by
Microsoft.  This class provides the means to dynamically subclass a
VBX control through an C++ object. We here reproduce a portion of the
original readme file that came with the example.

>>
Windows controls, such as an edit control or a listbox control, can be
subclassed in MFC using the CWnd::SubclassWindow() and 
CWnd::SubclassDlgItem() functions.  These functions do not work for
VBX controls.  These functions rely on the fact that each window
control has its own windows procedure.  This way it is possible for
an MFC object to chain to controls original Windows procedure. 
However, VB controls under MFC 2.0 are managed by MFC objects.  So,
VB controls use the same windows procedure as all other MFC objects. 

In order to subclass a VB control in MFC 2.0 it is necessary to copy
the data from the original control object into the object that you
want to use to subclass the original control.  After the original
object has been copied, it can be detached and deleted, and the new
control object can be attached.  

This sample defines the CVBClone class that contains the function 
SubclassVBControl().  This function does the copying, attaching and 
detaching that is described above.  To use this class, derive a new 
class from the CVBClone class and new message handling functions to
the message map.  This class can then be used to subclass a VB
control in a dialog box by calling the SubclassVBControl() function
in the OnInitDialog() or OnInitialUpdate() function of the dialog box
or form view that contains the control.  
<<

We have derived new versions all of our wrapper classes from CVBClone.
The new class names are the same as the old names with "VBX" appended
(e.g. CHButt -> CHButtVBX)  If you wish to use these classes, you
must link to SUBVBL.LIB (large model) or SUBVBM.LIB (medium model). 
Instead of calling AttachToVBX, as you would in our CWnd-derived
classes, call SubclassVBControl.

  
  CVBClone :: SubclassVBControl()

  Purpose:  Copies data from an existing CVBControl class
            into this class.  It also detaches the old
            class and attaches this one.
                                                         
  Parameters:  CWnd* pParent     parent window of the control
               UINT  idChild     child window ID of control
               BOOL  bEmbedded   Inicates if contol is embedded
                                 in an object that will be 
                                 cleaned up or if this object
                                 should be deleted when the 
                                 control is deleted 



/*********************** 4. Directory Structure *********************/
 

WIDGETS       'Main WinWidgets Directory
  |
  \LIB        'Libraries (*.lib)
  \CPP        'C++ support 
     |
     \INCLUDE   'Include Files for Wrappers
     \SOURCE    '*.CPP files for Wrappers
        |
        \MFC      'Release makefiles
        \MFCD     'Debug makefiles


  
Wrapper Libraries:

MFCWDGL.LIB    
MFCWDGM.LIB
  Contents: All WinWidgets wrapper classes except for XTable
  Include: MFCWIDG.H
  Additional libraries required: WIDGETS.LIB, SUBVB(L/M).LIB (if using CVBClone classes)

MFCXTL.LIB    
MFCXTM.LIB
  Contents: XTable wrapper classes
  Include: MFCXTBL.H
  Additional libraries required: XTABLE.LIB, 
                                 SUBVB(L/M).LIB (if using CVBClone class),
                                 ODBC.LIB (if using CXRecsetTable and related classes)

SUBVBL.LIB    
SUBVBM.LIB
  Contents: CVBClone class
  Include: SUBVBCTL.H (already included by both MFCWIDG.H and MFCXTBL.H)
  Additional libraries required: none



!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!                                         
!THE WRAPPER LIBRARIES WE DISTRIBUTE ARE COMPILED IN RELEASE MODE.  TO COMPILE      
!AN APPLICATION WITH DEBUGGING INFORMATION, YOU MUST COMPILE AND LINK TO THE LIBRARIES
!IN THE MFCD SUBDIRECTORY.  LINKING A DEBUGGING VERSION OF YOUR APPLICATION TO RELEASE
!VERSIONS OF THESE LIBRARIES WILL FAIL.                         
!                                           
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


/******************* 5. New Features/Bug Fixes ************************/

Multiple Instances of WIDGEVB.VBX can now be run simultaneously under
VC++/MFC.  This means, among other things,  that you can now leave 
AppStudio running in the background while debugging your application.  

 Edit Control
+------------+
  - The edit control has min and max properties for dates and numbers.

 Grid Control
+------------+
  - The Fields property was not editable at design time

  - The argument type for HGM_SETVSCROLLPOS  is an INT, not a LONG.

  - Temporary memory leakage in bound Grids has been fixed.

  - HGM_ADDREC returns rowcount not row index

  - VB Grid Records property not documented (should be same as RowCount)


 Tab Control
+------------+

  - The control now fires events as documented

  - Disabled Tabs are now accessable at design time via the ActiveTab property

  - Transparent child controls now paint correctly in the Tab

  - Hidden and Disabled properties now set correctly


 XTable
+------+
  - entering negative numeric constants into formulas caused XTable to hang
  
  - very deep dependencies caused stack faults (significantly improved)

  - autoformatting of floats, formula results
  
  - non-implemented functions	have been implemented

  - loading speed has been improved

  - Usablility enhancements for design mode.



 ListBox
+-------+
  - occasional selection painting problems in exended and multi-select modes

  - VLSelectItem() was documented but unimplemented.  It is now implemented.


  - VLFindString has now been implemented; this was essentially just a semantic
    bug since you could alias VLFindString in WIDGEVB.TXT as VCFindString which
    has been implemented and exported like below:

    Declare Function VLFindString Lib "WidgeVB" Alias "VCFindString" 
    (ByVal hwnd As Integer, ByVal iStart As Integer, ByVal strItem As String) As Integer

    FindString Attribute for ListBox incorrectly has VLFindData
    listed instead of VLFindString.  The ComboBox VB entry is OK.


 ComboBox
+--------+
  - text appears 'underlined' for certain fonts in dropdown list variant

  - In Combo box under VB, TWO (Sel)Change events were fired when selecting with
    the mouse.  This did not happen when selecting with arrow keys, i.e.
    only one event is fired. The control now fires one event in all cases.
    A mouse click on the selected item generated one change event also.  This 
    has been fixed.

  - In "SelectString Method" for HComboBox, the C++ member function should be
    SelectString() not SelectData().


************************************************************************
                        Documentation Changes
************************************************************************
For the latest documentation, consult the on-line manual.  

XTable Insert and Delete events are fired once for each Row or Column
being inserted or deleted.  The manual implies that these events
are fired only once when the delete or insert key is pressed.

The Autoextend attribute in the XTable has not yet been implemented.




A new event in the VBX XTable called RecInitFieldProps has been introduced
to allow programmers to control the formatting of automatically created 
fields for bound tables.  This event is fired once for each field in the 
record; Fld indicates the field index (beginning at 0).  Various flags
can be logically Or'ed together to prevent the XTable from setting certain
attributes for these field, allowing predefined table attributes to take
precedence.  Alternatively, the XTable's default Field Width, Control Type, 
Horizontal Alignment, Locked Status, Format String, and Field Heading can be 
inspected and modified while processing this event.	

RecInitFieldProps (Fld As Integer, CancelFlags As Integer, FldWidth As Integer, 
                   CtrlType As Integer, AlignHorz As Integer, Locked As Integer, 
                   FormatString As String, FldHeading As String)

See the on-line manual for more information on this event.





************************************************************************
                       Future Releases
************************************************************************
WinWidgets 4.0 is already in its preliminary design phase.  This version 
will include OLE implementations of our controls and enhanced support
for internationalization.
