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

xml/soap/webservice

开发平台:

C/C++

  1. /***********************************************************************
  2. *
  3. * This module is part of the XMLGUI system 
  4. *
  5. * File name:       DlgItemTemplate.cpp
  6. *
  7. * Creation date:   [12 AUGUST 2002] 
  8. *
  9. * Author(s):       [Kolosenko Ruslan]
  10. *
  11. * Description:     Implements the class CDlgItemTemplate
  12. *
  13. **********************************************************************/
  14. #include "stdafx.h"
  15. #include "DlgItemTemplate.h"
  16. #include "XMLTags.h"
  17. #include <afxpriv.h>
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[]=__FILE__;
  21. #define new DEBUG_NEW
  22. #endif
  23. //////////////////////////////////////////////////////////////////////
  24. // Construction/Destruction
  25. //////////////////////////////////////////////////////////////////////
  26. /**************************************************************************
  27. * Function     : CDlgItemTemplate::CDlgItemTemplate
  28. * Description  : Constructor
  29. ***************************************************************************/
  30. CDlgItemTemplate::CDlgItemTemplate()
  31. {
  32.     m_pWinTemplate  = NULL;
  33.     m_pInitData     = NULL;
  34.     m_bIsActiveX    = FALSE;
  35. }
  36. /**************************************************************************
  37. * Function     : CDlgItemTemplate::~CDlgItemTemplate
  38. * Description  : Destructor
  39. ***************************************************************************/
  40. CDlgItemTemplate::~CDlgItemTemplate()
  41. {
  42.     Invalidate();   // if any memory was allocated - free it
  43. }
  44. /**************************************************************************
  45. * Function     : CDlgItemTemplate::operator LPDLGITEMTEMPLATE
  46. * Description  : Converts CDlgItemTemplate object to Win32 DLGITEMTEMPLATE
  47. *              : structure, allocates memory and initializes it with dialog
  48. *              : item template fields values
  49. * Return value : pointer to the allocated memory holding DLGITEMTEMPLATE structure
  50. * CAUTION      : zero may be returned, which indicates structure building failure
  51. ***************************************************************************/
  52. CDlgItemTemplate::operator LPDLGITEMTEMPLATE()
  53. {
  54.     if ( m_pWinTemplate ) return m_pWinTemplate;           // if the structure
  55.            // has been built already and it is not invalidated yet - return it
  56.     m_pWinTemplate = (LPDLGITEMTEMPLATE)malloc(Length());  // allocate memory
  57.     if ( !FillBuffer(m_pWinTemplate) )   // fill the memory with the template
  58.     {
  59.         free(m_pWinTemplate);   // free memory in case of filling failure
  60.         m_pWinTemplate = NULL;
  61.     }
  62.     return m_pWinTemplate;
  63. }
  64. /**************************************************************************
  65. * Function     : CDlgItemTemplate::Length
  66. * Description  : Calculates number of bytes necessary to store Win32 DLGITEMTEMPLATE
  67. *              : structure holding all control's data
  68. * Return value : number of bytes calculated
  69. ***************************************************************************/
  70. UINT CDlgItemTemplate::Length()
  71. {
  72. UINT nLen = sizeof(DLGITEMTEMPLATE);    // all static length fields
  73.     nLen += m_nWndClassOrdinal ? 4 : 2*(1+m_strWndClass.length()); // 4 bytes for
  74.                       // window class ordinal if any, or length of the class name
  75.                                         // ( 1+ for trailing 0 , 2* for UNICODE )
  76.     nLen += m_nRCOrdinal ? 4 : 2*(1+m_strTitle.length());    // 4 bytes for RC ID
  77.         // if any, or length of the window title ( in UNICODE , with trailing 0 )
  78.     nLen += 2;    // reserved for creation data, will be filled with 0, inasmuch as
  79.          // we deal with creation data for ActiveX controls in a separate structure
  80.          // pointed to with m_pInitData
  81.     nLen += nLen%4 ? 4-nLen%4 : 0;    // align on a DWORD boundary,
  82.                                       // nLen must be aliqout of 4
  83.     return nLen;
  84. }
  85. /**************************************************************************
  86. * Function     : CDlgItemTemplate::GetInitData
  87. * Description  : Allocates memory and initializes it with control's init data
  88. *              : section used for control's creation
  89. * Return value : pointer to the allocated memory holding init data section
  90. *              : or zero if the control doesn't require any init data
  91. ***************************************************************************/
  92. LPVOID CDlgItemTemplate::GetInitData()
  93. {
  94. if ( m_pInitData )
  95.     {
  96.            // if the memory was already allocated and it is not invalidated yet
  97.            // we just return pointer to the old memory
  98.         return m_pInitData;
  99.     }
  100.     UINT nInitDataLen = InitDataLength();   // get the required number of bytes
  101.     if ( !nInitDataLen )
  102.     {
  103.         return NULL;   // if no init data required for the control - return NULL
  104.     }
  105.     m_pInitData = malloc(nInitDataLen);   // allocate new memory
  106.     if ( !FillInitDataBuffer(m_pInitData) )   // fill the memory with init data
  107.     {
  108.         free(m_pInitData);   // free memory in case of filling failure
  109.         m_pInitData = NULL;
  110.     }
  111.     return m_pInitData;
  112. }
  113. /**************************************************************************
  114. * Function     : CDlgItemTemplate::InitDataLength
  115. * Description  : Calculates number of bytes necessary to store init data
  116. *              : section for the control's initialization
  117. * Return value : number of bytes calculated
  118. ***************************************************************************/
  119. UINT CDlgItemTemplate::InitDataLength()
  120. {
  121.        // now only creation data for ActiveX controls is supported as init data
  122.        // for this creation data we have to reserve 8 bytes,
  123.        // see function FillInitDataBuffer for the fillup for these 8 bytes
  124.     return m_bIsActiveX ? 8 : 0;
  125. }
  126. /**************************************************************************
  127. * Function     : CDlgItemTemplate::FillBuffer
  128. * Description  : Fills buffer with Win32 DLGITEMTEMPLATE structure
  129. * Return value : number of bytes actually written to the buffer, zero indicates
  130. *              : some data inconsistency and structure building failure
  131. * Arguments    : lpStructBuffer - pointer to the allocated memory which is
  132. *              :    to be filled with structure fields values
  133. ***************************************************************************/
  134. UINT CDlgItemTemplate::FillBuffer(LPVOID lpStructBuffer)
  135. {
  136.     UINT nTemplateLength = Length();
  137.     if ( !AfxIsValidAddress(lpStructBuffer,nTemplateLength,TRUE) )
  138.     {
  139.         ASSERT(FALSE);   // a not valid pointer passed to the function
  140.         return 0;        // 0 bytes were written to the buffer
  141.     }
  142.     if ( m_strWndClass == _bstr_t(_T("")) && !m_nWndClassOrdinal )
  143.     {
  144.         TRACE(_T("nNot initialized control's window class. Building DLGITEMTEMPLATE failed."));
  145.         return 0;  // no bytes were written to the buffer
  146.     }
  147.        // fill all fields of static length
  148. LPDLGITEMTEMPLATE pStaticFields = (LPDLGITEMTEMPLATE)lpStructBuffer;
  149.     pStaticFields->style = style;
  150.     pStaticFields->dwExtendedStyle = dwExtendedStyle;
  151.     pStaticFields->x = x;
  152.     pStaticFields->y = y;
  153.     pStaticFields->cx = cx;
  154.     pStaticFields->cy = cy;
  155.     pStaticFields->id = id;
  156.        // and now copy all variable length fields to the buffer
  157.     LPBYTE pToWrite = (LPBYTE)lpStructBuffer + sizeof(DLGITEMTEMPLATE);   // pointer to
  158.                                       // the current byte in the structure being filled,
  159.                 // start copying from the next byte after the structure's static fields
  160.        // store control's window class name
  161.     if ( m_nWndClassOrdinal )
  162.     {
  163.            // if window class specified by an ordinal - in the template it looks like
  164.            // ... FF FF <WORD value> ...
  165.         *((LPWORD)pToWrite) = 0xFFFF;
  166.         *((LPWORD)pToWrite+1) = m_nWndClassOrdinal;
  167.         pToWrite += 4;    // two words were written to the template
  168.     }
  169.     else
  170.     {
  171.         int nSizeOfClassString = 2*m_strWndClass.length();   // length of the UNICODE
  172.                // string that will be built from m_strWndClass , excluding trailing 0
  173.         if ( !!m_strWndClass )   // copy UNICODE string only if it is not empty
  174.         {
  175.             memcpy(pToWrite,(const wchar_t*)m_strWndClass,nSizeOfClassString);
  176.         }
  177.         *((LPWORD)(pToWrite+nSizeOfClassString)) = 0;   // add trailing zero
  178.                                                     // to the UNICODE string
  179.         pToWrite += nSizeOfClassString+2;   // nSizeOfClassString+2 bytes were written
  180.     }
  181.        // store control's window text
  182.     if ( m_nRCOrdinal )
  183.     {
  184.            // if specified resource ID ordinal - in the template it looks like
  185.            // ... FF FF <WORD value> ...
  186.         *((LPWORD)pToWrite) = 0xFFFF;
  187.         *((LPWORD)pToWrite+1) = m_nRCOrdinal;
  188.         pToWrite += 4;    // two words were written to the template
  189.     }
  190.     else
  191.     {
  192.         int nSizeOfTitleString = 2*m_strTitle.length(); // length of the UNICODE string
  193.                                // without trailing 0 that will be built from m_strTitle
  194.         if ( !!m_strTitle )
  195.         {
  196.             memcpy(pToWrite,(const wchar_t*)m_strTitle,nSizeOfTitleString);
  197.         }
  198.         *((LPWORD)(pToWrite+nSizeOfTitleString)) = 0;
  199.         pToWrite += nSizeOfTitleString+2;   // nSizeOfTitleString+2 bytes were written
  200.     }
  201.        // write 0 as init data for the control
  202.     *(LPWORD)pToWrite = 0;
  203.        // DLGITEMTEMPLATE structure has been filled successfully
  204.     return nTemplateLength;  // nTemplateLength bytes were written to the buffer
  205. }
  206. /**************************************************************************
  207. * Function     : CDlgItemTemplate::FillInitDataBuffer
  208. * Description  : Fills buffer with control's init data section
  209. * Return value : number of bytes actually written to the buffer, zero indicates
  210. *              : that the control doesn't require any init data for its creation
  211. * Arguments    : lpInitDataBuffer - pointer to the allocated memory which is
  212. *              :    to be filled with init data
  213. ***************************************************************************/
  214. UINT CDlgItemTemplate::FillInitDataBuffer(LPVOID lpInitDataBuffer)
  215. {
  216.     UINT nInitDataLen = InitDataLength();
  217.     if ( !nInitDataLen )
  218.     {
  219.         return 0;   // the control doesn't require init data
  220.     }
  221.     if ( !AfxIsValidAddress(lpInitDataBuffer,nInitDataLen,TRUE) )
  222.     {
  223.         ASSERT(FALSE);   // a not valid pointer passed to the function
  224.         return 0;        // 0 bytes were written to the buffer
  225.     }
  226.     LPBYTE pToWrite = (LPBYTE)lpInitDataBuffer;
  227.     *((LPWORD&)pToWrite)++ = id;   // store control's ID
  228.     *((LPWORD&)pToWrite)++ = WM_OCC_INITNEW;   // store OCC message for creation
  229.     *((LPDWORD)pToWrite) = 0;   // store 0 as the initialization data length
  230.        // reading stored properties of OLE controls is not yet supported in XMLGUI
  231. return nInitDataLen;
  232. }
  233. /**************************************************************************
  234. * Function     : CDlgItemTemplate::SerializeFrom
  235. * Description  : Initializes CDlgItemTemplate object from XML tag pointer
  236. *              : describing dialog control
  237. * Return value : nonzero if XML parsing is successful, otherwise zero
  238. * Arguments    : pXMLTag - pointer to the COM interface of the XML element
  239. *              :    which contains XML-style template for dialog's control
  240. ***************************************************************************/
  241. BOOL CDlgItemTemplate::SerializeFrom(IXMLElement* pXMLTag)
  242. {
  243.     try   // watch possible CXMLParsingException
  244.     {
  245.            // construct CXMLControlTag object from the COM interface pointer
  246.         CXMLControlTag xmlControl(pXMLTag);
  247.         
  248.         // check validity of the tag, naturally compare the tag name with "CONTROL"
  249.         if ( !CXMLControlTag::IsTypeValid(xmlControl) )
  250.         {
  251.             TRACE(_T("nXML file with dialog template is not valid. Serialization failed."));
  252.             return FALSE;
  253.         }
  254.         
  255.            // fill all control's properties from the XML
  256.         style = xmlControl.GetStyles();
  257.         dwExtendedStyle = xmlControl.GetExStyles();
  258.         x = (short)xmlControl.GetAttributeInt(ATTRIBUTE_CONTROL_LEFT);
  259.         y = (short)xmlControl.GetAttributeInt(ATTRIBUTE_CONTROL_TOP);
  260.         cx = (short)xmlControl.GetAttributeInt(ATTRIBUTE_CONTROL_WIDTH);
  261.         cy = (short)xmlControl.GetAttributeInt(ATTRIBUTE_CONTROL_HEIGHT);
  262.         id = (WORD)xmlControl.GetAttributeInt(ATTRIBUTE_CONTROL_ID);
  263.         SetWndClassOrdinal(xmlControl.GetWindowClassOrdinal());
  264.         if ( !GetWndClassOrdinal() )
  265.         {
  266.             SetWndClass(xmlControl.GetWindowClass());
  267.         }
  268.         SetRCOrdinal((WORD)xmlControl.GetAttributeInt(ATTRIBUTE_CONTROL_RCID));
  269.         if ( !GetRCOrdinal() )
  270.         {
  271.             SetTitle(xmlControl.GetText());
  272.         }
  273.         m_bIsActiveX = xmlControl.IsActiveX();
  274.            // dialog item template object was successfully initialized from XML
  275.         return TRUE;
  276.     }
  277.     catch ( const CXMLParsingException& excp )
  278.     {
  279.         TRACE(excp.GetDescription());
  280.         return FALSE;
  281.     }
  282. }
  283. /**************************************************************************
  284. * Function     : CDlgItemTemplate::Invalidate
  285. * Description  : Discards any memory that was allocated in previous calls to
  286. *              : the operator LPDLGITEMTEMPLATE, the next call to this operator
  287. *              : will allocate a new memory and build a new DLGITEMTEMPLATE structure
  288. * CAUTION      : all LPDLGITEMTEMPLATE pointers that were previously obtained
  289. *              : through calls to operator LPDLGITEMTEMPLATE become invalid
  290. *              : and should not be used
  291. ***************************************************************************/
  292. void CDlgItemTemplate::Invalidate()
  293. {
  294.        // if any memory was allocated for DLGITEMTEMPLATE structure - free it
  295.        // and set m_pWinTemplate to NULL which allows next memory allocation
  296.     if ( m_pWinTemplate )
  297.     {
  298.         free (m_pWinTemplate);
  299.         m_pWinTemplate = NULL;
  300.     }
  301.        // free memory allocated for init data section as well and set m_pInitData
  302.        // to NULL allowing next allocations
  303.     if ( m_pInitData )
  304.     {
  305.         free ( m_pInitData );
  306.         m_pInitData = NULL;
  307.     }
  308. }