Click here to Skip to main content
15,887,683 members
Articles / Containers / Virtual Machine

TOOL

Rate me:
Please Sign up or sign in to vote.
4.98/5 (52 votes)
23 Oct 200676 min read 230.4K   5.4K   147  
TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language interpreter. The purpose of this article is to introduce the TOOL interpreter and language from the perspective of a person who has a desire to include a scripting solution as part of his project.
/*****************************************************************************/
/*                              SOURCE FILE                                  */
/*****************************************************************************/
/*
          $Archive:   $

         $Revision:   $

      Last Checkin:
             $Date:   $
                By:
           $Author:   $

 Last Modification:
          $ModTime:   $

       Description:   Declaration of a mixin class that allows its parent window
                      (and all of its child controls) to be dynamically switched
                      at runtime.

                      TOOL And XML FORMS License
                      ==========================

                      Except where otherwise noted, all of the documentation 
                      and software included in the TOOL package is 
                      copyrighted by Michael Swartzendruber.

                      Copyright (C) 2005 Michael John Swartzendruber. 
                      All rights reserved.

                      Access to this code, whether intentional or accidental,
                      does NOT IMPLY any transfer of rights.

                      This software is provided "as-is," without any express 
                      or implied warranty. In no event shall the author be held
                      liable for any damages arising from the use of this software.

                      Permission is granted to anyone to use this software for 
                      any purpose, including commercial applications, and to 
                      alter and redistribute it, provided that the following 
                      conditions are met:

                      1. All redistributions of source code files must retain 
                         all copyright notices that are currently in place, 
                         and this list of conditions without modification.

                      2. The origin of this software must not be misrepresented;
                         you must not claim that you wrote the original software.

                      3. If you use this software in another product, an acknowledgment
                         in the product documentation would be appreciated but is
                         not required.

                      4. Modified versions in source or binary form must be plainly 
                         marked as such, and must not be misrepresented as being 
                         the original software.
*/
static char OBJECT_ID[] = "$Revision:   $ : $JustDate:   $";
/*****************************************************************************/

#include "stdafx.h"
#include "XMLFormControls.h"
#include "XMLFormComboBox.h"
#include "XMLFormColorizedTree.h"
#include "XMLFormMultiColumnSortList.h"
#include "XMLFormSpinButton.h"
#include "XMLFormCalendarControl.h"
#include "XMLFormIPAddressEntryControl.h"
#include "XMLFormTimeEntryControl.h"
#include "XMLFormSliderButton.h"
#include "XMLFormBMPImage.h"
#include "XMLFormFileDirBrowseCtrl.h"
#include "XMLFormWindow.h"
#include "XMLFormControlFactory.h"


#pragma warning( disable : 4786 )


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif



/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::CXMLFormControlFactory

       DESCRIPTION:  ctor

             INPUT:  poParent - pointer to parent window for the controls from the
                                dialog's resource definition
            OUTPUT:  

           RETURNS:  void
