DlgTemplate.cpp
上传用户:kj0090
上传日期:2007-03-02
资源大小:39k
文件大小:16k
- /***********************************************************************
- *
- * This module is part of the XMLGUI system
- *
- * File name: DlgTemplate.cpp
- *
- * Creation date: [12 AUGUST 2002]
- *
- * Author(s): [Kolosenko Ruslan]
- *
- * Description: Implements the class CDlgTemplate
- *
- **********************************************************************/
- #include "stdafx.h"
- #include "DlgTemplate.h"
- #include "XMLIterator.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- /**************************************************************************
- * Function : CDlgTemplate::CDlgTemplate
- * Description : Constructor
- ***************************************************************************/
- CDlgTemplate::CDlgTemplate()
- {
- m_hGlobalTemplate = NULL;
- m_pInitData = NULL;
- }
- /**************************************************************************
- * Function : CDlgTemplate::~CDlgTemplate
- * Description : Destructor
- ***************************************************************************/
- CDlgTemplate::~CDlgTemplate()
- {
- Invalidate(); // free any previously allocated memory
- }
- /**************************************************************************
- * Function : CDlgTemplate::operator LPDLGTEMPLATE
- * Description : Converts CDlgTemplate object to Win32 DLGTEMPLATE structure
- * : allocates memory and initializes it with values of dialog
- * : template fields
- * Return value : pointer to the allocated memory holding DLGTEMPLATE structure
- * CAUTION : zero may be returned, which indicates structure building failure
- ***************************************************************************/
- CDlgTemplate::operator LPDLGTEMPLATE()
- {
- if ( m_hGlobalTemplate )
- {
- // if the memory was already allocated and it is not invalidated yet
- // we do not reallocate memory but return pointer to the old memory
- LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)::GlobalLock(m_hGlobalTemplate);
- ::GlobalUnlock(m_hGlobalTemplate); // to restore memory lock counter
- return lpTemplate;
- }
- m_hGlobalTemplate = ::GlobalAlloc(GMEM_ZEROINIT,Length()); // allocate memory
- LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)::GlobalLock(m_hGlobalTemplate);
- if ( !lpTemplate )
- {
- TRACE(_T("nCannot allocate memory for DLGTEMPLATE"));
- return NULL;
- }
- // now, fill the allocated buffer with the dialog template
- // first we fill all static length fields except cdit, it will be filled later
- lpTemplate->style = style;
- lpTemplate->dwExtendedStyle = dwExtendedStyle;
- lpTemplate->x = x;
- lpTemplate->y = y;
- lpTemplate->cx = cx;
- lpTemplate->cy = cy;
- // and now copy all variable length fields to the buffer
- LPBYTE pToWrite = (LPBYTE)lpTemplate + sizeof(DLGTEMPLATE); // pointer to
- // the current byte in the structure being filled,
- // start copying from the next byte after the structure's static fields
- // store menu name for the dialog
- if ( m_nMenuID )
- {
- // if menu ID is specified by an ordinal - in the template it looks like
- // ... FF FF <WORD value> ...
- *((LPWORD)pToWrite) = 0xFFFF;
- *((LPWORD)pToWrite+1) = m_nMenuID;
- pToWrite += 4; // two words were written to the template
- }
- else
- {
- int nSizeOfMenuString = 2*m_strMenuName.length(); // length of the UNICODE
- // string without trailing 0 that will be built from m_strMenuName
- if ( !!m_strMenuName ) // copy UNICODE string if not empty
- {
- memcpy(pToWrite,(const wchar_t*)m_strMenuName,nSizeOfMenuString);
- }
- *((LPWORD)(pToWrite+nSizeOfMenuString)) = 0; // add trailing zero
- pToWrite += nSizeOfMenuString+2; // nSizeOfMenuString+2 bytes were written
- }
- // store dialog's window class name
- if ( m_nWndClassOrdinal )
- {
- // if window class is specified by an ordinal - in the template it looks like
- // ... FF FF <WORD value> ...
- *((LPWORD)pToWrite) = 0xFFFF;
- *((LPWORD)pToWrite+1) = m_nWndClassOrdinal;
- pToWrite += 4; // two words were written to the template
- }
- else
- {
- int nSizeOfClassString = 2*m_strWndClass.length(); // length of the UNICODE
- // built from m_strWndClass
- if ( !!m_strWndClass )
- {
- memcpy(pToWrite,(const wchar_t*)m_strWndClass,nSizeOfClassString);
- }
- *((LPWORD)(pToWrite+nSizeOfClassString)) = 0;
- pToWrite += nSizeOfClassString+2;
- }
-
- // store title of the dialog's window
- int nSizeOfTitleString = 2*m_strTitle.length();
- if ( !!m_strTitle )
- {
- memcpy(pToWrite,(const wchar_t*)m_strTitle,nSizeOfTitleString);
- }
- *((LPWORD)(pToWrite+nSizeOfTitleString)) = 0;
- pToWrite += nSizeOfTitleString+2;
- if ( style & DS_SETFONT ) // fill font size and typeface name only if the dialog
- // has style DS_SETFONT
- {
- // store font size
- *((LPWORD)pToWrite) = m_nFontSize;
- pToWrite += 2; // two bytes were written
- // store font's typeface name
- int nSizeOfFontString = 2*m_strFontTypeface.length();
- if ( !!m_strFontTypeface )
- {
- memcpy(pToWrite,(const wchar_t*)m_strFontTypeface,nSizeOfFontString);
- }
- *((LPWORD)(pToWrite+nSizeOfFontString)) = 0;
- pToWrite += nSizeOfFontString+2;
- }
- // skip bytes allocated for DWORD alignment
- pToWrite += (UINT)pToWrite%4 ? 4-(UINT)pToWrite%4 : 0;
- // append DLGITEMTEMPLATE structure for each control to the dialog template
- UINT nItemTemplateSize = 0;
- for ( int i = 0; i < cdit(); i++ )
- {
- nItemTemplateSize = controls[i].FillBuffer(pToWrite);
- pToWrite += nItemTemplateSize; // shift write pointer to the next position
- if ( nItemTemplateSize )
- {
- lpTemplate->cdit++; // increase cdit field for valid controls only
- }
- }
- // DLGTEMPLATE structure has been filled successfully
- return lpTemplate;
- }
- /**************************************************************************
- * Function : CDlgTemplate::Length
- * Description : Calculates number of bytes necessary to store Win32 DLGTEMPLATE
- * : structure holding all dialog template's data
- * Return value : number of bytes calculated
- ***************************************************************************/
- UINT CDlgTemplate::Length()
- {
- UINT nLen = sizeof(DLGTEMPLATE); // all static length fields
- nLen += m_nMenuID ? 4 : 2*(1+m_strMenuName.length()); // 4 bytes for menu
- // ordinal if any, or length of the menu name
- // ( 1+ for trailing 0 , 2* for UNICODE )
- nLen += m_nWndClassOrdinal ? 4 : 2*(1+m_strWndClass.length()); // 4 bytes
- // for class ordinal value if any, or length of the UNICODE string
- //with trailing zero containing window class name
- nLen += 2*(1+m_strTitle.length()); // length of the UNICODE string
- // with trailing 0 containing the title of the dialog window
- if ( style & DS_SETFONT ) // font size and typeface name are included
- // into the DLGTEMPLATE structure only if dialog has DS_SETFONT style
- {
- nLen += 2 + 2*(1+m_strFontTypeface.length()); // 2 bytes for the font size
- // value plus the length of the UNICODE string with the typeface name
- }
- nLen += nLen%4 ? 4-nLen%4 : 0; // align on a DWORD boundary,
- // nLen must be aliqout of 4
- for ( int i = 0; i < cdit(); i++ )
- {
- nLen += controls[i].Length(); // add to this all DLGITEMTEMPLATE's lengths
- }
- return nLen;
- }
- /**************************************************************************
- * Function : CDlgTemplate::GetInitData
- * Description : Allocates memory and initializes it with dialog init data
- * : section used for creating dialog controls
- * Return value : pointer to the allocated memory holding init data section
- * : or zero if no init data required for the dialog's controls
- ***************************************************************************/
- LPVOID CDlgTemplate::GetInitData()
- {
- if ( m_pInitData )
- {
- // if the memory was already allocated and it is not invalidated yet
- // we just return pointer to the old memory
- return m_pInitData;
- }
- UINT nInitDataLen = InitDataLength(); // get the required number of bytes
- if ( !nInitDataLen )
- {
- return NULL; // if no init data required for any control - return NULL
- }
- m_pInitData = malloc(nInitDataLen + 2); // allocate new memory,
- // + 2 is here for terminating zero
- // write init data section for each control to the allocated memory
- LPBYTE pToWrite = (LPBYTE)m_pInitData;
- UINT nInitDataSize = 0;
- for ( int i = 0; i < cdit(); i++ )
- {
- nInitDataSize = controls[i].FillInitDataBuffer(pToWrite);
- pToWrite += nInitDataSize; // shift write pointer to the next position
- }
- *((LPWORD)pToWrite) = 0; // append terminating zero
- return m_pInitData;
- }
- /**************************************************************************
- * Function : CDlgTemplate::InitDataLength
- * Description : Calculates number of bytes necessary to store init data
- * : section holding dialog control's initialization data
- * : excluding terminating zero
- * Return value : number of bytes calculated,
- * : excluding 2 bytes for terminating zero
- ***************************************************************************/
- UINT CDlgTemplate::InitDataLength()
- {
- UINT nLen = 0; // dialog itself doesn't have its own init data
- // we just calculate sum of the init data section for each control
- for ( int i = 0; i < cdit(); i++ )
- {
- nLen += controls[i].InitDataLength();
- }
- return nLen;
- }
- /**************************************************************************
- * Function : CDlgTemplate::SerializeFrom(LPCTSTR)
- * Description : Initializes CDlgTemplate object from XML file with XML-style
- * : dialog template
- * Return value : nonzero if XML parsing is successful, otherwise zero
- * Arguments : szXMLFile - pointer to a string with the name of XML file
- * : containing XML-style template for dialog
- ***************************************************************************/
- BOOL CDlgTemplate::SerializeFrom(LPCTSTR szXMLFile)
- {
- try // watch possible CXMLParsingException
- {
- // construct CXMLTag object for root <DIALOG> tag in the XML file
- CXMLDialogTag xmlDialog(szXMLFile);
- // serialize dialog template fields from the XML tag
- return SerializeFrom(xmlDialog);
- }
- catch ( const CXMLParsingException& excp )
- {
- TRACE(excp.GetDescription());
- return FALSE;
- }
- }
- /**************************************************************************
- * Function : CDlgTemplate::SerializeFrom(IXMLElement*)
- * Description : Initializes CDlgTemplate object from XML tag pointer
- * : describing dialog template
- * Return value : nonzero if XML parsing is successful, otherwise zero
- * Arguments : pXMLTag - pointer to the COM interface of the XML element
- * : which contains XML-style template for dialog
- ***************************************************************************/
- BOOL CDlgTemplate::SerializeFrom(IXMLElement* pXMLTag)
- {
- try // watch possible CXMLParsingException
- {
- // construct CXMLDialogTag object from the COM interface pointer
- CXMLDialogTag xmlDialog(pXMLTag);
-
- // check validity of the tag, naturally compare the tag name with "DIALOG"
- if ( !CXMLDialogTag::IsTypeValid(xmlDialog) )
- {
- TRACE(_T("nXML file with dialog template is not valid. Serialization failed."));
- return FALSE;
- }
-
- // fill all properties of the dialog template from the XML
- style = xmlDialog.GetStyles();
- dwExtendedStyle = xmlDialog.GetExStyles();
- x = (short)xmlDialog.GetAttributeInt(ATTRIBUTE_DIALOG_LEFT);
- y = (short)xmlDialog.GetAttributeInt(ATTRIBUTE_DIALOG_TOP);
- cx = (short)xmlDialog.GetAttributeInt(ATTRIBUTE_DIALOG_WIDTH);
- cy = (short)xmlDialog.GetAttributeInt(ATTRIBUTE_DIALOG_HEIGHT);
- m_strTitle = xmlDialog.GetAttributeString(ATTRIBUTE_DIALOG_CAPTION);
- m_nMenuID = (WORD)xmlDialog.GetAttributeInt(ATTRIBUTE_DIALOG_MENU);
- if ( !m_nMenuID ) // if menu not specified by ordinal number -
- { // try to interpret the XML attribute as menu name
- m_strMenuName = xmlDialog.GetAttributeString(ATTRIBUTE_DIALOG_MENU);
- }
- m_nWndClassOrdinal = (WORD)xmlDialog.GetAttributeInt(ATTRIBUTE_DIALOG_CLASS);
- if ( !m_nWndClassOrdinal ) // if class ordinal value not specified -
- { // try to extract from XML attribute the class name
- m_strWndClass = xmlDialog.GetAttributeString(ATTRIBUTE_DIALOG_CLASS);
- }
- m_nFontSize = (WORD)xmlDialog.GetAttributeInt(ATTRIBUTE_DIALOG_FONTSIZE);
- m_strFontTypeface = xmlDialog.GetAttributeString(ATTRIBUTE_DIALOG_FONTNAME);
-
- // now we fill controls array
- controls.RemoveAll(); // remove all previously written entries if any
-
- // iterate through all <CONTROL> tags within the root <DIALOG> tag
- CXMLControlIterator iControl(xmlDialog);
- for ( iControl.Begin(); !iControl.AtEnd(); ++iControl )
- {
- // temporary CDlgItemTemplate object to be filled and added to controls array
- CDlgItemTemplate control;
- // temporary CXMLTag object for retrieving XML attribute values
- CXMLControlTag xmlControl(*iControl);
-
- // fill all control's properties from the XML
- control.SerializeFrom(xmlControl);
-
- // add the built dialog item template to the controls array
- *this += control;
- }
-
- // dialog template object was successfully initialized from XML
- return TRUE;
- }
- catch ( const CXMLParsingException& excp )
- {
- TRACE(excp.GetDescription());
- return FALSE;
- }
- }
- /**************************************************************************
- * Function : CDlgTemplate::Invalidate
- * Description : Discards any memory that was allocated in previous calls to
- * : the operator LPDLGTEMPLATE, the next call to this operator
- * : will allocate a new memory and build a new DLGTEMPLATE structure
- * CAUTION : all LPDLGTEMPLATE pointers that were previously obtained
- * : through calls to operator LPDLGTEMPLATE become invalid
- * : and should not be used
- ***************************************************************************/
- void CDlgTemplate::Invalidate()
- {
- if ( m_hGlobalTemplate )
- {
- ::GlobalUnlock(m_hGlobalTemplate); // free any previously allocated
- ::GlobalFree(m_hGlobalTemplate); // memory and set m_hGlobalTemplate
- m_hGlobalTemplate = NULL; // to NULL allowing next memory allocation
- }
- if ( m_pInitData )
- {
- free(m_pInitData); // free memory holding init data section as well
- m_pInitData = NULL; // and set pointer to NULL allowing next allocation
- }
- }