XMLTags.cpp
上传用户:kj0090
上传日期:2007-03-02
资源大小:39k
文件大小:22k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /***********************************************************************
  2. *
  3. * This module is part of the XMLGUI system 
  4. *
  5. * File name:       XMLTags.cpp
  6. *
  7. * Creation date:   [15 AUGUST 2002] 
  8. *
  9. * Author(s):       [Kolosenko Ruslan]
  10. *
  11. * Description:     Implements the class XMLTags and descendants
  12. *
  13. **********************************************************************/
  14. #include "stdafx.h"
  15. #include "XMLTags.h"
  16. #ifdef _DEBUG
  17. #undef THIS_FILE
  18. static char THIS_FILE[]=__FILE__;
  19. #define new DEBUG_NEW
  20. #endif
  21. //////////////////////////////////////////////////////////////////////
  22. //   CXMLTag methods
  23. //////////////////////////////////////////////////////////////////////
  24. /**************************************************************************
  25. * Function     : CXMLTag::CXMLTag
  26. * Description  : Constructs CXMLTag object representing root tag
  27. *              : of the XML document
  28. * Arguments    : szXMLFile - pointer to a string specifying full name
  29. *              :    of the XML file, whose root tag is encapsulated
  30. *              :    in the CXMLTag object
  31. ***************************************************************************/
  32. CXMLTag::CXMLTag(LPCTSTR szXMLFile)
  33. {
  34.     HRESULT hr;   // result descriptor for COM operations
  35.        // initialize COM if necessary
  36.     static HRESULT hCOMInitialized = ::CoInitialize(NULL);
  37.        // set initial values for members - COM interface pointers
  38.     m_pXMLDocument = NULL;
  39.     m_pXMLElement  = NULL;
  40.     
  41.        // create COM object representing XML document
  42.     hr = CoCreateInstance(CLSID_XMLDocument,NULL,CLSCTX_SERVER,IID_IXMLDocument,
  43.         (void**)&m_pXMLDocument);
  44.     WATCH_XML_EXCEPTION(hr);
  45.        // initialize the created COM object from the specified XML file
  46.     _bstr_t strXMLFile(szXMLFile);
  47.     hr = m_pXMLDocument->put_URL(strXMLFile.copy());
  48.     WATCH_XML_EXCEPTION(hr);
  49.        // retrieve the root tag of the document and save its pointer
  50.     hr = m_pXMLDocument->get_root(&m_pXMLElement);
  51.     WATCH_XML_EXCEPTION(hr);
  52. }
  53. /**************************************************************************
  54. * Function     : CXMLTag::CXMLTag
  55. * Description  : Constructs CXMLTag object representing any XML tag node
  56. * Arguments    : pXMLElement - pointer to the COM interface of the XML element
  57. *              :    corresponding to the node being encapsulated
  58. ***************************************************************************/
  59. CXMLTag::CXMLTag(IXMLElement* pXMLElement)
  60. {
  61.        // set initial values for members - COM interface pointers
  62.     HRESULT hr;
  63.     m_pXMLDocument = NULL;
  64.     m_pXMLElement  = NULL;
  65.        // retrieve IXMLElement interface pointer of the specified XML node
  66.        // this also increments reference count for the XML element COM object
  67.     hr = pXMLElement->QueryInterface(IID_IXMLElement,(void**)&m_pXMLElement);
  68.     WATCH_XML_EXCEPTION(hr);
  69. }
  70. /**************************************************************************
  71. * Function     : CXMLTag::~CXMLTag
  72. * Description  : Destructor
  73. ***************************************************************************/
  74. CXMLTag::~CXMLTag()
  75. {
  76.        // release all used COM interfaces
  77.     if ( m_pXMLDocument ) m_pXMLDocument->Release();
  78.     if ( m_pXMLElement )  m_pXMLElement->Release();
  79. }
  80. /**************************************************************************
  81. * Function     : CXMLTag::GetTitle
  82. * Description  : Returns name of the XML tag
  83. * Return value : string containing the name of the XML tag
  84. ***************************************************************************/
  85. _bstr_t CXMLTag::GetTitle()
  86. {
  87.     HRESULT hr;
  88.     BSTR bszTagName;
  89.        // retrieve tag name from the encapsulated COM object
  90.     hr = m_pXMLElement->get_tagName(&bszTagName);
  91.     _bstr_t strTagName(bszTagName);
  92.        // return obtained COM string converted to _bstr_t object
  93.     return strTagName;
  94. }
  95. /**************************************************************************
  96. * Function     : CXMLTag::GetText
  97. * Description  : Returns text inside the XML tag
  98. * Return value : string containing the text inside the XML tag,
  99. *              : if the tag doesn't contain any text - empty string is returned
  100. ***************************************************************************/
  101. _bstr_t CXMLTag::GetText()
  102. {
  103.     HRESULT hr;
  104.     BSTR bszTagText;
  105.        // retrieve text from the encapsulated COM object
  106.     hr = m_pXMLElement->get_text(&bszTagText);
  107.     _bstr_t strTagText(bszTagText);
  108.        // return obtained COM string converted to _bstr_t object
  109.     return strTagText;
  110. }
  111. /**************************************************************************
  112. * Function     : CXMLTag::GetAttributeInt
  113. * Description  : Returns value of the specified tag's attribute converted
  114. *              : to numeric representation
  115. * Return value : numeric representation of the attribute value,
  116. *              : if the tag doesn't contain such attribute or its value
  117. *              : cannot be converted to number - zero is returned
  118. * Arguments    : szAttributeName - pointer to a string containing the name
  119. *              :    of the attribute whose value is retrieved
  120. ***************************************************************************/
  121. int CXMLTag::GetAttributeInt(LPCTSTR szAttributeName)
  122. {
  123.     HRESULT hr;
  124.     VARIANT attributeValue;
  125.     int nAttributeValue = 0;  // default value, it is returned if attribute not present
  126.        // build COM string wrapper with the attribute name
  127.     _bstr_t strAttributeName(szAttributeName);
  128.        // retrieve attribute value from the encapsulated COM object
  129.     hr = m_pXMLElement->getAttribute(strAttributeName.copy(),&attributeValue);
  130.     if ( SUCCEEDED(hr) )
  131.     {
  132.            // if value obtained - convert in to numeric representation
  133.         nAttributeValue = GetIntegerValue(attributeValue);
  134.     }
  135.        // return result of conversion or zero if attribute not found
  136.     return nAttributeValue;
  137. }
  138. /**************************************************************************
  139. * Function     : CXMLTag::GetAttributeString
  140. * Description  : Returns value of the specified tag's attribute converted
  141. *              : to string representation
  142. * Return value : string representation the attribute value,
  143. *              : if the tag doesn't contain such attribute - empty string
  144. *              : is returned
  145. * Arguments    : szAttributeName - pointer to a string containing the name
  146. *              :    of the attribute whose value is retrieved
  147. ***************************************************************************/
  148. _bstr_t CXMLTag::GetAttributeString(LPCTSTR szAttributeName)
  149. {
  150.     HRESULT hr;
  151.     VARIANT attributeValue;
  152.     _bstr_t strAttributeValue;   // default value is empty string,
  153.                        // it is returned if attribute not present
  154.        // build COM string wrapper with the attribute name
  155.     _bstr_t strAttributeName(szAttributeName);
  156.        // retrieve attribute value from the encapsulated COM object
  157.     hr = m_pXMLElement->getAttribute(strAttributeName.copy(),&attributeValue);
  158.     if ( SUCCEEDED(hr) )
  159.     {
  160.            // if value obtained - convert in to string representation
  161.         strAttributeValue = GetStringValue(attributeValue);
  162.     }
  163.        // return resulting string
  164.     return strAttributeValue;
  165. }
  166. /**************************************************************************
  167. * Function     : CXMLTag::GetIntegerValue
  168. * Description  : Converts value of VARIANT object to integer number
  169. * Return value : numberic representation of the VARIANT object's value,
  170. *              : if the value cannot be converted to an integer number -
  171. *              : zero is returned
  172. * Arguments    : var - VARIANT object whose value is converted
  173. ***************************************************************************/
  174. /*static*/ int CXMLTag::GetIntegerValue(VARIANT var)
  175. {
  176.        // build COM wrappers for VARIANT structure and its string value
  177.     _variant_t vart(var);
  178.     _bstr_t strt = (_bstr_t)vart;
  179.        // return string value of the VARIANT object converted to int type
  180.     return atoi((const char*)strt);
  181. }
  182. /**************************************************************************
  183. * Function     : CXMLTag::GetStringValue
  184. * Description  : Converts value of VARIANT object to CString object
  185. * Return value : string representation of the VARIANT object's value,
  186. *              : if the value cannot be converted to a string -
  187. *              : empty string is returned
  188. * Arguments    : var - VARIANT object whose value is converted
  189. ***************************************************************************/
  190. /*static*/ _bstr_t CXMLTag::GetStringValue(VARIANT var)
  191. {
  192.        // build COM wrappers for VARIANT structure and its string value
  193.     _variant_t vart(var);
  194.     _bstr_t strt = (_bstr_t)vart;
  195.        // return string value of retrieved from the COM string wrapper
  196.     return strt;
  197. }
  198. //////////////////////////////////////////////////////////////////////
  199. //   CXMLStylableTag methods
  200. //////////////////////////////////////////////////////////////////////
  201. /**************************************************************************
  202. * Function     : CXMLStylableTag::CXMLStylableTag
  203. * Description  : Constructs CXMLStylableTag object representing root tag
  204. *              : of the XML document
  205. * Arguments    : szXMLFile - pointer to a string specifying full name
  206. *              :    of the XML file, whose root tag is encapsulated
  207. *              :    in the CXMLStylableTag object
  208. ***************************************************************************/
  209. CXMLStylableTag::CXMLStylableTag(LPCTSTR szXMLFile) : CXMLTag(szXMLFile)
  210. {
  211.        // initialize member variables with empty style values
  212.     m_nStyles        = 0;
  213.     m_nExStyles      = 0;
  214. }
  215. /**************************************************************************
  216. * Function     : CXMLStylableTag::CXMLStylableTag
  217. * Description  : Constructs CXMLStylableTag object representing any XML tag node
  218. * Arguments    : pXMLElement - pointer to the COM interface of the XML element
  219. *              :    corresponding to the node being encapsulated
  220. ***************************************************************************/
  221. CXMLStylableTag::CXMLStylableTag(IXMLElement* pXMLElement) : CXMLTag(pXMLElement)
  222. {
  223.        // initialize member variables with empty style values
  224.     m_nStyles        = 0;
  225.     m_nExStyles      = 0;
  226. }
  227. /**************************************************************************
  228. * Function     : CXMLStylableTag::ParseStylesAttribute
  229. * Description  : Parses string specified in the "style" attribute and fills
  230. *              : member variables with window style and extended style values
  231. * Arguments    : pTagSpecificStyleSyntax - pointer to the syntax structure
  232. *              :    describing mapping of allowed styles in string representaion
  233. *              :    to Win32 style constants
  234. *              : pTagSpecificExStyleSyntax - pointer to the syntax structure
  235. *              :    describing mapping of allowed extended styles
  236. ***************************************************************************/
  237. void CXMLStylableTag::ParseStylesAttribute(
  238.                          LPXMLGUIStylesValues pTagSpecificStyleSyntax /*= NULL*/,
  239.                          LPXMLGUIStylesValues pTagSpecificExStyleSyntax /*= NULL*/)
  240. {
  241.        // retrieve styles in string representation
  242.     CString szStyles = (LPCTSTR)GetAttributeString(ATTRIBUTE_CONTROL_STYLE);
  243.     int nCurrPos = 0;   // counter for the current position in the string
  244.     int nStylesStringLen = szStyles.GetLength();   // total styles string length
  245.     
  246.     while ( nCurrPos < nStylesStringLen )   // lookup through all styles string
  247.     {
  248.            // find next delimiter ( comma by default )
  249.         int nNextPos = szStyles.Find(ATTVALUE_CONTROL_STYLE_DELIM,nCurrPos);
  250.            // calculate length of the next word describing one style
  251.         int nNextWordLen = nNextPos != -1 ? nNextPos - nCurrPos
  252.                                           : nStylesStringLen - nCurrPos;
  253.            // and obtain the word with one style name
  254.         CString szOneStyle = szStyles.Mid(nCurrPos,nNextWordLen);
  255.         nCurrPos += nNextWordLen+1;   // increase current position counter
  256.         if ( szOneStyle.IsEmpty() )
  257.         {
  258.             continue;   // if the found word is empty - go to the next one
  259.         }
  260.            // the meaning of the next variable is whether we have to set or to remove
  261.            // the corresponding style bit, true means to set, false - to remove
  262.            // bSetStyle will be assigned false if the style word is prefixed with "not "
  263.         bool bSetStyle = true;
  264.         if ( !_tcsncmp(szOneStyle,ATTVALUE_CONTROL_STYLE_PREFIX_NOT,
  265.                        _tcslen(ATTVALUE_CONTROL_STYLE_PREFIX_NOT)) )
  266.         {
  267.                // if prefix "not " found - remove it from the style word
  268.                // and set bSetStyle to false
  269.             szOneStyle = szOneStyle.Right(szOneStyle.GetLength() - 
  270.                 _tcslen(ATTVALUE_CONTROL_STYLE_PREFIX_NOT));
  271.             bSetStyle = false;
  272.         }
  273.            // now try to identify a Windows style constant corresponding
  274.            // to the current style word in string representation
  275.            // first - we look through common window styles list
  276.         DWORD nWin32Style = LookupStylesSet(g_CommonWindowStyles,
  277.             (LPCTSTR)szOneStyle);
  278.            // if the style is not found in the common window styles list -
  279.            // search control-specific styles list if any
  280.         if ( !nWin32Style && pTagSpecificStyleSyntax )
  281.         {
  282.             nWin32Style = LookupStylesSet(pTagSpecificStyleSyntax,(LPCTSTR)szOneStyle);
  283.         }
  284.            // if the style constant is found among simple window styles -
  285.            // set or clear the corresponding bit in m_nStyles variable
  286.         if ( nWin32Style )
  287.         {
  288.             if ( bSetStyle )
  289.             {
  290.                 m_nStyles |= nWin32Style;
  291.             }
  292.             else
  293.             {
  294.                 m_nStyles &= ~nWin32Style;
  295.             }
  296.             continue;   // the style is identified - procede to the next one
  297.         }
  298.            // the style was not found among simple window styles -
  299.            // now we search the constant in the list of extended styles
  300.         nWin32Style = LookupStylesSet(g_CommonWindowExStyles,
  301.             (LPCTSTR)szOneStyle);
  302.            // if the extended style wasn't found among common window ex.styles
  303.            // try to lookup control-specific extended styles list
  304.         if ( !nWin32Style && pTagSpecificExStyleSyntax )
  305.         {
  306.             nWin32Style = LookupStylesSet(pTagSpecificExStyleSyntax,(LPCTSTR)szOneStyle);
  307.         }
  308.            // if the style value is found among extended styles -
  309.            // set or clear the corresponding bit in m_nExStyles
  310.         if ( nWin32Style )
  311.         {
  312.             if ( bSetStyle )
  313.             {
  314.                 m_nExStyles |= nWin32Style;
  315.             }
  316.             else
  317.             {
  318.                 m_nExStyles &= ~nWin32Style;
  319.             }
  320.         }
  321.     }
  322. }
  323. /**************************************************************************
  324. * Function     : CXMLStylableTag::LookupStylesSet
  325. * Description  : Searches the specified syntax structure for the Windows
  326. *              : style constant corresponding to the given string representation
  327. * Return value : double word corresponding to the found Win32 window style or
  328. *              : zero if matching style was not found in the styles syntax
  329. * Arguments    : pStylesSet - pointer to the syntax structure
  330. *              :    describing mapping of allowed styles in string representaion
  331. *              :    to Win32 style constants
  332. *              : szStyle - string representation of a style whose value is searched
  333. ***************************************************************************/
  334. DWORD CXMLStylableTag::LookupStylesSet(LPXMLGUIStylesValues pStylesSet, LPCTSTR szStyle)
  335. {
  336.        // enumerate all available styles to identify the given string
  337.     int i = 0;
  338.     while ( _tcscmp(pStylesSet[i].szXMLGUIStyle,_T("")) )
  339.     {
  340.         if ( !_tcscmp(pStylesSet[i].szXMLGUIStyle,szStyle) )
  341.         {
  342.                // if style name found in the syntax structure -
  343.                // return the corresponding style bit
  344.             return pStylesSet[i].nWin32Style;
  345.         }
  346.         i++;   // if style name mismatches - try next
  347.     }
  348.     return 0;   // corresponding style string was not found - returning zero
  349. }
  350. //////////////////////////////////////////////////////////////////////
  351. //   CXMLDialogTag methods
  352. //////////////////////////////////////////////////////////////////////
  353. /**************************************************************************
  354. * Function     : CXMLDialogTag::CXMLDialogTag
  355. * Description  : Constructs CXMLDialogTag object representing root <DIALOG> tag
  356. *              : of the XML document
  357. * Arguments    : szXMLFile - pointer to a string specifying full name
  358. *              :    of the XML file, whose root <DIALOG> tag is encapsulated
  359. *              :    in the CXMLDialogTag object
  360. ***************************************************************************/
  361. CXMLDialogTag::CXMLDialogTag(LPCTSTR szXMLFile) : CXMLStylableTag(szXMLFile)
  362. {
  363.        // parse string of dialog's styles and fill member variables
  364.     ParseStylesAttribute(g_DialogStyles,NULL);
  365. }
  366. /**************************************************************************
  367. * Function     : CXMLDialogTag::CXMLDialogTag
  368. * Description  : Constructs CXMLDialogTag object representing <DIALOG> tag node
  369. * Arguments    : pXMLElement - pointer to the COM interface of the XML element
  370. *              :    corresponding to the node being encapsulated
  371. ***************************************************************************/
  372. CXMLDialogTag::CXMLDialogTag(IXMLElement* pXMLElement) : CXMLStylableTag(pXMLElement)
  373. {
  374.        // parse string of dialog's styles and fill member variables
  375.     ParseStylesAttribute(g_DialogStyles,NULL);
  376. }
  377. //////////////////////////////////////////////////////////////////////
  378. //   CXMLControlTag methods
  379. //////////////////////////////////////////////////////////////////////
  380. /**************************************************************************
  381. * Function     : CXMLControlTag::CXMLControlTag
  382. * Description  : Constructs CXMLControlTag object representing <CONTROL>
  383. *              : XML tag node
  384. * Arguments    : pXMLElement - pointer to the COM interface of the XML element
  385. *              :    corresponding to the node being encapsulated
  386. ***************************************************************************/
  387. CXMLControlTag::CXMLControlTag(IXMLElement* pXMLElement) : CXMLStylableTag(pXMLElement)
  388. {
  389.        // set initial values for class variables
  390.     m_pControlSyntax = NULL;
  391.     m_bActiveX       = FALSE;
  392.        // identify control's class
  393. _bstr_t strXMLGUIClass = GetAttributeString(ATTRIBUTE_CONTROL_CLASS);
  394.     if ( !strXMLGUIClass )
  395.     {
  396.         throw CXMLParsingException(
  397.             _T("Invalid GUI description file - control with no class attribute"));
  398.     }
  399.     int i = 0;
  400.     if ( wcscmp((const wchar_t*)strXMLGUIClass,ATTVALUE_CONTROL_ACTIVEX) )
  401.     {
  402.            // for standard Windows controls (not OLE controls) try to identify
  403.            // predefined window class using XMLGUI syntax mapping structure
  404.         while ( wcscmp(g_ControlsSyntax[i].szXMLGUIName,L"") )
  405.         {
  406.             if ( !wcscmp(g_ControlsSyntax[i].szXMLGUIName,(const wchar_t*)strXMLGUIClass) )
  407.             {
  408.                    // if class name found in the syntax structure - remember
  409.                    // pointer to the control's syntax
  410.                 m_pControlSyntax = &g_ControlsSyntax[i];
  411.                 break;
  412.             }
  413.             i++;   // if class name mismatches try next syntax structure
  414.         }
  415.     }
  416.     else
  417.     {
  418.            // for OLE controls there's no predefined window class,
  419.            // we just set the ActiveX control flag
  420.         m_bActiveX = TRUE;
  421.     }
  422.        // default styles for any control is "child" and "visible"
  423.     m_nStyles = WS_CHILD|WS_VISIBLE;
  424. if ( m_pControlSyntax )
  425.     {
  426.            // if the control syntax structure found - add the corresponding
  427.            // default styles mask for the control's window class
  428.         m_nStyles |= m_pControlSyntax->nDefWindowStyles;
  429.     }
  430.        // parse string of control's styles and fill member variables
  431.     ParseStylesAttribute(m_pControlSyntax ? m_pControlSyntax->controlStylesSet : NULL,
  432.                          m_pControlSyntax ? m_pControlSyntax->controlExStylesSet : NULL);
  433. }
  434. /**************************************************************************
  435. * Function     : CXMLControlTag::GetWindowClass
  436. * Description  : Returns string describing window class for the control
  437. * Return value : string containing the window class for the control
  438. ***************************************************************************/
  439. _bstr_t CXMLControlTag::GetWindowClass()
  440. {
  441. if ( m_bActiveX )
  442.     {
  443.            // OLE controls should store CLSID in the DLGITEMTEMPLATE structure
  444.            // instead of window class name - return value of "clsid" attribute
  445.         return GetAttributeString(ATTRIBUTE_CONTROL_CLSID);
  446.     }
  447.     else if ( m_pControlSyntax )
  448.     {
  449.            // if the control syntax structure found - return the corresponding
  450.            // Windows class name
  451.         return _bstr_t(m_pControlSyntax->szWindowClass);
  452.     }
  453.     else
  454.     {
  455.            // otherwise treat the value of the "class" attribute as a registered
  456.            // Windows class name - return it
  457.         return GetAttributeString(ATTRIBUTE_CONTROL_CLASS);
  458.     }
  459. }
  460. /**************************************************************************
  461. * Function     : CXMLControlTag::GetWindowClassOrdinal
  462. * Description  : Returns ordinal number of the registered window class
  463. *              : for the control
  464. * Return value : ordinal number of the control's window class
  465. ***************************************************************************/
  466. WORD CXMLControlTag::GetWindowClassOrdinal()
  467. {
  468. if ( m_pControlSyntax )
  469.     {
  470.            // if the control syntax structure found - return the corresponding
  471.            // ordinal value for Windows class
  472.         return m_pControlSyntax->nClassOrdinal;
  473.     }
  474.     else
  475.     {
  476.            // otherwise the control is not a standard windows control and there's
  477.            // no ordinal value for its class - class name should be used
  478.         return 0;
  479.     }
  480. }