*/
CXMLFormControlFactory::CXMLFormControlFactory( CWnd* poParent ) 
:  m_poCurPageList( NULL )
{
  ASSERT( poParent );
  m_poParent = poParent;

  if ( IsRunningOnLowResolutionScreen() || IsRunningLargeFonts() )
  {
    m_bLowResScreen = true;
  }
  else
  {
    m_bLowResScreen = false;
  }
}
/* End of function "CXMLFormControlFactory::CXMLFormControlFactory"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::~CXMLFormControlFactory

       DESCRIPTION:  deletes all allocations made here

             INPUT:  none
            OUTPUT:  none

           RETURNS:  none
*/
CXMLFormControlFactory::~CXMLFormControlFactory( void )
{
  DestroyAllControls();
}
/* End of function "CXMLFormControlFactory::~CXMLFormControlFactory"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::IsRunningLargeFonts

       DESCRIPTION:  determines if the os is running large fonts

             INPUT:  void
            OUTPUT:  none

           RETURNS:  true if it is, false if not
*/
bool CXMLFormControlFactory::IsRunningLargeFonts( void )
{
  bool bResult = false;
  HWND hWnd = ::GetDesktopWindow();
  HDC  hDC  = ::GetWindowDC( hWnd );
  if ( hDC )
  {
    long lPrevMapMode = ::SetMapMode( hDC, MM_TEXT );
    TEXTMETRIC xTextMetrics;

    ::GetTextMetrics( hDC, &xTextMetrics );
    ::SetMapMode( hDC, lPrevMapMode );

    if ( xTextMetrics.tmHeight > 16 )
    {
      SIZE  xSize;

      ::GetTextExtentPoint32( hDC, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &xSize );

      m_iBaseUnitX = ( xSize.cx / 26 + 1 ) / 2;
      m_iBaseUnitY = xTextMetrics.tmHeight;

      bResult = true;
    }
    else
    {
      bResult = false;
    }
  }
  ::ReleaseDC( hWnd, hDC );
  return bResult;
}
/* End of function "CXMLFormControlFactory::IsRunningLargeFonts"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::IsRunningOnLowResolutionScreen

       DESCRIPTION:  determines if the system is running on a low res screen

             INPUT:  void
            OUTPUT:  none

           RETURNS:  true if it is, false if not
*/
bool CXMLFormControlFactory::IsRunningOnLowResolutionScreen( void )
{
  HWND    hwnd  = ::GetDesktopWindow();
  HDC     hdc   = ::GetWindowDC( hwnd );
  int     iHorz = ::GetDeviceCaps( hdc, HORZRES );
  int     iVert = ::GetDeviceCaps( hdc, VERTRES );
  int     iText = ::GetDeviceCaps( hdc, LOGPIXELSY );

  ::ReleaseDC( hwnd, hdc );

  if ( iHorz <= 800 || iVert <= 600 )
  {
    return true;
  }
  else
  {
    return false;
  }
}
/* End of function "CXMLFormControlFactory::IsRunningOnLowResolutionScreen"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CXMLFormControlFactory::DLGUNIT_TO_PIXEL_X

       DESCRIPTION:  performs coordinate conversion for the x dimension for
                     control location

             INPUT:  iTemplateXValue - the x value from the template file 
            OUTPUT:  none

           RETURNS:  the scaled value for the input value
*/
inline int CXMLFormControlFactory::DLGUNIT_TO_PIXEL_X( int iTemplateXValue )
{
  if ( m_bLowResScreen )
  {
    return ( iTemplateXValue * m_iBaseUnitX ) / 6;
  }
  else
  {
    return ( iTemplateXValue * LOWORD( ::GetDialogBaseUnits() ) ) / 5;
  }
}
/* End of function "CXMLFormControlFactory::DLGUNIT_TO_PIXEL_X"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  CXMLFormControlFactory::DLGUNIT_TO_PIXEL_Y

       DESCRIPTION:  performs coordinate conversion for the y dimension for
                     control location

             INPUT:  iTemplateXValue - the x value from the template file 
            OUTPUT:  none

           RETURNS:  the scaled value for the input value
*/
inline int CXMLFormControlFactory::DLGUNIT_TO_PIXEL_Y( int dlgY ) 
{
  if ( m_bLowResScreen )
  {
    return ( dlgY * m_iBaseUnitY ) / 12;
  }
  else
  {
    return ( dlgY * HIWORD( ::GetDialogBaseUnits() ) ) / 10;
  }
}
/* End of function "CXMLFormControlFactory::DLGUNIT_TO_PIXEL_Y"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::SetFormDefinition

       DESCRIPTION:  iterates over the form definition creating the controls
                     and the structures to track them

             INPUT:  poFormDefinition - pointer to a form definition object
            OUTPUT:  none

           RETURNS:  void
*/
void CXMLFormControlFactory::SetFormDefinition( PROP_PAGE_LIST* poFormDefinition )
{
  PROP_PAGE_LIST_ITER oIter;
  for ( oIter = poFormDefinition->begin(); oIter != poFormDefinition->end(); oIter++ )
  {
    // for each sheet in the form definition
    //
    int               iFormID = (*oIter).first;
    P_FORM_DEFINITION pxForm  = (*oIter).second;
 
    // create the container that allows this to track the controls created for the
    // form
    //
    CTRL_LIST* poCtrlList = new CTRL_LIST;

    // associate this list of controls with this sheet in the form
    //
    m_oPageMap.insert( PAGE_CTRL_MAP::value_type( iFormID, poCtrlList ) );

    // for each control in the sheet definition
    // 
    FORM_CONTROL_SET_ITER oCtrlIter;
    for ( oCtrlIter  = pxForm->m_oControlsSet.begin(); 
          oCtrlIter != pxForm->m_oControlsSet.end();
          oCtrlIter++ )
    {
      // call on subordinate to create the window from the control definition
      // then save that control in the collection of controls for the current
      // sheet
      //
      CWnd* poNewCtrl = MakeControlFromDefinition( *oCtrlIter );
      if ( NULL != poNewCtrl )
      {
        poCtrlList->push_back( poNewCtrl );
      }
    } 
  }
}
/* End of function "CXMLFormControlFactory::SetFormDefinition"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::MakeControlFromDefinition

       DESCRIPTION:  One of the main work-horses of this class. This method
                     looks at the contents of the control definition and sets
                     up the actual window accordingly

             INPUT:  pxCtrl - pointer to form control definition
            OUTPUT:  none

           RETURNS:  pointer to window created according to control def'n
*/
CWnd* CXMLFormControlFactory::MakeControlFromDefinition( P_FORM_CONTROL pxCtrl )
{
  CWnd* poResult = NULL;

  // Set the position for this control
  //
  CRect oPosition( pxCtrl->m_xLocation.left, 
                   pxCtrl->m_xLocation.top,
                   pxCtrl->m_xLocation.right,
                   pxCtrl->m_xLocation.bottom );

  // NOTE: All controls are created with WS_CHILD 'force on to the style' in case
  //       user forgot to add that one in the xml -- it is pretty important that
  //       that value is in the style is why it is forced there. All controls are
  //       also created as not visible initially, because they are made visible by
  //       the selection of the property sheet they belong to -- see method (below):
  //       SetCurrentPropertyPage( UINT iPropPageID )
  //
  switch( pxCtrl->m_eCtrlType )
  {
    case eImage:
    {
       CXMLFormImageSource* poImageSource;
       switch( pxCtrl->m_eImageSourceType )
       {
         case eLocalResource:
           poImageSource = new CXMLFormResourceImageSource( pxCtrl->m_dwImageType );
         break;

         case eFromLocalFile:
           poImageSource = new CXMLFormLocalFileImageSource( pxCtrl->m_dwImageType );
         break;

         case eFromNetFile:
           poImageSource = new CXMLFormNetworkFileImageSource( pxCtrl->m_dwImageType );
         break;
      }

      poResult = new CXMLFormBMPImage( m_poParent, 
                                       poImageSource, 
                                       XMLFORM_IMAGE_AUTODELETE + XMLFORM_IMAGE_STRETCHED
                                       + XMLFORM_IMAGE_CENTERED );
      pxCtrl->m_poControl = poResult;

      ((CStatic*)poResult)->Create( NULL, 
                                    WS_CHILD | WS_THICKFRAME & ~WS_VISIBLE, 
                                    oPosition, 
                                    m_poParent, 
                                    pxCtrl->m_iCtrlID );
    }
    break;

    case eTabCtrl:
    {
      poResult = new CTabCtrl;
      pxCtrl->m_poControl = poResult;


      ((CTabCtrl*)poResult)->Create( pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | TCS_FIXEDWIDTH | TCS_TABS | WS_CLIPSIBLINGS, // | TCS_FOCUSNEVER, 
                                     oPosition, 
                                     m_poParent, 
                                     pxCtrl->m_iCtrlID );
      int iLoop = 0;
      STRING_POINTER_ARRAY_ITER oIter;
      for ( oIter  = pxCtrl->m_oSeedData.begin();
            oIter != pxCtrl->m_oSeedData.end();
            oIter++ )
      {
        TC_ITEM xTabItem;

        xTabItem.mask    = TCIF_TEXT;
        xTabItem.pszText = (char*)(*oIter)->c_str();

        ((CTabCtrl*)poResult)->InsertItem( iLoop, &xTabItem );
        iLoop++;
      }

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eMoneyEdit:
    {
      bool bHasToolTip = false;

      poResult = new CXMLFormMoneyEdit;

      ((CXMLFormMoneyEdit*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormMoneyEdit*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      pxCtrl->m_poControl = poResult;

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      // for some bizarre reason, must use CreateEx on edits to get the 3-d look
      //
      ((CEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                   _T( "EDIT" ), 
                                   oInitialValue.c_str(), 
                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL, 
                                   oPosition, 
                                   m_poParent, 
                                   pxCtrl->m_iCtrlID );
      ((CXMLFormMoneyEdit*)poResult)->CreateToolTip();

      ((CXMLFormMoneyEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormMoneyEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormMoneyEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormMoneyEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eNumericEdit:
    {
      bool bHasToolTip = false;

      poResult = new CXMLFormNumericEdit;

      ((CXMLFormNumericEdit*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormNumericEdit*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      pxCtrl->m_poControl = poResult;

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      // for some bizarre reason, must use CreateEx on edits to get the 3-d look
      //
      ((CEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                   _T( "EDIT" ), 
                                   oInitialValue.c_str(), 
                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL, 
                                   oPosition, 
                                   m_poParent, 
                                   pxCtrl->m_iCtrlID );
      ((CXMLFormNumericEdit*)poResult)->CreateToolTip();

      ((CXMLFormNumericEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormNumericEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormNumericEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormNumericEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eAlphaEdit:
    {
      bool bHasToolTip = false;

      poResult = new CXMLFormAlphaEdit;

      ((CXMLFormAlphaEdit*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormAlphaEdit*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      pxCtrl->m_poControl = poResult;

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      // for some bizarre reason, must use CreateEx on edits to get the 3-d look
      //
      ((CEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                   _T( "EDIT" ), 
                                   oInitialValue.c_str(), 
                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL, 
                                   oPosition, 
                                   m_poParent, 
                                   pxCtrl->m_iCtrlID );
      ((CXMLFormAlphaEdit*)poResult)->CreateToolTip();

      ((CXMLFormAlphaEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormAlphaEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormAlphaEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormAlphaEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eAlphaNumericEdit:
    {
      bool bHasToolTip = false;

      poResult = new CXMLFormAlphaNumericEdit;

      ((CXMLFormAlphaNumericEdit*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormAlphaNumericEdit*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      pxCtrl->m_poControl = poResult;

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      // for some bizarre reason, must use CreateEx on edits to get the 3-d look
      //
      ((CEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                   _T( "EDIT" ), 
                                   oInitialValue.c_str(), 
                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL, 
                                   oPosition, 
                                   m_poParent, 
                                   pxCtrl->m_iCtrlID );
      ((CXMLFormAlphaNumericEdit*)poResult)->CreateToolTip();

      ((CXMLFormAlphaNumericEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormAlphaNumericEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormAlphaNumericEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormAlphaNumericEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eFloatEdit:
    {
      bool bHasToolTip = false;

      poResult = new CXMLFormFloatEdit;

      ((CXMLFormFloatEdit*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormFloatEdit*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      pxCtrl->m_poControl = poResult;

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      // for some bizarre reason, must use CreateEx on edits to get the 3-d look
      //
      ((CEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                   _T( "EDIT" ), 
                                   oInitialValue.c_str(), 
                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL, 
                                   oPosition, 
                                   m_poParent, 
                                   pxCtrl->m_iCtrlID );
      ((CXMLFormFloatEdit*)poResult)->CreateToolTip();

      ((CXMLFormFloatEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormFloatEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormFloatEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormFloatEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eIntegerEdit:
    {
      bool bHasToolTip = false;

      poResult = new CXMLFormIntegerEdit;

      ((CXMLFormIntegerEdit*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormIntegerEdit*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      pxCtrl->m_poControl = poResult;

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      // for some bizarre reason, must use CreateEx on edits to get the 3-d look
      //
      ((CEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                   _T( "EDIT" ), 
                                   oInitialValue.c_str(), 
                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL, 
                                   oPosition, 
                                   m_poParent, 
                                   pxCtrl->m_iCtrlID );
      ((CXMLFormIntegerEdit*)poResult)->CreateToolTip();

      ((CXMLFormIntegerEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormIntegerEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormIntegerEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormIntegerEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

#ifndef TOOL_PUBLIC_BUILD
    case eHtmlCtrl:
    {
      poResult   = new CQhtmWnd;
      pxCtrl->m_poControl = poResult;

      poResult->m_hWnd = CreateWindowEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                         QHTM_CLASSNAME, 
                                         NULL, 
                                         pxCtrl->m_dwStyle & ~WS_VISIBLE | WS_BORDER | WS_CHILD, 
                                         oPosition.left, 
                                         oPosition.top, 
                                         oPosition.right - oPosition.left, 
                                         oPosition.bottom - oPosition.top, 
                                         m_poParent->m_hWnd, 
                                         (HMENU)NULL, 
                                         AfxGetInstanceHandle(), 
                                         NULL );

      // create window ex does not allow specification of ctrl id ??? 
      // okay, so that is another strange anomoly of win api, but the
      /// line below fixes that problem up
      //
      poResult->SetDlgCtrlID( pxCtrl->m_iCtrlID );

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      if ( strlen( oInitialValue.c_str() ) )
      {
        ((CQhtmWnd*)poResult)->LoadFromFile( oInitialValue.c_str() );
      }
      else
      {
        // if no initial data, then throw 'something meaningful' at 
        // the control
        //
        char achBlank[] = "<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.0 Transitional//EN>"
                          "<html>"
                          "<head>"
                          "<title>"
                          "No Data Yet"
                          "</title>"
                          "</head>"
                          "<body>"
                          "<center>"
                          "No Data To Display Yet"
                          "</center>"
                          "</body>"
                          "</html>";

        ((CQhtmWnd*)poResult)->AddHTML( achBlank, 1 );
      }
    }
    break;
#endif

    case eCheckBox:
    case eRadioButton:
    case eButton:
    {
      poResult = new CXMLFormButton;
      pxCtrl->m_poControl = poResult;

      std::string oCaption = *( *( pxCtrl->m_oSeedData.begin() ) );
      DWORD  dwStyle       = pxCtrl->m_dwStyle;

      // make sure the appropriate button style is on the control
      //
      if ( pxCtrl->m_eCtrlType == eButton )
      {
        dwStyle |= BS_PUSHBUTTON;
      }
      else
      if ( pxCtrl->m_eCtrlType == eCheckBox )
      {
        dwStyle |= BS_AUTOCHECKBOX | BS_PUSHBUTTON;
      }
      else
      if ( pxCtrl->m_eCtrlType == eRadioButton )
      {
        dwStyle |= BS_AUTORADIOBUTTON | BS_PUSHBUTTON;
        if ( pxCtrl->m_iGroupID == pxCtrl->m_iCtrlID )
        {
          // for radio buttons whose control ID is same as group ID,
          // means that this radio button is the start of a radio group
          //
          dwStyle |= WS_GROUP;
        }
      }
      if ( eButton == pxCtrl->m_eCtrlType )
      {
        ((CXMLFormButton*)poResult)->Create( oCaption.c_str(), 
                                             dwStyle | WS_CHILD & ~WS_VISIBLE | BS_OWNERDRAW, 
                                             oPosition, 
                                             m_poParent, 
                                             pxCtrl->m_iCtrlID );
        ((CXMLFormButton*)poResult)->Attach( pxCtrl->m_iCtrlID, m_poParent, pxCtrl->m_xBackColor, pxCtrl->m_xTextColor );
        ((CXMLFormButton*)poResult)->SetColors( pxCtrl->m_xBackColor, pxCtrl->m_xTextColor );
      }
      else
      {
        ((CButton*)poResult)->Create( oCaption.c_str(), 
                                      dwStyle | WS_CHILD & ~WS_VISIBLE, 
                                      oPosition, 
                                      m_poParent, 
                                      pxCtrl->m_iCtrlID );
      }

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eEditCtrl:
    {
      bool bHasToolTip = false;

      poResult = new CXMLFormEdit;

      ((CXMLFormEdit*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormEdit*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      pxCtrl->m_poControl = poResult;

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      if ( pxCtrl->m_dwStyle & ES_MULTILINE ) 
      { 
        if ( pxCtrl->m_dwStyle & ES_AUTOHSCROLL )
        {
          pxCtrl->m_dwStyle |= WS_HSCROLL;
        }
        if ( pxCtrl->m_dwStyle & ES_AUTOVSCROLL )
        {
          pxCtrl->m_dwStyle |= WS_VSCROLL;
        }
      }

      // for some bizarre reason, must use CreateEx on edits to get the 3-d look
      //
      ((CEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                   _T( "EDIT" ), 
                                   oInitialValue.c_str(), 
                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL, 
                                   oPosition, 
                                   m_poParent, 
                                   pxCtrl->m_iCtrlID );
      ((CXMLFormEdit*)poResult)->CreateToolTip();

      ((CXMLFormEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eCardTrackDataCtrl:
    {
      bool bHasToolTip = false;

      poResult = new CXMLFormSwipeEdit;

      ((CXMLFormSwipeEdit*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormSwipeEdit*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      pxCtrl->m_poControl = poResult;

      std::string oInitialValue;
      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        oInitialValue = pxCtrl->m_oInitialValue;
      }
      else
      {
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
      }

      // for some bizarre reason, must use CreateEx on edits to get the 3-d look
      //
      ((CEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                   _T( "EDIT" ), 
                                   oInitialValue.c_str(), 
                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL | ES_AUTOHSCROLL | ES_WANTRETURN | ES_MULTILINE, 
                                   oPosition, 
                                   m_poParent, 
                                   pxCtrl->m_iCtrlID );

      ((CEdit*)poResult)->SetLimitText( 255 );
      ((CXMLFormSwipeEdit*)poResult)->CreateToolTip();
      ((CXMLFormSwipeEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormSwipeEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormSwipeEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormSwipeEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eSubForm:
    case eLabelBox:
    {
      std::string oCaption = *( *( pxCtrl->m_oSeedData.begin() ) );
      DWORD  dwStyle = pxCtrl->m_dwStyle;

      poResult = new CXMLFormGroupBox;
      pxCtrl->m_poControl = poResult;

      DWORD dwShowStyle = dwStyle | WS_CHILD | BS_GROUPBOX;

      if ( eSubForm != pxCtrl->m_eCtrlType )
      {
        dwShowStyle &= ~WS_VISIBLE;
        pxCtrl->m_bForcedHidden = true;
      }
      else
      {
        // this makes sub-form group boxes invisible
        //
        dwShowStyle |= WS_CLIPSIBLINGS | BS_OWNERDRAW;
        ((CXMLFormGroupBox*)poResult)->TreatAsSubform();
      }

      ((CButton*)poResult)->Create( oCaption.c_str(), 
                                    dwShowStyle, 
                                    oPosition, 
                                    m_poParent, 
                                    pxCtrl->m_iCtrlID );
     
      ((CXMLFormGroupBox*)poResult)->SetBackgroundColor( ((CXMLFormWindow*)m_poParent)->GetBackgroundColor() );
      ((CXMLFormGroupBox*)poResult)->SetTextColor( ((CXMLFormWindow*)m_poParent)->GetTextColor() );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }

      if ( eSubForm == pxCtrl->m_eCtrlType )
      {
        poResult->ModifyStyleEx( 0, WS_EX_DLGMODALFRAME );
        std::vector < struct _tagAFormControl* >::iterator oIter;

        for ( oIter  = pxCtrl->m_oSubFormControls.begin();
              oIter != pxCtrl->m_oSubFormControls.end();
              oIter++ )
        {
          (*oIter)->m_bForcedHidden = true;

          MakeControlFromDefinition( (*oIter) );
          if ( (*oIter)->m_poControl != NULL )
          {
            if ( IsWindow( (*oIter)->m_poControl->m_hWnd ) )
            {
//              (*oIter)->m_poControl->ShowWindow( SW_HIDE );
              CWnd* poOwner = m_poParent->GetDlgItem( pxCtrl->m_iBuddyID );
              if ( poOwner )
              {
                (*oIter)->m_poControl->SetOwner( poOwner );
              }
            }
          }
        }
      }
    }
    break;

    case eStaticText:
    {
      poResult = new CStatic;
      pxCtrl->m_poControl = poResult;

      std::string oCaption = *( *( pxCtrl->m_oSeedData.begin() ) );
      ((CStatic*)poResult)->Create( oCaption.c_str(), 
                                    pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE, 
                                    oPosition, 
                                    m_poParent, 
                                    pxCtrl->m_iCtrlID );
      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eListBox:
    {
      poResult = new CXMLFormListBox;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormListBox*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormListBox*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      ((CListBox*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE,
                                       _T( "LISTBOX" ), 
                                       _T( "" ), 
                                       pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | LBS_SORT | WS_VSCROLL | LBS_EXTENDEDSEL, 
                                       oPosition, 
                                       m_poParent, 
                                       pxCtrl->m_iCtrlID );
      STRING_POINTER_ARRAY_ITER oIter;
      for ( oIter  = pxCtrl->m_oSeedData.begin();
            oIter != pxCtrl->m_oSeedData.end();
            oIter++ )
      {
        ((CXMLFormListBox*)poResult)->AddString( (*oIter)->c_str() );
      }

      INT_ARRAY_ITER oItemDataIter;
      int            iLoop = 0;
      for ( oItemDataIter  = pxCtrl->m_oItemData.begin();
            oItemDataIter != pxCtrl->m_oItemData.end();
            oItemDataIter++ )
      {
        ((CXMLFormListBox*)poResult)->SetItemData( iLoop, (DWORD)(*oItemDataIter) );
        iLoop++;
      }

      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        int iIndex = ((CXMLFormListBox*)poResult)->FindStringExact( -1, pxCtrl->m_oInitialValue.c_str() );
        if ( LB_ERR != iIndex )
        {
          ((CXMLFormListBox*)poResult)->SetSel( iIndex ); 
        }
        else
        {
          bool        bCanConvert = true;
          const char* pchValue    = pxCtrl->m_oInitialValue.c_str();
          int         iTop        = strlen( pchValue );
 
          for ( int iLoop = 0; iLoop < iTop && bCanConvert; iLoop++ )
          {
            if ( !isdigit( *(pchValue + iLoop ) ) )
            {
              bCanConvert = false;
            }
          }
          if ( bCanConvert )
          {
            iIndex = atoi( pchValue );
            ((CXMLFormListBox*)poResult)->SetSel( iIndex );
          }
        }
      }
      ((CXMLFormListBox*)poResult)->CreateToolTip();

      ((CXMLFormListBox*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormListBox*)poResult)->SetTextColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eHScroll:
    case eVScroll:
    {

      DWORD dwType = pxCtrl->m_eCtrlType == eHScroll ? SBS_HORZ : SBS_VERT;

      poResult = new CXMLFormScrollBar;
      pxCtrl->m_poControl = poResult;

      ((CScrollBar*)poResult)->Create( pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | dwType, 
                                       oPosition, 
                                       m_poParent, 
                                       pxCtrl->m_iCtrlID );

      ((CScrollBar*)poResult)->SetScrollRange( pxCtrl->m_iMinRangeValue, 
                                               pxCtrl->m_iMaxRangeValue );

      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        bool        bCanConvert = true;
        const char* pchValue    = pxCtrl->m_oInitialValue.c_str();
        int         iTop        = strlen( pchValue );
 
        for ( int iLoop = 0; iLoop < iTop && bCanConvert; iLoop++ )
        {
          if ( !isdigit( *(pchValue + iLoop ) ) )
          {
            bCanConvert = false;
          }
        }
        if ( bCanConvert )
        {
          int iIndex = atoi( pchValue );
          ((CScrollBar*)poResult)->SetScrollPos( iIndex );
        }
      }
    }
    break;

    case eComboBox:
    {
      poResult = new CXMLFormSuperComboBox;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormSuperComboBox*)poResult)->SetDDVHandler( pxCtrl->m_pxMyDDV );
      ((CXMLFormSuperComboBox*)poResult)->SetDDXHandler( pxCtrl->m_pxMyDDX );

      ((CXMLFormSuperComboBox*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormSuperComboBox*)poResult)->SetTextColor( pxCtrl->m_xTextColor );

      DWORD dwStyle;

      if ( pxCtrl->m_bCanEditCombo == true )
      {
        // editable
        //
        dwStyle = pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE & ~CBS_SIMPLE & ~CBS_DROPDOWNLIST | CBS_DROPDOWN | CBS_HASSTRINGS;
      }
      else
      {
        // not editable
        //
        dwStyle = pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE & ~CBS_SIMPLE | CBS_DROPDOWNLIST | CBS_DROPDOWN | CBS_HASSTRINGS;
      }

      ((CXMLFormSuperComboBox*)poResult)->Create( dwStyle, 
                                                  oPosition, 
                                                  m_poParent, 
                                                  pxCtrl->m_iCtrlID );
      STRING_POINTER_ARRAY_ITER oIter;
      for ( oIter  = pxCtrl->m_oSeedData.begin();
            oIter != pxCtrl->m_oSeedData.end();
            oIter++ )
      {
        ((CXMLFormSuperComboBox*)poResult)->AddString( (*oIter)->c_str() );
      }

      INT_ARRAY_ITER oItemDataIter;
      int            iLoop = 0;
      for ( oItemDataIter  = pxCtrl->m_oItemData.begin();
            oItemDataIter != pxCtrl->m_oItemData.end();
            oItemDataIter++ )
      {
        DWORD dwItemData = (DWORD)(*oItemDataIter);
        ((CXMLFormSuperComboBox*)poResult)->SetItemData( iLoop, dwItemData );
        iLoop++;
      }

      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        int iIndex = ((CXMLFormSuperComboBox*)poResult)->FindStringExact( -1, pxCtrl->m_oInitialValue.c_str() );
        if ( CB_ERR != iIndex )
        {
          ((CXMLFormSuperComboBox*)poResult)->SetCurSel( iIndex ); 
        }
        else
        {
          bool        bCanConvert = true;
          const char* pchValue    = pxCtrl->m_oInitialValue.c_str();
          int         iTop        = strlen( pchValue );
 
          for ( int iLoop = 0; iLoop < iTop && bCanConvert; iLoop++ )
          {
            if ( !isdigit( *(pchValue + iLoop ) ) )
            {
              bCanConvert = false;
            }
          }
          if ( bCanConvert )
          {
            iIndex = atoi( pchValue );
            ((CXMLFormSuperComboBox*)poResult)->SetCurSel( iIndex );
          }
        }
      }
      ((CXMLFormSuperComboBox*)poResult)->CreateToolTip();

      if ( pxCtrl->m_bCustomFont )
      {
        ((CXMLFormSuperComboBox*)poResult)->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eSpinButton:
    {
      poResult = new CXMLFormSpinButton;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormSpinButton*)poResult)->Create( pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE, 
                                               oPosition, 
                                               m_poParent, 
                                               pxCtrl->m_iCtrlID );

      ((CXMLFormSpinButton*)poResult)->SetRange( pxCtrl->m_iMinRangeValue,
                                                 pxCtrl->m_iMaxRangeValue );

      ((CXMLFormSpinButton*)poResult)->SetBuddyValueType( pxCtrl->m_eBuddyType );
      ((CXMLFormSpinButton*)poResult)->SetPrecision( pxCtrl->m_iPrecision );

      CWnd* poBuddy = m_poParent->GetDlgItem( pxCtrl->m_iBuddyID );
      if ( poBuddy != NULL )
      {
        ((CXMLFormSpinButton*)poResult)->SetBuddy( poBuddy );
        ((CXMLFormEdit*)poBuddy)->AssignBuddy( poResult );
      }
    }
    break;

    case eTreeCtrl:
    {
      poResult = new CXMLFormColorizedTree;
      pxCtrl->m_poControl = poResult;

      ((CTreeCtrl*)poResult)->Create( pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE 
                                         | TVS_NOTOOLTIPS | TVS_DISABLEDRAGDROP | BS_OWNERDRAW, // stamp these defaults on to the tree
                                      oPosition, 
                                      m_poParent, 
                                      pxCtrl->m_iCtrlID );


      CString oNodeText;
      oNodeText = _T( "Root" );
      ((CXMLFormColorizedTree*)poResult)->AddItemToTree( TVI_ROOT, (char*)(const char*)oNodeText, 0, 1, 0  );

      // now add an initial data to the control
      //
      bool                      bHasItemData = pxCtrl->m_oItemData.size() > 0;
      STRING_POINTER_ARRAY_ITER oIter;
      INT_ARRAY_ITER            oItemDataIter;

      if ( bHasItemData )
      {
        oItemDataIter  = pxCtrl->m_oItemData.begin();
      }

      for ( oIter  = pxCtrl->m_oSeedData.begin();
            oIter != pxCtrl->m_oSeedData.end();
            oIter++ )
      {
        ((CXMLFormColorizedTree*)poResult)->AddPath( (*oIter)->c_str() );

        if ( bHasItemData )
        {
          if ( oItemDataIter != pxCtrl->m_oItemData.end() )
          {
            CString   oPath( (*oIter)->c_str() );
            int       iItemData = (*oItemDataIter);

            HTREEITEM hRoot = ((CXMLFormColorizedTree*)poResult)->GetRootItem();

            HTREEITEM hTreeNode = ((CXMLFormColorizedTree*)poResult)->FromPath( hRoot, oPath );

            ((CXMLFormColorizedTree*)poResult)->SetItemData( hTreeNode, (DWORD)iItemData );

            oItemDataIter++;
          }
        }
      }

      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        HTREEITEM hRoot = ((CXMLFormColorizedTree*)poResult)->GetRootItem();
        HTREEITEM hItem = ((CXMLFormColorizedTree*)poResult)->FromPath( hRoot, 
                                                                        CString( pxCtrl->m_oInitialValue.c_str() ) );
        ((CXMLFormColorizedTree*)poResult)->SelectItem( hItem );

      }
      ((CXMLFormColorizedTree*)poResult)->CreateToolTip();
      ((CXMLFormColorizedTree*)poResult)->SetBackgroundColor( pxCtrl->m_xBackColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eDateTimePicker:
    {
      poResult = new CXMLFormDateTimeEdit;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormDateTimeEdit*)poResult)->CreateEx( pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                                   _T( "EDIT" ), 
                                                   "", 
                                                   pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL | WM_VSCROLL, 
                                                   oPosition, 
                                                   m_poParent, 
                                                   pxCtrl->m_iCtrlID );

      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        COleDateTime oDate;
        oDate.ParseDateTime( pxCtrl->m_oInitialValue.c_str(), VAR_TIMEVALUEONLY );
        ((CXMLFormDateTimeEdit*)poResult)->SetDateTime( oDate );
      }
      else
      if ( pxCtrl->m_oSeedData.begin() != pxCtrl->m_oSeedData.end() )
      {
        std::string oInitialValue;
        oInitialValue = *( *( pxCtrl->m_oSeedData.begin() ) );
        COleDateTime oDate;
        oDate.ParseDateTime( oInitialValue.c_str(), VAR_TIMEVALUEONLY );
        ((CXMLFormDateTimeEdit*)poResult)->SetDateTime( oDate );
      }
      else
      {
        ((CXMLFormDateTimeEdit*)poResult)->SetDateTime( COleDateTime::GetCurrentTime() );
      }

      ((CXMLFormDateTimeEdit*)poResult)->CreateToolTip();

      ((CXMLFormDateTimeEdit*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormDateTimeEdit*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormDateTimeEdit*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormDateTimeEdit*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eMonthCalender:
    {
      poResult = new CXMLFormCalendarControl;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormCalendarControl*)poResult)->Create( pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE, 
                                                    oPosition, 
                                                    m_poParent, 
                                                    pxCtrl->m_iCtrlID );

      ((CXMLFormCalendarControl*)poResult)->CreateToolTip();

      SYSTEMTIME xDate;
      GetLocalTime( &xDate );

      if ( eMonthCalender == pxCtrl->m_eCtrlType )
      {
        ((CXMLFormCalendarControl*)poResult)->SetFormat( _T( "MM/dd/yyyy" ) );
      }
      else
      {
        ((CXMLFormCalendarControl*)poResult)->SetFormat( _T( "hh:mm:ss" ) );
      }
      ((CXMLFormCalendarControl*)poResult)->SetTime( &xDate );

      ((CXMLFormCalendarControl*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormCalendarControl*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormCalendarControl*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormCalendarControl*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eFilePicker:
    {
      poResult = new CXMLFormFileDirBrowseCtrl;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormFileDirBrowseCtrl*)poResult)->Create( oPosition, 
                                                      m_poParent, 
                                                      pxCtrl->m_iCtrlID );
      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
      ((CXMLFormFileDirBrowseCtrl*)poResult)->SetOpenSave( TRUE );                         // TRUE-"open", FALSE-"save as"
      ((CXMLFormFileDirBrowseCtrl*)poResult)->SetDefExt( NULL );                           // Do not use any default extension
      ((CXMLFormFileDirBrowseCtrl*)poResult)->SetFilter( _T( "All Files (*.*)|*.*||" ) );
      ((CXMLFormFileDirBrowseCtrl*)poResult)->SetFileFlags( OFN_FILEMUSTEXIST | OFN_HIDEREADONLY );
      ((CXMLFormFileDirBrowseCtrl*)poResult)->SetPathName( _T( "c:\\" ) );                 // default path
    }
    break;

    case eDirPicker:
    {
      poResult = new CXMLFormFileDirBrowseCtrl;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormFileDirBrowseCtrl*)poResult)->Create( oPosition, 
                                                      m_poParent, 
                                                      pxCtrl->m_iCtrlID );
      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
      DWORD dwStyle  = ((CXMLFormFileDirBrowseCtrl*)poResult)->GetButtonStyle();
            dwStyle |=  BC_BTN_ICON;         // Make sure to display icon instead of text
            dwStyle &= ~BC_BTN_FLAT;         // Not a Flat button
            dwStyle |=  BC_ICO_FOLDER;
            dwStyle &= ~BC_ICO_EXPLORER;     
            dwStyle &= ~BC_ICO_ARROWFOLDER;  // select the icon
            dwStyle |=  BC_CTL_FOLDERSONLY;  // Browse for folders only
            dwStyle |=  BC_CTL_ALLOWEDIT;    // allow edit of path

      ((CXMLFormFileDirBrowseCtrl*)poResult)->SetButtonStyle( dwStyle );
      ((CXMLFormFileDirBrowseCtrl*)poResult)->SetFolderFlags( BIF_EDITBOX | BIF_RETURNONLYFSDIRS & ~BIF_NONEWFOLDERBUTTON );       // Display an editbox on the dialog
      ((CXMLFormFileDirBrowseCtrl*)poResult)->SetFolderDialogTitle( _T( "Please select a folder" ) );
    }
    break;

    case eIPAddress:
    {
      poResult = new CXMLFormIPAddressControl;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormIPAddressControl*)poResult)->Create( pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | WS_TABSTOP | WS_CLIPCHILDREN, 
                                                     oPosition, 
                                                     m_poParent, 
                                                     pxCtrl->m_iCtrlID );


      if ( pxCtrl->m_oSeedData.begin() != pxCtrl->m_oSeedData.end() )
      {
        std::string oInitialValue;
        oInitialValue        = *( *( pxCtrl->m_oSeedData.begin() ) );
        const char* pchValue = oInitialValue.c_str();
 
        bool      bIsGoodParse = true;
        IPA_ADDR  xAddress;

        char* pchToken     = (char*)pchValue;
        char* pchNextDelim = strchr( pchToken, '.' );

        if ( NULL != pchNextDelim )
        {
          *pchNextDelim   = 0;
          xAddress.nAddr1 = atoi( pchToken );
          *pchNextDelim   = '.';
          pchToken        = pchNextDelim + 1;
        }
        else
        {
          bIsGoodParse = false;
        }
    
        if ( true == bIsGoodParse )
        {
          char* pchNextDelim = strchr( pchToken, '.' );

          if ( NULL != pchNextDelim )
          {
            *pchNextDelim   = 0;
            xAddress.nAddr2 = atoi( pchToken );
            *pchNextDelim = '.';
            pchToken = pchNextDelim + 1;
          }
          else
          {
            bIsGoodParse = false;
          }
        } 

        if ( true == bIsGoodParse )
        {
          char* pchNextDelim = strchr( pchToken, '.' );

          if ( NULL != pchNextDelim )
          {
            *pchNextDelim   = 0;
            xAddress.nAddr3 = atoi( pchToken );
            *pchNextDelim = '.';
            pchToken = pchNextDelim + 1;
          }
          else
          {
            bIsGoodParse = false;
          }
        } 

        if ( true == bIsGoodParse )
        {
          char achLastOctet[ 4 ];
          memset( achLastOctet, 0, 4 );
          strncpy( achLastOctet, pchToken, min( 3, strlen( pchToken ) ) );
          xAddress.nAddr4 = atoi( achLastOctet );
        }

        if ( bIsGoodParse )
        {
          ((CXMLFormIPAddressControl*)poResult)->SetAddress( &xAddress );
        }
      }

      ((CXMLFormIPAddressControl*)poResult)->CreateToolTip();

      ((CXMLFormIPAddressControl*)poResult)->SetBackColor( pxCtrl->m_xBackColor );
      ((CXMLFormIPAddressControl*)poResult)->SetBackFocusColor( pxCtrl->m_xBackColor );
      ((CXMLFormIPAddressControl*)poResult)->SetTextColor( pxCtrl->m_xTextColor );
      ((CXMLFormIPAddressControl*)poResult)->SetTextFocusColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eSlideCtrl:
    {
      poResult = new CXMLFormSliderButton;
      pxCtrl->m_poControl = poResult;

      ((CXMLFormSliderButton*)poResult)->Create( FALSE,
                                                 pxCtrl->m_dwExStyle | WS_EX_CLIENTEDGE, 
                                                 "", 
                                                 pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | ES_NOHIDESEL, 
                                                 oPosition, 
                                                 m_poParent, 
                                                 pxCtrl->m_iCtrlID );

      ((CXMLFormSliderButton*)poResult)->SetRange( 0,
                                                   pxCtrl->m_iMinRangeValue,
                                                   pxCtrl->m_iMaxRangeValue );

      if ( 0 != pxCtrl->m_oInitialValue.size() )
      {
        bool        bCanConvert = true;
        const char* pchValue    = pxCtrl->m_oInitialValue.c_str();
        int         iTop        = strlen( pchValue );
 
        for ( int iLoop = 0; iLoop < iTop && bCanConvert; iLoop++ )
        {
          if ( !isdigit( *(pchValue + iLoop ) ) )
          {
            bCanConvert = false;
          }
        }
        if ( bCanConvert )
        {
          int iIndex = atoi( pchValue );
          ((CXMLFormSliderButton*)poResult)->SetPos( iIndex );
        }
      }

        // mjs: set color here
    }
    break;

    case eListCtrl:
    {
      poResult = new CXMLFormMultiColumnSortList;
      
      ((CXMLFormMultiColumnSortList*)poResult)->SetGridLines( pxCtrl->m_bShowGridLines );
      pxCtrl->m_poControl = poResult;

      ((CListCtrl*)poResult)->Create( pxCtrl->m_dwStyle | WS_CHILD & ~WS_VISIBLE | LVS_REPORT, 
                                      oPosition, 
                                      m_poParent, 
                                      pxCtrl->m_iCtrlID );
      int iLoop = 0;
      STRING_POINTER_ARRAY_ITER oIter;
      for ( oIter  = pxCtrl->m_oColumnNames.begin();
            oIter != pxCtrl->m_oColumnNames.end();
            oIter++ )
      {
        const char* pchColInfo  = (*oIter)->c_str();
        char*       pchHatAt    = strchr( pchColInfo, '^' );
        double      dblColWidth = 100;
        if ( NULL != pchHatAt )
        {
          *pchHatAt = 0;
          pchHatAt++;
          dblColWidth = oPosition.Width() * atof( pchHatAt );
        }

        // first add the columns to the control
        //
        ((CListCtrl*)poResult)->InsertColumn( iLoop, pchColInfo, LVCFMT_LEFT, static_cast<int>(dblColWidth), 0 );	// 2b|!2b==?

        iLoop++;
      }

      // now add an initial data to the control
      //
      bool                      bHasItemData = pxCtrl->m_oItemData.size() > 0;
      INT_ARRAY_ITER            oItemDataIter;

      if ( bHasItemData )
      {
        oItemDataIter  = pxCtrl->m_oItemData.begin();
      }

      STRING_POINTER_ARRAY_ITER oValuesIter;
      for ( oValuesIter  = pxCtrl->m_oSeedData.begin();
            oValuesIter != pxCtrl->m_oSeedData.end();
            oValuesIter++ )
      {
        int          iIndex     = 0;
        int          iColumn    = 0;
        int          iLoop      = 0;
        const char*  pchRowData = (*oValuesIter)->c_str();
        int          iTop       = strlen( pchRowData );
        char         achCellValue[ 255 ];
        memset( achCellValue, 0, 255 );

        CXMLFormRowDataInfo* poRow = new CXMLFormRowDataInfo;
        poRow->m_bUseColumnData    = true;

        while ( iLoop < iTop )
        {
          if ( pchRowData[ iLoop ] == '|' )
          {
            // found new row marker, so:
            // a. insert the cell text into the current column
            // b. then reset the column counter
            // c. inc loop to skip the marker 
            // d. continue
            //
            poRow->m_oColumnData.insert( 
                COLUMN_VARIANT_DATA::value_type( iColumn, 
                   new XMLFormVariantData( achCellValue ) ) );

            ((CXMLFormMultiColumnSortList*)poResult)->AddItem( poRow );

            if ( bHasItemData )
            {
              if ( oItemDataIter != pxCtrl->m_oItemData.end() )
              {
                ((CXMLFormMultiColumnSortList*)poResult)->SetItemData( 0, (DWORD)(*oItemDataIter) );
                oItemDataIter++;
              }
            }

            memset( achCellValue, 0, 255 );

            iColumn = 0;
            iIndex  = 0;
            iLoop++;

            if ( iLoop < iTop )
            {
              // start a new row
              //
              poRow = new CXMLFormRowDataInfo;
              poRow->m_bUseColumnData = true;
            }
            continue;
          }
          else
          {
            if ( pchRowData[ iLoop ] == '^' )
            {
              // found new cell marker, so:
              // a. insert the cell text into the current column
              // b. then increment the column counter
              // c. inc loop to skip the marker 
              // d. continue
              //
              poRow->m_oColumnData.insert( 
                  COLUMN_VARIANT_DATA::value_type( iColumn, 
                     new XMLFormVariantData( achCellValue ) ) );

              memset( achCellValue, 0, 255 );
              iIndex  = 0;
              iColumn++;
              iLoop++;
              continue;
            }
            else
            {
              // copy the character to the cell value
              //
              achCellValue[ iIndex ] = pchRowData[ iLoop ];
              iIndex++;
            }
          }
          iLoop++;
        }
      }

      ((CXMLFormMultiColumnSortList*)poResult)->SetBackgroundColor( pxCtrl->m_xBackColor );
      ((CXMLFormMultiColumnSortList*)poResult)->SetTextColor( pxCtrl->m_xTextColor );

      if ( pxCtrl->m_bCustomFont )
      {
        poResult->SetFont( &pxCtrl->m_oFont );
      }
    }
    break;

    case eColorPicker:
    {
      poResult = NULL;
      pxCtrl->m_poControl = poResult;
    }
    break;
  }
  return poResult;
}
/* End of function "CXMLFormControlFactory::MakeControlFromDefinition"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::SetCurrentPropertyPage

       DESCRIPTION:  sets the current property page

             INPUT:  iPropPageID - the property page id for the page
            OUTPUT:  none

           RETURNS:  true if found/loaded false if not
*/
bool CXMLFormControlFactory::SetCurrentPropertyPage( UINT iPropPageID )
{
  PAGE_CTRL_MAP_ITER oIter;
  CTRL_LIST_ITER     oCtrlIter;

  oIter = m_oPageMap.find( iPropPageID );
  if ( oIter != m_oPageMap.end() )
  {
    // hide current controls before changing to next page
    //
    if ( NULL != m_poCurPageList )
    {
      for ( oCtrlIter = m_poCurPageList->begin(); oCtrlIter != m_poCurPageList->end(); oCtrlIter++ )
      {
        (*oCtrlIter)->ShowWindow( SW_HIDE );
      }
    }
    // change to this control list
    //
    m_poCurPageList = (*oIter).second;
    m_iCurrentPage  = iPropPageID;

    // make all controls visible from this list
    //
    for ( oCtrlIter = m_poCurPageList->begin(); oCtrlIter != m_poCurPageList->end(); oCtrlIter++ )
    {
      (*oCtrlIter)->ShowWindow( SW_SHOW );
    }
    return true;
  }
  else
  {
    // requested page was not found.....
    //
    // hide current controls....hopefully someone will figure out an error was made
    //
    if ( NULL != m_poCurPageList )
    {    
      for ( oCtrlIter = m_poCurPageList->begin(); oCtrlIter != m_poCurPageList->end(); oCtrlIter++ )
      {
       (*oCtrlIter)->ShowWindow( SW_HIDE );
      }

      // page is invalid now.
      // 
      m_poCurPageList = NULL;
    }
    return false;
  }
}
/* End of function "CXMLFormControlFactory::SetCurrentPropertyPage"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::GetWindowRect

       DESCRIPTION:  Given a window, gets the client rectangle for it

             INPUT:  poWindow - pointer to window
            OUTPUT:  none

           RETURNS:  CRect : the location of the given window
*/
CRect CXMLFormControlFactory::GetWindowRect( CWnd* poWindow )
{
  CRect oResult;

  poWindow->GetWindowRect( oResult );
  m_poParent->ScreenToClient( oResult );

  return oResult;
}
/* End of function "CXMLFormControlFactory::GetWindowRect"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::DestroyPropertyPage

       DESCRIPTION:  Destroy all the child windows associated with a property
                     sheet 

             INPUT:  iPropPageID - the ID of the property page to destroy
            OUTPUT:  none

           RETURNS:  void  
*/
void CXMLFormControlFactory::DestroyPropertyPage( UINT iPropPageID ) 
{
  CTRL_LIST_ITER       oCtrlsIter;
  PAGE_CTRL_MAP_ITER   oPagesIter;

  oPagesIter = m_oPageMap.find( iPropPageID );
  if ( oPagesIter != m_oPageMap.end() )
  {
    CTRL_LIST* poCtrls = (*oPagesIter).second;
    for ( oCtrlsIter = poCtrls->begin(); oCtrlsIter != poCtrls->end(); oCtrlsIter++ )
    {
      delete *oCtrlsIter;
    }
    poCtrls->clear();
    delete poCtrls;
    m_oPageMap.erase( oPagesIter );
  }  
}
/* End of function "CXMLFormControlFactory::DestroyPropertyPage"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  CXMLFormControlFactory::DestroyAllControls

       DESCRIPTION:  destroys all allocations made in this

             INPUT:  none
            OUTPUT:  none

           RETURNS:  void
*/
void CXMLFormControlFactory::DestroyAllControls( void )
{
  // Delete child windows for each property page
  //
  for ( PAGE_CTRL_MAP_ITER oPageIter = m_oPageMap.begin(); oPageIter != m_oPageMap.end(); oPageIter++ )
  {
    CTRL_LIST* poCtrls = (*oPageIter).second;
    for ( CTRL_LIST_ITER oCtrlsIter = poCtrls->begin(); oCtrlsIter != poCtrls->end(); oCtrlsIter++ )
    {
      delete *oCtrlsIter;
    }
    poCtrls->clear();
    delete poCtrls;
  }
  m_oPageMap.clear();


  for ( CTRL_LIST_ITER oCtrlsIter = m_oRootPageList.begin(); oCtrlsIter != m_oRootPageList.end(); oCtrlsIter++ )
  {
    delete *oCtrlsIter;
  }
  m_oRootPageList.clear();

  // Delete fonts
  //
  for ( FONT_LIST_ITER oFontIter = m_FontList.begin(); oFontIter != m_FontList.end(); oFontIter++ )
  {
    delete *oFontIter;
  }
  m_FontList.clear();
}
/* End of function "CXMLFormControlFactory::DestroyAllControls"
/*****************************************************************************/



/*****************************************************************************/
/* Check-in history 
   $WorkFile:   $
    $Archive:   $

 *$Log:   $
*/
/*****************************************************************************/


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions