Przepraszam, ale wprowadziłem cię w błąd z rozpędu. W załączniku odpowiedni program do tego typu plików.
#include & lt; stdlib.h & gt;
#include " crc.h "
#include & lt; memory.h & gt;
//#include " global.h "
const unsigned int crc_16_l_table[ CRC_TAB_SIZE ] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
///////////////////////////////////////////////////////////////////
//CRC Table
///////////////////////////////////////////////////////////////////
/*********************************************************************/
unsigned int crc_16_l_calc(char* buf_ptr,unsigned int len)
{
unsigned int i;
unsigned short crc = 0;
while (len--!=0)
{
for(i = 0x80; i !=0 ; i = i & gt; & gt; 1)
{
if((crc & 0x8000) !=0 )
{
crc = crc & lt; & lt; 1 ;
crc = crc ^ 0x1021;
}
else
{
crc = crc & lt; & lt; 1 ;
}
if((*buf_ptr & i) != 0 )
{
crc = crc ^ 0x1021;
}
}
buf_ptr++;
}
return (crc);
}
/**---------------------------------------------------------------------------*
** FUNCTION *
** unsigned short cm_decode_msg(uchar_ptr *dest, byte *src) *
** *
** DESCRIPTION *
** This function decodes the message of the source and restore the *
** decoded message to the destination buffer. *
** *
** INPUT *
** size: Size of the source buffer in byte. *
** src: Pointer of the input message. *
** *
** OUTPUT *
** dest: Pointer of the decoded message. *
** *
** RETURN VALUE *
** If the function is successful, return the size of the decoded message. *
** Else it returns CRC_ERROR : 0 or NO_END_FLAG : 0. *
** *
** DEPENDENCIES *
** extern word crc_16_l_calc(const void *src, word size); *
**---------------------------------------------------------------------------*/
int decode_msg(char* input_buf, int input_size,
char **output_buf, int *output_len,int bcrc)
{
unsigned short crc; /* CRC value*/
char *src_ptr; /* source buffer pointer*/
int dest_len; /* output buffer length*/
char *dest_ptr; /* dest buffer pointer*/
register int curr;
/* Check if exist End Flag.*/
src_ptr = input_buf;
dest_len = 0;
if( input_size & lt; 4 )
{
return 0;
}
/* Get the total size to be allocated for decoded message.*/
for( curr = 1; curr & lt; input_size - 1; curr++)
{
switch(*(src_ptr + curr))
{
case HDLC_ESCAPE:
curr++;
dest_len ++;
break;
default:
dest_len++;
break;
}
}
/* Allocate meomory for decoded message*/
dest_ptr = NULL;
dest_ptr = (char *)malloc(dest_len);
/* Memory Free fail.*/
if(dest_ptr == NULL)
{
return 0;
}
memset(dest_ptr, 0, dest_len);
curr = 0;
dest_len = 0;
/* Do de-escape.*/
for( curr = 1; curr & lt; input_size - 1; curr++)
{
switch(*(src_ptr + curr))
{
case HDLC_ESCAPE:
curr++;
*(dest_ptr + dest_len) = *(src_ptr + curr) ^ HDLC_ESCAPE_MASK;
break;
default:
*(dest_ptr + dest_len) = *(src_ptr + curr);
break;
}
dest_len = dest_len + 1;
}
/* CRC Check. */
if(bcrc)
{
crc = crc_16_l_calc(dest_ptr, dest_len);
if (crc != CRC_16_L_OK)
{
free(dest_ptr);
return 0;
}
}
else
{
/*
crc = crc_32_l_calc(dest_ptr, dest_len);
if ((crc & 0xFFFF) != CRC_16_L_OK)
{
free(dest_ptr);
return FALSE;
}
*/
crc = frm_chk((unsigned short *)dest_ptr, dest_len);
if (0 != crc)
{
free(dest_ptr);
return 0;
}
}
*(output_buf) = dest_ptr;
*(output_len) = dest_len - CRC_CHECK_SIZE ;
return 1;
}
/**---------------------------------------------------------------------------*
** FUNCTION *
** word cm_encode_msg() *
** *
** DESCRIPTION *
** This function encodes the message of the input message and restore *
** the encoded message to the dest bufffer. *
** *
** INPUT *
** size: Size of the source buffer in byte. *
** src: Pointer of the input message. *
** *
** OUTPUT *
** dest: Pointer of the encoded message. *
** *
** RETURN VALUE *
** Return the size of the coded message. *
** *
** DEPENDENCIES *
** extern word crc_16_l_calc(const void *src, word size); *
**---------------------------------------------------------------------------*/
int encode_msg(char* input_buf, int input_size,
char **output_buf, int *output_len, int bcrc)
{
unsigned short crc; /* CRC value*/
char *src_ptr; /* source buffer pointer*/
int dest_len; /* output buffer length*/
char *dest_ptr; /* dest buffer pointer*/
char high_crc, low_crc;
register int curr;
/* CRC Check. */
src_ptr = input_buf;
/* CRC Check. */
if(bcrc)
{
crc = crc_16_l_calc(src_ptr, input_size);
}
else
{
//crc = crc_32_l_calc(src_ptr, input_size);
crc = frm_chk((unsigned short *)src_ptr, input_size);
/*
unsigned short SoruceValue, DestValue;
SoruceValue = crc;
DestValue = 0;
CONVERT_SHORT(SoruceValue, DestValue);
crc = DestValue;*/
}
high_crc = (crc & gt; & gt; 8) & 0xFF;
low_crc = crc & 0xFF;
/* Get the total size to be allocated.*/
dest_len = 0;
for (curr = 0; curr & lt; input_size; curr++)
{
switch (*(src_ptr+curr))
{
case HDLC_FLAG:
case HDLC_ESCAPE:
dest_len += 2;
break;
default:
dest_len++;
break;
}
}
switch (low_crc)
{
case HDLC_FLAG:
case HDLC_ESCAPE:
dest_len += 2;
break;
default:
dest_len++;
}
switch (high_crc)
{
case HDLC_FLAG:
case HDLC_ESCAPE:
dest_len += 2;
break;
default:
dest_len++;
}
dest_ptr = (char *)malloc((dest_len + 2));
/* Memory Allocate fail.*/
if(dest_ptr == NULL)
{
return 0;
}
*dest_ptr = HDLC_FLAG;
dest_len = 1;
/* do escape*/
for (curr = 0; curr & lt; input_size; curr++)
{
switch (*(src_ptr+curr))
{
case HDLC_FLAG:
case HDLC_ESCAPE:
*(dest_ptr + dest_len++) = HDLC_ESCAPE;
*(dest_ptr + dest_len++) = *(src_ptr + curr) ^ HDLC_ESCAPE_MASK;
break;
default:
*(dest_ptr + dest_len++) = *(src_ptr + curr);
break;
}
}
switch (high_crc)
{
case HDLC_FLAG:
case HDLC_ESCAPE:
*(dest_ptr + dest_len++) = HDLC_ESCAPE;
*(dest_ptr + dest_len++) = high_crc ^ HDLC_ESCAPE_MASK;
break;
default:
*(dest_ptr + dest_len++) = high_crc;
}
switch (low_crc)
{
case HDLC_FLAG:
case HDLC_ESCAPE:
*(dest_ptr + dest_len++) = HDLC_ESCAPE;
*(dest_ptr + dest_len++) = low_crc ^ HDLC_ESCAPE_MASK;
break;
default:
*(dest_ptr + dest_len++) = low_crc;
}
*(dest_ptr + dest_len++) = HDLC_FLAG;
*output_buf = dest_ptr;
*output_len = dest_len;
return 1;
}
unsigned short frm_chk(unsigned short *src, int len)
{
unsigned int sum = 0;
unsigned short SourceValue, DestValue;
unsigned short lowSourceValue, hiSourceValue;
/* Get sum value of the source.*/
while (len & gt; 1)
{
SourceValue = *src++;
DestValue = 0;
lowSourceValue = ( SourceValue & 0xFF00 ) & gt; & gt; 8;
hiSourceValue = ( SourceValue & 0x00FF ) & lt; & lt; 8;
DestValue = lowSourceValue | hiSourceValue;
sum += DestValue;
len -= 2;
}
if (len == 1)
{
sum += *( (unsigned char *) src );
}
sum = (sum & gt; & gt; 16) + (sum & 0x0FFFF);
sum += (sum & gt; & gt; 16);
return (~sum);
}
/*********************************************************************/
unsigned int crc_32_l_calc(char* buf_ptr,unsigned int len)
{
unsigned int data, crc_16;
len *= 8;
for (crc_16 = CRC_16_L_SEED ; len & gt; = 8; len -= 8, buf_ptr++)
{
crc_16 = crc_16_l_table[ (crc_16 ^ *buf_ptr) & 0x00ff ] ^ (crc_16 & gt; & gt; 8);
}
if (len != 0)
{
data = ((unsigned short) (*buf_ptr)) & lt; & lt; (16-8);
while (len-- != 0)
{
if ( ((crc_16 ^ data) & 0x01) != 0 )
{
crc_16 & gt; & gt; = 1;
crc_16 ^= CRC_16_L_POLYNOMIAL;
}
else
{
crc_16 & gt; & gt; = 1;
}
data & gt; & gt; = 1;
}
}
return( ~crc_16 );
}
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by BMAFrame.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 9000
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 9000
#define _APS_NEXT_SYMED_VALUE 9000
#endif
#endif
// BMAFrame.h : main header file for the BMAFRAME DLL
//
#if !defined(AFX_BMAFRAME_H__6EFD7319_CCD8_4E7B_91B5_5AF4887CFD2D__INCLUDED_)
#define AFX_BMAFRAME_H__6EFD7319_CCD8_4E7B_91B5_5AF4887CFD2D__INCLUDED_
#if _MSC_VER & gt; 1000
#pragma once
#endif // _MSC_VER & gt; 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include " resource.h " // main symbols
/////////////////////////////////////////////////////////////////////////////
// CBMAFrameApp
// See BMAFrame.cpp for the implementation of this class
//
class CBMAFrameApp : public CWinApp
{
public:
CBMAFrameApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBMAFrameApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
//{{AFX_MSG(CBMAFrameApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_BMAFRAME_H__6EFD7319_CCD8_4E7B_91B5_5AF4887CFD2D__INCLUDED_)
// XmlConfigParse.cpp: implementation of the CXmlConfigParse class.
//
//////////////////////////////////////////////////////////////////////
#include " stdafx.h "
#include " XmlConfigParse.h "
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define FILE_OMIT_FLAG 2
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXmlConfigParse::CXmlConfigParse()
{
m_xmlConfig.Close();
m_mapProductInfo.RemoveAll();
m_mapProductEnable.RemoveAll();
m_aProductList.RemoveAll();
m_pCurProduct = NULL;
m_bOK = FALSE;
m_strBaseConfig = _T( " " );
m_mapPrdCfg.RemoveAll();
}
CXmlConfigParse::CXmlConfigParse(LPCTSTR lpcstrFileName)
{
if(!Init(lpcstrFileName))
{
return;
}
m_pCurProduct = NULL;
}
CXmlConfigParse::~CXmlConfigParse()
{
Clear();
}
void CXmlConfigParse::Clear()
{
m_bOK = FALSE;
m_pCurProduct = NULL;
int nCount = m_aProductList.GetSize();
PPRODUCT_INFO_T pProd;
for(int i = 0; i & lt; nCount; i++)
{
m_mapProductInfo.Lookup(m_aProductList[i],pProd);
if(pProd != NULL)
{
pProd- & gt; Clear();
delete pProd;
}
}
m_mapProductInfo.RemoveAll();
m_mapProductEnable.RemoveAll();
m_aProductList.RemoveAll();
m_mapPrdCfg.RemoveAll();
}
BOOL CXmlConfigParse::Init(LPCTSTR lpszFileName,int nFlag /*= 0*/)
{
if(!lpszFileName)
{
AfxMessageBox( _T( " The file name must not be empty! " ) );
return FALSE;
}
m_strBaseConfig = lpszFileName;
if(nFlag == 0)
{
Clear();
CString strBasePath= lpszFileName;
int nFind = strBasePath.ReverseFind(_T('\\'));
strBasePath = strBasePath.Left(nFind);
m_bOK = LoadAllProductInfo(strBasePath);
}
else
{
// m_aProductList.RemoveAll();
// m_mapProductInfo.RemoveAll();
// m_mapProductEnable.RemoveAll();
// m_mapPrdCfg.RemoveAll();
m_bOK = _LoadProductInfo(lpszFileName,TRUE);
}
return m_bOK;
}
/**
* Get the number of products
*
* @return Returns dwCount,the number of products
*/
DWORD CXmlConfigParse::GetProductCount()
{
return m_aProductList.GetSize();
}
/**
* Get product names
*
* @param arrProductNameList: store the names;
*/
/*void CXmlConfigParse::GetProductNameList(CStringArray & arrProductNameList)
{
LPXNode lpChild;
lpChild = m_xmlConfig.GetChild(_T( " ProductList " ) );
XNodes childs;
childs = lpChild- & gt; GetChilds(_T( " Product " ) );
int nCount = childs.size();
CString strAttValue;
for( int i = 0; i & lt; nCount; i++)
{
strAttValue= childs[i]- & gt; GetAttrValue(_T( " name " ));
ASSERT(!strAttValue.IsEmpty());
arrProductNameList.Add(strAttValue);
}
childs.clear();
}*/
/**
* Get product names
*
* @param pProductNameList: store the names;
* @param dwSize: original pProductNameList spaces size;
* @param dwRealSize: real used size;
*/
void CXmlConfigParse::GetProductNameList(LPTSTR pProductNameList,DWORD dwSize,DWORD & dwRealSize)
{
int nCount = m_aProductList.GetSize();
CString strName;
dwRealSize = 0;
memset(pProductNameList,0,dwSize*sizeof(_TCHAR));
for( int i = 0; i & lt; nCount; i++)
{
strName= m_aProductList.GetAt(i);
ASSERT(!strName.IsEmpty());
dwRealSize+=strName.GetLength();
if(dwRealSize & gt; = dwSize)
{
break;
}
_tcscat(pProductNameList,(LPCTSTR)strName);
pProductNameList[dwRealSize]=_T(';');
dwRealSize++; //+';'
//arrProductNameList.Add(strAttValue);
}
pProductNameList[dwRealSize] = _T('\0');
}
PPRODUCT_INFO_T CXmlConfigParse::GetProdInfo(LPCTSTR lpszProductName)
{
ASSERT(lpszProductName != NULL);
BOOL bOk = m_mapProductInfo.Lookup(lpszProductName,m_pCurProduct);
if(!bOk)
{
m_pCurProduct = NULL;
}
return m_pCurProduct;
}
/**
* Release this
*/
void CXmlConfigParse::Release()
{
Clear();
delete this;
}
BOOL CXmlConfigParse::Success()
{
return m_bOK;
}
BOOL CXmlConfigParse::LoadAllProductInfo(LPCTSTR lpszConfigBase)
{
CString strWildPath = lpszConfigBase;
strWildPath += _T( " \\*.xml " );
CFileFind finder;
BOOL bFound;
bFound = finder.FindFile(strWildPath);
CStringArray aFilePath;
CObArray aTime;
CString strPath;
CString strName;
CString strBaseConfg = m_strBaseConfig;
int nFind = strBaseConfg.ReverseFind(_T('\\'));
strBaseConfg = strBaseConfg.Right(strBaseConfg.GetLength() - nFind -1);
// CTime *pCurTime;
CTime lmCurTime;
int i=0;
while(bFound)
{
bFound = finder.FindNextFile();
strName = finder.GetFileName();
if(strName.CompareNoCase(_T( " BMAConfigSchema.xml " )) == 0 ||
strName.CompareNoCase(strBaseConfg)== 0)
{
continue;
}
else if(strName.Right(4).CompareNoCase(_T( " .xml " )) == 0)
{
strPath = finder.GetFilePath();
finder.GetLastWriteTime(lmCurTime);
int nCount = aFilePath.GetSize();
if(nCount == 0)
{
aFilePath.Add(strPath);
//pCurTime= new CTime(lmCurTime);
aTime.Add((CObject *) & lmCurTime);
}
else
{
for(i=0; i & lt; nCount;i++)
{
if(lmCurTime & gt; = *(CTime*)aTime[i])
{
aTime.InsertAt(i,(CObject *) & lmCurTime);
aFilePath.InsertAt(i,strPath);
break;
}
}
if(i & gt; =nCount)
{
aTime.Add((CObject *) & lmCurTime);
aFilePath.Add(strPath);
}
}
}
}
/*
m_aProductList.RemoveAll();
m_mapProductInfo.RemoveAll();
m_mapProductEnable.RemoveAll();
m_mapPrdCfg.RemoveAll();
*/
aFilePath.Add(m_strBaseConfig);
int nFileCount = aFilePath.GetSize();
if(nFileCount == 0)
return FALSE;
BOOL bOk = TRUE;
for(i=0;i & lt; nFileCount;i++)
{
bOk = _LoadProductInfo(aFilePath.GetAt(i));
if(!bOk)
return FALSE;
}
return TRUE;
}
BOOL CXmlConfigParse::_Init(LPCTSTR lpszConfigName)
{
_ASSERTE(lpszConfigName != NULL);
// Open file
CString strText;
CString strNotes;
CFile file;
if ( !file.Open( lpszConfigName, CFile::modeRead ) )
{
AfxMessageBox( _T( " Unable to open xml config file " ) );
return FALSE;
}
int nFileLen = (int)file.GetLength();
// Allocate buffer for binary file data
char* pBuffer = new char[nFileLen + 1];
memset(pBuffer,0,nFileLen + 1);
nFileLen = file.Read( pBuffer, nFileLen );
file.Close();
pBuffer[nFileLen] = '\0';
_TCHAR *pBufferU = NULL;
if(pBuffer[0] != (UCHAR)0xFF || pBuffer[1] != (UCHAR)0xFE)//not unicode
{
pBufferU = new _TCHAR[nFileLen+1];
memset(pBufferU,0,sizeof(_TCHAR)*(nFileLen + 1));
MultiByteToWideChar(CP_ACP,0,pBuffer,nFileLen+1,pBufferU,nFileLen+1);
strText.Empty();
strText = pBufferU;
}
else
{
strText = (LPTSTR)pBuffer;
}
delete [] pBuffer;
pBuffer = NULL;
if(pBufferU != NULL)
{
delete [] pBufferU;
pBufferU = NULL;
}
CString strXmlRet;
strXmlRet = m_xmlConfig.Load(strText);
strText.Empty();
if(strXmlRet.IsEmpty())
{
return FALSE;
}
return TRUE;
}
BOOL CXmlConfigParse::_LoadProductInfo(LPCTSTR lpszConfigName,BOOL bChangePrdName/*= FALSE*/)
{
BOOL bRet = _Init(lpszConfigName);
if(!bRet)
return FALSE;
PPRODUCT_INFO_T pProuctInfo = NULL;
PPRODUCT_INFO_T pFindProuctInfo = NULL;
LPXNode lpChild;
lpChild = m_xmlConfig.GetChild(_T( " ProductList " ) );
if(lpChild == NULL) //check
return FALSE;
XNodes xnProductNodes;
xnProductNodes = lpChild- & gt; GetChilds(_T( " Product " ) );
int nCount = xnProductNodes.size();
CString strCurSchemeName;
CString strValue;
int nValue;
int nNvBkpItem;
int i,j,k;
UINT uEnable;
for( i = 0; i & lt; nCount; i++)
{
strValue= xnProductNodes[i]- & gt; GetAttrValue(_T( " name " ));
ASSERT(!strValue.IsEmpty());
if(strValue.IsEmpty())
{
continue;
}
if(bChangePrdName)
{
strValue.TrimLeft();
strValue.Insert(0,_T( " PAC_ " ));
}
CString strEnable = xnProductNodes[i]- & gt; GetAttrValue(_T( " enable " ));
nValue = 1;
_stscanf( strEnable, _T( " %d " ), & nValue);
pFindProuctInfo = NULL;
if(!bChangePrdName)
{
//already exist
if(m_mapProductInfo.Lookup(strValue,pFindProuctInfo))
{
continue;
}
uEnable = 1;
if(m_mapProductEnable.Lookup(strValue,uEnable) & & uEnable == 0 )
{
continue;
}
else
{
m_mapProductEnable.SetAt(strValue,(UINT)nValue);
if(nValue == 0) //
{
continue;
}
}
}
else // PAC file config must be high level
{
//already exist,must remove it and use this one
if(m_mapProductInfo.Lookup(strValue,pFindProuctInfo))
{
if(pFindProuctInfo != NULL)
{
pFindProuctInfo- & gt; Clear();
delete pFindProuctInfo;
pFindProuctInfo = NULL;
}
m_mapProductInfo.RemoveKey(strValue);
}
m_mapProductEnable.SetAt(strValue,(UINT)1);
}
pProuctInfo = new PRODUCT_INFO_T;
m_aProductList.Add(strValue);
m_mapProductInfo.SetAt(strValue,pProuctInfo);
m_mapPrdCfg.SetAt(strValue,lpszConfigName);
_tcscpy(pProuctInfo- & gt; szProductName,strValue);
strCurSchemeName=xnProductNodes[i]- & gt; GetChildValue(_T( " SchemeName " ));
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " FlashTypeID " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; dwFlashType = nValue;
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " Mode " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; dwMode = nValue;
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " ProductComment " ));
lstrcpyn(pProuctInfo- & gt; szComment,strValue,MAX_PATH+1);
nValue = 0;
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " NvBaseAddrChangeFlag " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; dwNvBaseChangeFlag = nValue;
nValue = 0;
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " NvNewBasePosition " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; dwNvNewBasePosition= nValue;
nValue = 0;
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " NVOrgFlag " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; dwNVOrgFlag = nValue;
nValue = 0;
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " NVOrgBasePosition " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; dwNVOrgBasePosition= nValue;
nValue = 0;
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " OmaDMFlag " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; dwOmaDMFlag= nValue;
nValue = 0;
strValue = xnProductNodes[i]- & gt; GetChildValue(_T( " RebootByAT " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; bRebootByAT = (BYTE)nValue;
// for NV backup
LPXNode lpNvBackup = NULL;
lpNvBackup = xnProductNodes[i]- & gt; GetChild(_T( " NVBackup " ));
if(lpNvBackup != NULL) // if " NVBackup " exist
{
nValue = 0;
strValue = lpNvBackup- & gt; GetAttrValue(_T( " backup " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; dwNvBackupFlag = nValue;
if(nValue != 0)
{
XNodes xnNvBkpList;
xnNvBkpList = lpNvBackup- & gt; GetChilds(_T( " NVItem " ));
pProuctInfo- & gt; dwNvBackupItemCount = xnNvBkpList.size();
nNvBkpItem = pProuctInfo- & gt; dwNvBackupItemCount;
if(nNvBkpItem != 0)
{
pProuctInfo- & gt; paNvBackupItem = new NV_BACKUP_ITEM_T[nNvBkpItem];
memset(pProuctInfo- & gt; paNvBackupItem,0,sizeof(NV_BACKUP_ITEM_T)*nNvBkpItem);
for(j = 0; j & lt; nNvBkpItem;j++)
{
PNV_BACKUP_ITEM_T pNBIT = pProuctInfo- & gt; paNvBackupItem + j;
strValue = xnNvBkpList[j]- & gt; GetAttrValue(_T( " name " ));
_tcscpy(pNBIT- & gt; szItemName,strValue);
strValue = xnNvBkpList[j]- & gt; GetAttrValue(_T( " backup " ));
nValue = 0;
_stscanf(strValue,_T( " %d " ), & nValue);
pNBIT- & gt; wIsBackup = (WORD)nValue;
strValue = xnNvBkpList[j]- & gt; GetChildAttrValue(_T( " BackupFlag " ),_T( " use " ));
nValue = 0;
_stscanf(strValue,_T( " %d " ), & nValue);
pNBIT- & gt; wIsUseFlag = (WORD)nValue;
strValue = xnNvBkpList[j]- & gt; GetChildValue(_T( " ID " ));
_stscanf(strValue,_T( " 0x%x " ), & (pNBIT- & gt; dwID));
if(pNBIT- & gt; wIsUseFlag == 1)
{
XNodes xnNvFlagList;
LPXNode lpxnFlag;
lpxnFlag = xnNvBkpList[j]- & gt; GetChild(_T( " BackupFlag " ));
if(lpxnFlag == NULL)
{
delete [] pProuctInfo- & gt; paNvBackupItem;
pProuctInfo- & gt; paNvBackupItem = NULL;
delete pProuctInfo;
pProuctInfo = NULL;
return FALSE;
}
xnNvFlagList = lpxnFlag- & gt; GetChilds(_T( " NVFlag " ));
int nNvFlagCount = xnNvFlagList.size();
if(nNvFlagCount & gt; MAX_NV_BACKUP_FALG_NUM)
{
nNvFlagCount = MAX_NV_BACKUP_FALG_NUM;
}
pNBIT- & gt; dwFlagCount = (DWORD)nNvFlagCount;
//TRACE(_T( " %s: NvFlagCount:%d\n " ),pProuctInfo- & gt; szProductName,nNvFlagCount);
for(k=0; k & lt; nNvFlagCount;k++)
{
strValue = xnNvFlagList[k]- & gt; GetAttrValue(_T( " name " ));
_tcscpy(pNBIT- & gt; nbftArray[k].szFlagName,strValue);
strValue = xnNvFlagList[k]- & gt; GetAttrValue(_T( " check " ));
_stscanf( strValue, _T( " %d " ), & (pNBIT- & gt; nbftArray[k].dwCheck));
}
xnNvFlagList.clear();
}
}
}
xnNvBkpList.clear();
}
}
//////////////////////////////////////////////////////////////////////////
// for Chips
/*
* & lt; Chips enable= " 0 " & gt;
* & lt; ChipItem id= " 0x222 " name= " L2 " / & gt;
* & lt; ChipItem id= " 0x777 " name= " L7 " / & gt;
* & lt; /Chips & gt;
*/
LPXNode lpChips = NULL;
lpChips = xnProductNodes[i]- & gt; GetChild(_T( " Chips " ));
if(lpChips != NULL) // if " Chips " exist
{
nValue = 0;
strValue = lpChips- & gt; GetAttrValue(_T( " enable " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pProuctInfo- & gt; tChips.bEnable = nValue;
if(nValue != 0)
{
XNodes xnChipList;
xnChipList = lpChips- & gt; GetChilds(_T( " ChipItem " ));
UINT nChipCount = xnChipList.size();
pProuctInfo- & gt; tChips.dwCount = nChipCount;
if(nChipCount != 0)
{
pProuctInfo- & gt; tChips.pChips = new CHIPITEM_T[nChipCount];
memset(pProuctInfo- & gt; tChips.pChips,0,sizeof(CHIPITEM_T)*nChipCount);
for(j = 0; j & lt; (int)nChipCount;j++)
{
CHIPITEM_PTR pChipItem = pProuctInfo- & gt; tChips.pChips + j;
strValue.Empty();
strValue = xnChipList[j]- & gt; GetAttrValue(_T( " id " ));
nValue = 0;
_stscanf(strValue,_T( " 0x%X " ), & nValue);
pChipItem- & gt; dwID = (DWORD)nValue;
strValue.Empty();
strValue = xnChipList[j]- & gt; GetAttrValue(_T( " name " ));
_tcscpy(pChipItem- & gt; szName,strValue);
}
}
xnChipList.clear();
}
}
//////////////////////////////////////////////////////////////////////////
LPXNode lpSpecialStrings = NULL;
lpSpecialStrings = xnProductNodes[i]- & gt; GetChild(_T( " SpecialStrings " ));
if(lpSpecialStrings != NULL) // if " SpecialStrings " exist
{
nValue = 0;
strValue = lpSpecialStrings- & gt; GetAttrValue(_T( " enable " ));
_stscanf( strValue, _T( " %d " ), & nValue);
if(nValue != 0)
{
XNodes xnSpecialStrList;
xnSpecialStrList = lpSpecialStrings- & gt; GetChilds(_T( " SString " ));
int nSSItem = xnSpecialStrList.size();
if(nSSItem != 0)
{
pProuctInfo- & gt; pSpecialStrings = new SPECIAL_STRING_ARR;
for(j = 0; j & lt; nSSItem;j++)
{
SPECIAL_STRING_PTR pSString = new SPECIAL_STRING_T;
strValue = xnSpecialStrList[j]- & gt; GetAttrValue(_T( " name " ));
_tcscpy(pSString- & gt; szName,strValue);
strValue = xnSpecialStrList[j]- & gt; GetAttrValue(_T( " content " ));
_tcscpy(pSString- & gt; szContent,strValue);
strValue = xnSpecialStrList[j]- & gt; GetAttrValue(_T( " included " ));
_tcscpy(pSString- & gt; szIncluedFileID,strValue);
XNodes xnLinkedFileList;
xnLinkedFileList = xnSpecialStrList[j]- & gt; GetChilds(_T( " LinkedFile " ));
int nLFNodeCount = xnLinkedFileList.size();
if(nLFNodeCount & gt; 0)
{
pSString- & gt; pLinkedFileIDs = new LINKED_FILE_ARR;
for(k=0; k & lt; nLFNodeCount;k++)
{
LINKED_FILE_PTR pLinkedFile = new LINKED_FILE_T;
strValue = xnLinkedFileList[k]- & gt; GetAttrValue(_T( " id " ));
_tcscpy(pLinkedFile- & gt; szFileID,strValue);
strValue = xnLinkedFileList[k]- & gt; GetAttrValue(_T( " download " ));
_stscanf( strValue, _T( " %d " ), & (pLinkedFile- & gt; dwDLFlag));
pSString- & gt; pLinkedFileIDs- & gt; push_back(pLinkedFile);
}
}
pProuctInfo- & gt; pSpecialStrings- & gt; push_back(pSString);
xnLinkedFileList.clear();
}
}
xnSpecialStrList.clear();
}
}
//////////////////////////////////////////////////////////////////////////
LPXNode lpSchemeListNode = m_xmlConfig.GetChild( _T( " SchemeList " ) );
XNodes xnSchemeNodeList;
xnSchemeNodeList = lpSchemeListNode- & gt; GetChilds(_T( " Scheme " ));
int nSchemeCount = xnSchemeNodeList.size();
for(j = 0; j & lt; nSchemeCount;j++)
{
strValue= xnSchemeNodeList[j]- & gt; GetAttrValue(_T( " name " ));
ASSERT(!strValue.IsEmpty());
if(strValue.Compare(strCurSchemeName)==0)
{
XNodes xnFileNodeList;
xnFileNodeList = xnSchemeNodeList[j]- & gt; GetChilds(_T( " File " ));
pProuctInfo- & gt; dwFileCount = xnFileNodeList.size();
int nFileCount = (int)(pProuctInfo- & gt; dwFileCount);
if(nFileCount & gt; 0)
{
pProuctInfo- & gt; pFileInfoArr = new FILE_INFO_T[nFileCount];
memset(pProuctInfo- & gt; pFileInfoArr,0,sizeof(FILE_INFO_T)*nFileCount);
for(k=0;k & lt; nFileCount;k++)
{
PFILE_INFO_T pFIT = pProuctInfo- & gt; pFileInfoArr + k;
nValue = 0;
strValue = xnFileNodeList[k]- & gt; GetAttrValue(_T( " backup " ));
_stscanf( strValue, _T( " %d " ), & nValue);
pFIT- & gt; isBackup = (BYTE)nValue;
strValue = xnFileNodeList[k]- & gt; GetChildValue(_T( " ID " ));
_tcscpy(pFIT- & gt; szID,strValue);
strValue.Empty();
strValue = xnFileNodeList[k]- & gt; GetChildValue(_T( " IDAlias " ));
if(!strValue.IsEmpty())
{
_tcscpy(pFIT- & gt; szIDAlias,strValue);
}
else
{
_tcscpy(pFIT- & gt; szIDAlias,pFIT- & gt; szID);
}
strValue = xnFileNodeList[k]- & gt; GetChildValue(_T( " Type " ));
_tcscpy(pFIT- & gt; szType,strValue);
strValue = xnFileNodeList[k]- & gt; GetChildValue(_T( " Flag " ));
pFIT- & gt; dwFlag = (DWORD)_ttoi(strValue);
strValue = xnFileNodeList[k]- & gt; GetChildValue(_T( " CheckFlag " ));
pFIT- & gt; dwCheckFlag = (DWORD)_ttoi(strValue);
strValue = xnFileNodeList[k]- & gt; GetChildValue(_T( " Description " ));
_tcscpy(pFIT- & gt; szFileDescript,strValue);
XNodes nxBlockList;
nxBlockList = xnFileNodeList[k]- & gt; GetChilds(_T( " Block " ));
int nBlockCount = nxBlockList.size();
if(nBlockCount & gt; MAX_BLOCK_NUM)
nBlockCount = MAX_BLOCK_NUM;
pFIT- & gt; dwBlockCount = (DWORD)nBlockCount;
for(int t=0; t & lt; nBlockCount;t++)
{
strValue = nxBlockList[t]- & gt; GetChildValue(_T( " Base " ));
_stscanf( strValue, _T( " 0x%X " ), & (pFIT- & gt; arrBlock[t].dwBase));
strValue = nxBlockList[t]- & gt; GetChildValue(_T( " Size " ));
_stscanf( strValue, _T( " 0x%X " ), & (pFIT- & gt; arrBlock[t].dwSize));
}
nxBlockList.clear();
}
}
xnFileNodeList.clear();
break;
}
}
xnSchemeNodeList.clear();
if(j & gt; = nSchemeCount)
{
//TRACE(_T( " Product scheme[%s] is not exist!\r\n " ),strCurSchemeName);
continue;
}
}
xnProductNodes.clear();
_Close();
return TRUE;
}
void CXmlConfigParse::_Close()
{
m_xmlConfig.Close();
}
LPTSTR CXmlConfigParse::GetConfigFile(LPCTSTR lpszProductName)
{
ASSERT(lpszProductName != NULL);
static CString strConfigFile = _T( " " );
BOOL bOk = m_mapPrdCfg.Lookup(lpszProductName,strConfigFile);
if(!bOk)
{
return NULL;
}
return (LPTSTR)(LPCTSTR)strConfigFile;
}
#if !defined(AFX_LISTEDITCTRL_H__3C02B0B1_A395_11D1_9799_002018026B76__INCLUDED_)
#define AFX_LISTEDITCTRL_H__3C02B0B1_A395_11D1_9799_002018026B76__INCLUDED_
#if _MSC_VER & gt; = 1000
#pragma once
#endif // _MSC_VER & gt; = 1000
// ListEditCtrl.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CListEditCtrl window
class CListEditCtrl : public CEdit
{
// Construction
public:
CListEditCtrl(int iItem, int iSubItem, const CString & sInitText);
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CListEditCtrl)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CListEditCtrl(){};
private:
int m_iItem;
int m_iSubItem;
CString m_strInitText;
BOOL m_bVK_ESCAPE;
// Generated message map functions
protected:
//{{AFX_MSG(CListEditCtrl)
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnNcDestroy();
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_LISTEDITCTRL_H__3C02B0B1_A395_11D1_9799_002018026B76__INCLUDED_)
// FlashOptPage.cpp : implementation file
//
#include " stdafx.h "
#include " dloader.h "
#include " FlashOptPage.h "
#include " EdtBtnCtrl.h "
#include " BMAGlobal.h "
#include " SettingsSheet.h "
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifndef _lint // bad pc-lint
extern BOOL g_bInitSheet;
#endif
static _TCHAR g_sz_SEC_READFLASH[] = _T( " ReadFlash " );
static _TCHAR g_sz_KEY_FLASH[] = _T( " flash " );
#define READ_FLASH 0
#define ERASE_FLASH 1
#define WRITE_FLASH 2
/////////////////////////////////////////////////////////////////////////////
// CFlashOptPage property page
IMPLEMENT_DYNCREATE(CFlashOptPage, CPropertyPage)
CFlashOptPage::CFlashOptPage() : CPropertyPage(CFlashOptPage::IDD)
{
//{{AFX_DATA_INIT(CFlashOptPage)
m_bTmpActiveRead = FALSE;
m_bTmpActiveErase = FALSE;
m_bTmpActiveWrite = FALSE;
m_bTmpEraseAll = FALSE;
//}}AFX_DATA_INIT
m_agReadFlash.RemoveAll();
m_bActiveRead = m_bTmpActiveRead;
m_bActiveErase = m_bTmpActiveErase;
m_bActiveWrite = m_bTmpActiveWrite;
m_bEraseAll = m_bTmpEraseAll;
}
CFlashOptPage::~CFlashOptPage()
{
/*lint -save -e1551 */
Clear();
m_agReadFlash.RemoveAll();
m_agEraseFlash.RemoveAll();
m_agWriteFlash.RemoveAll();
/*lint -restore */
}
void CFlashOptPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFlashOptPage)
DDX_Control(pDX, IDC_FOD_LST_WRITE, m_lstWrite);
DDX_Control(pDX, IDC_FOD_LST_ERASE, m_lstErase);
DDX_Control(pDX, IDC_FOD_LST_READ, m_lstRead);
DDX_Check(pDX, IDC_FOD_CHK_ACTIVE_READ_FLASH, m_bTmpActiveRead);
DDX_Check(pDX, IDC_FOD_CHK_ACTIVE_ERASE_FLASH, m_bTmpActiveErase);
DDX_Check(pDX, IDC_FOD_CHK_ACTIVE_WRITE_FLASH, m_bTmpActiveWrite);
DDX_Check(pDX, IDC_FOD_CHK_ERASE_ALL, m_bTmpEraseAll);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFlashOptPage, CPropertyPage)
//{{AFX_MSG_MAP(CFlashOptPage)
ON_NOTIFY(NM_CLICK, IDC_FOD_LST_READ, OnClickLstRead)
ON_NOTIFY(LVN_ENDLABELEDIT, IDC_FOD_LST_READ, OnEndlabeleditLstRead)
ON_BN_CLICKED(IDC_FOD_BTN_DEL, OnBtnClear)
ON_BN_CLICKED(IDC_FOD_CHK_ACTIVE_READ_FLASH, OnChkActiveReadFlash)
ON_BN_CLICKED(IDC_FOD_BTN_DELE, OnEraseClear)
ON_BN_CLICKED(IDC_FOD_BTN_DELW, OnWriteClear)
ON_BN_CLICKED(IDC_FOD_CHK_ACTIVE_ERASE_FLASH, OnChkActiveEraseFlash)
ON_BN_CLICKED(IDC_FOD_CHK_ACTIVE_WRITE_FLASH, OnChkActiveWriteFlash)
ON_NOTIFY(NM_CLICK, IDC_FOD_LST_ERASE, OnClickLstErase)
ON_NOTIFY(NM_CLICK, IDC_FOD_LST_WRITE, OnClickLstWrite)
ON_NOTIFY(LVN_ENDLABELEDIT, IDC_FOD_LST_ERASE, OnEndlabeleditLstErase)
ON_NOTIFY(LVN_ENDLABELEDIT, IDC_FOD_LST_WRITE, OnEndlabeleditLstWrite)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFlashOptPage message handlers
BOOL CFlashOptPage::OnInitDialog()
{
CPropertyPage::OnInitDialog();
// TODO: Add extra initialization here
InitList(m_lstRead,READ_FLASH);
InitList(m_lstErase,ERASE_FLASH);
InitList(m_lstWrite,WRITE_FLASH);
if(!m_strIniFile.IsEmpty())
{
CString str;
LoadSettings(m_strIniFile,str);
}
FillList(m_lstRead,m_agReadFlash,READ_FLASH);
FillList(m_lstErase,m_agEraseFlash,ERASE_FLASH);
FillList(m_lstWrite,m_agWriteFlash,WRITE_FLASH);
m_bTmpActiveRead = m_bActiveRead;
m_bTmpActiveErase = m_bActiveErase;
m_bTmpActiveWrite = m_bActiveWrite;
m_bTmpEraseAll = m_bEraseAll;
UpdateData(FALSE);
OnChkActiveReadFlash();
OnChkActiveEraseFlash();
OnChkActiveWriteFlash();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CFlashOptPage::ClickList(NMHDR* pNMHDR,CListCtrl & ctrList,int nList)
{
LPNMITEMACTIVATE pnia = (LPNMITEMACTIVATE)pNMHDR;
CEdtBtnCtrl *pCtrl = NULL;
int nItem = pnia- & gt; iItem;
int nSubItem = pnia- & gt; iSubItem;
if(nItem == -1)
{
int nCount = ctrList.GetItemCount();
CString strText;
if( nCount == 0 ||
(nList == READ_FLASH & & !ctrList.GetItemText(nCount-1,1).IsEmpty() & &
!ctrList.GetItemText(nCount-1,2).IsEmpty() & &
!ctrList.GetItemText(nCount-1,3).IsEmpty()) ||
(nList == ERASE_FLASH & & !ctrList.GetItemText(nCount-1,1).IsEmpty() & &
!ctrList.GetItemText(nCount-1,2).IsEmpty())||
(nList == WRITE_FLASH & & !ctrList.GetItemText(nCount-1,1).IsEmpty() & &
!ctrList.GetItemText(nCount-1,3).IsEmpty()))
{
ctrList.InsertItem(nCount,_T( " " ));
if(nCount & gt; 0)
{
ctrList.SetCheck(nCount-1);
}
nItem = nCount;
}
else if(ctrList.GetItemText(nCount-1,1).IsEmpty() & &
ctrList.GetItemText(nCount-1,2).IsEmpty() & &
ctrList.GetItemText(nCount-1,3).IsEmpty())
{
ctrList.DeleteItem(nCount-1);
return;
}
else
{
return;
}
}
if(nSubItem == 0 || (nSubItem == 3 & & nList == ERASE_FLASH) || (nSubItem == 2 & & nList == WRITE_FLASH))
{
return;
}
pCtrl = new CEdtBtnCtrl();
BOOL bEnablBtn = FALSE;
BOOL bOpenFile = FALSE;
if(nSubItem == 3)
{
bEnablBtn = TRUE;
if(nList == WRITE_FLASH)
{
bOpenFile = TRUE;
}
}
if(NULL != pCtrl)
{
pCtrl- & gt; EnableFileSelButton(bEnablBtn);
pCtrl- & gt; SetBtnOpenFlag(bOpenFile);
if(nSubItem == 1 || nSubItem == 2 )
{
pCtrl- & gt; SetEditFmtMode(EX_FMT_HEX);
}
pCtrl- & gt; m_nItem = nItem;
pCtrl- & gt; m_nSubItem = nSubItem;
pCtrl- & gt; m_strText = ctrList.GetItemText(nItem,nSubItem);
if(!pCtrl- & gt; Create(IDD_EDT_BTN_DLG,FromHandle(ctrList.m_hWnd)))
{
AfxMessageBox(_T( " Error to create EdtBtnCtrl " ));
return;
}
}
else
{
return;
}
CRect rect;
ctrList.GetSubItemRect(nItem,nSubItem,LVIR_BOUNDS,rect);
CRect rtList;
ctrList.GetClientRect( & rtList);
if(rect.right & gt; rtList.right)
rect.right = rtList.right;
if(rect.left & lt; rtList.left)
rect.left = rtList.left;
if(rect.bottom & gt; rtList.bottom)
rect.bottom = rtList.bottom;
if(rect.top & lt; rtList.top)
rect.top = rtList.top;
pCtrl- & gt; SetWindowPos( & wndTop,rect.left,rect.top-1,rect.right-rect.left,rect.bottom-rect.top,NULL);
pCtrl- & gt; ShowWindow(SW_SHOW);
}
void CFlashOptPage::OnClickLstRead(NMHDR* pNMHDR, LRESULT* pResult)
{
ClickList(pNMHDR,m_lstRead,0);
*pResult = 0;
}
void CFlashOptPage::OnEndlabeleditLstRead(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
m_lstRead.SetItemText(pDispInfo- & gt; item.iItem,pDispInfo- & gt; item.iSubItem,pDispInfo- & gt; item.pszText);
*pResult = 0;
}
void CFlashOptPage::OnEndlabeleditLstErase(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
m_lstErase.SetItemText(pDispInfo- & gt; item.iItem,pDispInfo- & gt; item.iSubItem,pDispInfo- & gt; item.pszText);
*pResult = 0;
}
void CFlashOptPage::OnEndlabeleditLstWrite(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
m_lstWrite.SetItemText(pDispInfo- & gt; item.iItem,pDispInfo- & gt; item.iSubItem,pDispInfo- & gt; item.pszText);
*pResult = 0;
}
void CFlashOptPage::OnBtnClear()
{
// TODO: Add your control notification handler code here
m_lstRead.DeleteAllItems();
}
BOOL CFlashOptPage::OnKillActive()
{
// TODO: Add your specialized code here and/or call the base class
this- & gt; SetFocus();
if( !g_bInitSheet)
{
if(m_bTmpActiveRead)
{
int nCount = m_lstRead.GetItemCount();
for(int i = 0; i & lt; nCount;i++)
{
if(m_lstRead.GetCheck(i))
{
CString strBase = m_lstRead.GetItemText(i,1);
CString strSize = m_lstRead.GetItemText(i,2);
CString strFile = m_lstRead.GetItemText(i,3);
if(strBase.IsEmpty() || strFile.IsEmpty() || strSize.IsEmpty())
{
m_lstRead.SetFocus();
m_lstRead.SetItemState(i,LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED| LVIS_FOCUSED);
AfxMessageBox(IDS_ERR_ITEM_EMPTY);
return FALSE;
}
}
}
if( nCount & gt; 0 & & m_lstRead.GetItemText(nCount-1,1).IsEmpty() & &
m_lstRead.GetItemText(nCount-1,2).IsEmpty() & &
m_lstRead.GetItemText(nCount-1,3).IsEmpty())
{
m_lstRead.DeleteItem(nCount-1);
}
}
if(m_bTmpActiveErase)
{
int nCount = m_lstErase.GetItemCount();
for(int i = 0; i & lt; nCount;i++)
{
if(m_lstErase.GetCheck(i))
{
CString strBase = m_lstErase.GetItemText(i,1);
CString strSize = m_lstErase.GetItemText(i,2);
if(strBase.IsEmpty() || strSize.IsEmpty())
{
m_lstErase.SetFocus();
m_lstErase.SetItemState(i,LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED| LVIS_FOCUSED);
AfxMessageBox(IDS_ERR_ITEM_EMPTY);
return FALSE;
}
}
}
if( nCount & gt; 0 & & m_lstErase.GetItemText(nCount-1,1).IsEmpty() & &
m_lstErase.GetItemText(nCount-1,2).IsEmpty() )
{
m_lstErase.DeleteItem(nCount-1);
}
}
if(m_bTmpActiveWrite)
{
CFileFind finder;
int nCount = m_lstWrite.GetItemCount();
for(int i = 0; i & lt; nCount;i++)
{
if(m_lstWrite.GetCheck(i))
{
CString strBase = m_lstWrite.GetItemText(i,1);
//CString strSize = m_lstRead.GetItemText(i,2);
CString strFile = m_lstWrite.GetItemText(i,3);
if(strBase.IsEmpty() || strFile.IsEmpty() || (!strFile.IsEmpty() & & !finder.FindFile(strFile)))
{
m_lstWrite.SetFocus();
m_lstWrite.SetItemState(i,LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED| LVIS_FOCUSED);
if(!strFile.IsEmpty() & & !finder.FindFile(strFile))
{
CString strErr;
strErr.Format(_T( " File [%s] not exist! " ),strFile);
AfxMessageBox(strErr);
}
else
{
AfxMessageBox(IDS_ERR_ITEM_EMPTY);
}
return FALSE;
}
}
}
if( nCount & gt; 0 & & m_lstWrite.GetItemText(nCount-1,1).IsEmpty() & &
m_lstWrite.GetItemText(nCount-1,3).IsEmpty())
{
m_lstWrite.DeleteItem(nCount-1);
}
}
}
return CPropertyPage::OnKillActive();
}
void CFlashOptPage::OnOK()
{
// TODO: Add your specialized code here and/or call the base class
UpdateData();
m_bActiveRead = m_bTmpActiveRead;
m_bActiveErase = m_bTmpActiveErase;
m_bActiveWrite = m_bTmpActiveWrite;
m_bEraseAll = m_bTmpEraseAll;
Clear();
int nCount = m_lstRead.GetItemCount();
CFileFind finder;
int i=0;
for(i = 0; i & lt; nCount & & m_bActiveRead;i++)
{
if(m_lstRead.GetCheck(i))
{
CString strBase = m_lstRead.GetItemText(i,1);
CString strSize = m_lstRead.GetItemText(i,2);
CString strFile = m_lstRead.GetItemText(i,3);
CString strID;
if(finder.FindFile(strFile))
{
DWORD dwAttr = GetFileAttributes(strFile);
if(MAXDWORD != dwAttr)
{
dwAttr & = ~FILE_ATTRIBUTE_READONLY;
::SetFileAttributes(strFile,dwAttr);
}
}
PFILE_INFO_T pFileInfo = new FILE_INFO_T;
pFileInfo- & gt; arrBlock[0].dwBase = GetDigit(strBase);
pFileInfo- & gt; arrBlock[0].dwSize = GetDigit(strSize);
strID.Format(_T( " R%08X " ),pFileInfo- & gt; arrBlock[0].dwBase);
_tcscpy(pFileInfo- & gt; szID,strID);
_tcscpy(pFileInfo- & gt; szIDAlias,strID);
_tcscpy(pFileInfo- & gt; szFilePath,strFile);
_tcscpy(pFileInfo- & gt; szType,_T( " ReadFlashAndSave " ));
pFileInfo- & gt; dwCheckFlag = TRUE;
m_agFlashOpr.Add((DWORD)pFileInfo);
}
}
nCount = m_lstErase.GetItemCount();
for(i = 0; i & lt; nCount & & m_bActiveErase;i++)
{
if(m_lstErase.GetCheck(i))
{
CString strBase = m_lstErase.GetItemText(i,1);
CString strSize = m_lstErase.GetItemText(i,2);
CString strFile = m_lstErase.GetItemText(i,3);
CString strID;
PFILE_INFO_T pFileInfo = new FILE_INFO_T;
pFileInfo- & gt; arrBlock[0].dwBase = GetDigit(strBase);
pFileInfo- & gt; arrBlock[0].dwSize = GetDigit(strSize);
strID.Format(_T( " R%08X " ),pFileInfo- & gt; arrBlock[0].dwBase);
_tcscpy(pFileInfo- & gt; szID,strID);
_tcscpy(pFileInfo- & gt; szIDAlias,strID);
//_tcscpy(pFileInfo- & gt; szFilePath,strFile);
_tcscpy(pFileInfo- & gt; szType,_T( " EraseFlash " ));
pFileInfo- & gt; dwCheckFlag = TRUE;
m_agFlashOpr.Add((DWORD)pFileInfo);
}
}
nCount = m_lstWrite.GetItemCount();
for(i = 0; i & lt; nCount & & m_bActiveWrite;i++)
{
if(m_lstWrite.GetCheck(i))
{
CString strBase = m_lstWrite.GetItemText(i,1);
CString strSize = m_lstWrite.GetItemText(i,2);
CString strFile = m_lstWrite.GetItemText(i,3);
CString strID;
PFILE_INFO_T pFileInfo = new FILE_INFO_T;
pFileInfo- & gt; arrBlock[0].dwBase = GetDigit(strBase);
pFileInfo- & gt; arrBlock[0].dwSize = GetDigit(strSize);
strID.Format(_T( " W%08X " ),pFileInfo- & gt; arrBlock[0].dwBase);
_tcscpy(pFileInfo- & gt; szID,strID);
_tcscpy(pFileInfo- & gt; szIDAlias,strID);
_tcscpy(pFileInfo- & gt; szFilePath,strFile);
_tcscpy(pFileInfo- & gt; szType,_T( " CODE " ));
pFileInfo- & gt; dwCheckFlag = TRUE;
m_agFlashOpr.Add((DWORD)pFileInfo);
}
}
//±£´æÉèÖÃ
if(!m_strIniFile.IsEmpty() & & finder.FindFile(m_strIniFile))
{
DWORD dwAttr = GetFileAttributes(m_strIniFile);
if(MAXDWORD != dwAttr)
{
dwAttr & = ~FILE_ATTRIBUTE_READONLY;
::SetFileAttributes(m_strIniFile,dwAttr);
}
SaveSettings(m_strIniFile);
}
CPropertyPage::OnOK();
}
void CFlashOptPage::Clear()
{
for(int i = 0; i & lt; m_agFlashOpr.GetSize(); i++)
{
delete [] (PFILE_INFO_T)m_agFlashOpr[i];
}
m_agFlashOpr.RemoveAll();
}
void CFlashOptPage::OnChkActiveReadFlash()
{
// TODO: Add your control notification handler code here
UpdateData();
if(m_bTmpActiveRead)
{
m_lstRead.EnableWindow(TRUE);
GetDlgItem(IDC_FOD_BTN_DEL)- & gt; EnableWindow(TRUE);
}
else
{
m_lstRead.EnableWindow(FALSE);
GetDlgItem(IDC_FOD_BTN_DEL)- & gt; EnableWindow(FALSE);
}
}
BOOL CFlashOptPage::LoadSettings(LPCTSTR pFileName,CString & strErrorMsg)
{
// UNUSED_ALWAYS(strErrorMsg);
if(NULL == pFileName)
{
strErrorMsg += _T( " Configure file is empty!\n " );
return FALSE;
}
m_strIniFile = pFileName;
LoadFlashOpr(_T( " ReadFlash " ),m_agReadFlash);
LoadFlashOpr(_T( " EraseFlash " ),m_agEraseFlash);
LoadFlashOpr(_T( " WriteFlash " ),m_agWriteFlash);
return TRUE;
}
BOOL CFlashOptPage::SaveSettings(LPCTSTR pFileName)
{
if(NULL == pFileName)
return FALSE;
SaveFlashOpr(m_lstRead,_T( " ReadFlash " ),pFileName);
SaveFlashOpr(m_lstErase,_T( " EraseFlash " ),pFileName);
SaveFlashOpr(m_lstWrite,_T( " WriteFlash " ),pFileName);
return TRUE;
}
void CFlashOptPage::SaveFlashOpr(CListCtrl & ctrList,LPCTSTR lpszSec,LPCTSTR lpszFile)
{
WritePrivateProfileSection(lpszSec,_T( " " ),lpszFile);
int nCount = ctrList.GetItemCount();
for(int i= 0; i & lt; nCount; i++)
{
CString strText;
strText.Format(_T( " %d:%s:%s:%s " ),
ctrList.GetCheck(i),
ctrList.GetItemText(i,1).operator LPCTSTR(),
ctrList.GetItemText(i,2).operator LPCTSTR(),
ctrList.GetItemText(i,3).operator LPCTSTR());
CString strKey;
strKey.Format(_T( " %s%02d " ),g_sz_KEY_FLASH,i);
WritePrivateProfileString(lpszSec,strKey,strText,lpszFile);
}
}
void CFlashOptPage::FillList(CListCtrl & ctrList,CStringArray & agList,int nList)
{
int nFlashCount = agList.GetSize();
for(int i= 0; i & lt; nFlashCount; i++)
{
CString strText = agList[i];
if(strText.IsEmpty())
continue;
CString strBase;
CString strSize;
CString strFile;
BOOL bCheck = FALSE;
LPTSTR pBuf = strText.GetBuffer(1);
LPTSTR pFind = _tcschr(pBuf,':');
if(pFind != NULL)
{
*pFind = '\0';
bCheck = GetDigit(pBuf);
pBuf = pFind + 1;
}
else
{
strText.ReleaseBuffer();
continue;
}
pFind = _tcschr(pBuf,':');
if(pFind != NULL)
{
*pFind = '\0';
strBase = pBuf;
pBuf = pFind + 1;
}
else
{
strText.ReleaseBuffer();
continue;
}
pFind = _tcschr(pBuf,':');
if(pFind != NULL)
{
*pFind = '\0';
strSize = pBuf;
pBuf = pFind + 1;
}
else
{
if(nList == READ_FLASH || nList == ERASE_FLASH)
{
strText.ReleaseBuffer();
continue;
}
}
strFile = pBuf;
int nCount = ctrList.GetItemCount();
if( /*!bCheck || */
( nList == READ_FLASH & & !strBase.IsEmpty() & & !strSize.IsEmpty() & & !strFile.IsEmpty()) ||
( nList == ERASE_FLASH & & !strBase.IsEmpty() & & !strSize.IsEmpty()) ||
( nList == WRITE_FLASH & & !strBase.IsEmpty() & & !strFile.IsEmpty()) )
{
ctrList.InsertItem(nCount,_T( " " ));
ctrList.SetItemText(nCount,1,strBase);
if(nList == READ_FLASH)
{
ctrList.SetItemText(nCount,2,strSize);
ctrList.SetItemText(nCount,3,strFile);
}
else if(nList == ERASE_FLASH)
{
ctrList.SetItemText(nCount,2,strSize);
ctrList.SetItemText(nCount,3,_T( " " ));
}
else if(nList == WRITE_FLASH)
{
ctrList.SetItemText(nCount,2,_T( " " ));
ctrList.SetItemText(nCount,3,strFile);
}
ctrList.SetCheck(nCount,bCheck);
}
}
int nCount = ctrList.GetItemCount();
if( nCount & gt; 0 & & ctrList.GetItemText(nCount-1,1).IsEmpty() & &
ctrList.GetItemText(nCount-1,2).IsEmpty() & &
ctrList.GetItemText(nCount-1,3).IsEmpty())
{
ctrList.DeleteItem(nCount-1);
}
}
void CFlashOptPage::OnEraseClear()
{
// TODO: Add your control notification handler code here
m_lstErase.DeleteAllItems();
}
void CFlashOptPage::OnWriteClear()
{
// TODO: Add your control notification handler code here
m_lstWrite.DeleteAllItems();
}
void CFlashOptPage::InitList(CListCtrl & ctrList,int nList)
{
ctrList.SetBkColor(RGB(232, 232, 232));
ctrList.ModifyStyle(0, LVS_SHOWSELALWAYS);
DWORD dwExStyle = ctrList.GetExtendedStyle();
dwExStyle |= LVS_EX_FULLROWSELECT;
dwExStyle |= LVS_EX_GRIDLINES;
dwExStyle |= LVS_EX_CHECKBOXES;
ctrList.SetExtendedStyle(dwExStyle);
//Load Column
CString strClmn;
VERIFY( strClmn.LoadString(IDS_READ_FLASH_LIST_COL) );
int nLen = strClmn.GetLength();
LPTSTR lpBuf = strClmn.GetBuffer(nLen);
LPTSTR lpFind = _tcschr(lpBuf, _T(','));
int nIndex = 0;
while(lpFind != NULL)
{
*lpFind = _T('\0');
if(nIndex == 0)
{
ctrList.InsertColumn(nIndex++,lpBuf,LVCFMT_LEFT,50);
}
else
{
ctrList.InsertColumn(nIndex++,lpBuf,LVCFMT_LEFT,110);
}
lpBuf = lpFind + 1;
lpFind = _tcschr(lpBuf, _T(','));
}
ctrList.InsertColumn(nIndex, lpBuf, LVCFMT_LEFT, 229 );
strClmn.ReleaseBuffer();
LVCOLUMN col;
col.mask = LVCF_TEXT;
col.pszText = NULL;
if(nList == ERASE_FLASH)
{
ctrList.SetColumn(3, & col);
}
else if(nList == WRITE_FLASH)
{
ctrList.SetColumn(2, & col);
}
}
void CFlashOptPage::OnChkActiveEraseFlash()
{
// TODO: Add your control notification handler code here
UpdateData();
if(m_bTmpActiveErase)
{
m_lstErase.EnableWindow(TRUE);
GetDlgItem(IDC_FOD_BTN_DELE)- & gt; EnableWindow(TRUE);
}
else
{
m_lstErase.EnableWindow(FALSE);
GetDlgItem(IDC_FOD_BTN_DELE)- & gt; EnableWindow(FALSE);
}
}
void CFlashOptPage::OnChkActiveWriteFlash()
{
// TODO: Add your control notification handler code here
UpdateData();
if(m_bTmpActiveWrite)
{
m_lstWrite.EnableWindow(TRUE);
GetDlgItem(IDC_FOD_BTN_DELW)- & gt; EnableWindow(TRUE);
}
else
{
m_lstWrite.EnableWindow(FALSE);
GetDlgItem(IDC_FOD_BTN_DELW)- & gt; EnableWindow(FALSE);
}
}
BOOL CFlashOptPage::LoadFlashOpr(LPCTSTR lpszSec, CStringArray & agList)
{
agList.RemoveAll();
_TCHAR szKeyValue[ MAX_BUF_SIZE ]={0};
GetPrivateProfileSection( lpszSec, szKeyValue, MAX_BUF_SIZE, m_strIniFile );
CStringArray arrKeyData;
UINT nFileCount = (UINT)EnumKeys(szKeyValue, & arrKeyData);
for(UINT i= 0; i & lt; nFileCount; i++)
{
CString strText = arrKeyData[2*i+1];
if(!strText.IsEmpty())
{
agList.Add(strText);
}
}
return TRUE;
}
void CFlashOptPage::OnClickLstErase(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
ClickList(pNMHDR,m_lstErase,1);
*pResult = 0;
}
void CFlashOptPage::OnClickLstWrite(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
ClickList(pNMHDR,m_lstWrite,2);
*pResult = 0;
}
//Layout.cpp
#include " stdafx.h "
#include & lt; windowsx.h & gt;
#include " Layout.h "
#include & lt; malloc.h & gt;
#if !defined(ASSERT)
#define ASSERT ATLASSERT
#endif
///////////////////////////////////////////////////////////////////////////////
// A MapDialogRect function that works for non-dialog windows.
BOOL adgMapDialogRect (HWND hwndParent, PRECT prc) {
HDC hdc;
SIZE size;
int cxChar, cyChar;
HFONT hfont=NULL, hfontOriginal=NULL;
// This is the set of characters that Windows uses to compute the average
// character width.
static TCHAR szChars[] =
__TEXT( " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ " );
// Check assumptions.
ASSERT(IsWindow(hwndParent));
ASSERT(prc);
// If the window is a dialog, just use MapDialogRect.
if (GetClassWord(hwndParent, GCW_ATOM) == 32770)
return(MapDialogRect(hwndParent, prc));
// Get a device context and select the window's font into it.
hdc = GetDC(hwndParent);
hfont = GetWindowFont(hwndParent);
if (hfont != NULL)
hfontOriginal = SelectFont(hdc, hfont);
// Unfortunately, we cannot use GetTextMetrics to get the average character
// width because the TEXTMETRIC structure's tmAveCharWidth member is
// incorrect for proportional fonts. So, instead we compute the average
// character width ourselves using the same technique employed by Windows
// itself: We pass " a-zA-Z " to GetTextExtentPoint and average, rounding up.
// (NOTE: We do not call GetTextExtentPoint32 because this function corrects
// an error that Windows relies on)
GetTextExtentPoint(hdc, szChars, adgARRAY_SIZE(szChars), & size);
cyChar = size.cy;
cxChar = ((size.cx / (adgARRAY_SIZE(szChars) / 2)) + 1) / 2;
// Restore any original font and then release the device context.
if (hfont != NULL)
SelectFont(hdc, hfontOriginal);
ReleaseDC(hwndParent, hdc);
// Map rectangle prc based on the font dimensions (cxChar by cyChar).
SetRect(prc,
prc- & gt; left * cxChar / 4, prc- & gt; top * cyChar / 8,
prc- & gt; right * cxChar / 4, prc- & gt; bottom * cyChar / 8);
return(TRUE);
}
int Layout_GetOppositeSide (int nSide) {
int nOppositeSide=lpRIGHT;
// Check assumptions.
ASSERT(ISSIDE(nSide));
switch (nSide) {
case lpLEFT:
nOppositeSide = lpRIGHT;
break;
case lpRIGHT:
nOppositeSide = lpLEFT;
break;
case lpTOP:
nOppositeSide = lpBOTTOM;
break;
case lpBOTTOM:
nOppositeSide = lpTOP;
break;
default: // Invalid side
ASSERT(!__TEXT( " Invalid side " ));
break;
}
return(nOppositeSide);
}
CHILD* Layout_FindChild (CHILD* pChildList, int idcChild) {
CHILD *pChild;
// Check assumptions.
ASSERT(pChildList);
ASSERT(adgINRANGE(0, idcChild, IDC_LASTCHILD));
// Traverse the child list looking for an id
for (pChild = pChildList; pChild- & gt; idc != IDC_LASTCHILD; pChild++) {
// If we find idcChild, we solve the child for unknowns and return it
if (pChild- & gt; idc == idcChild) {
Layout_SolveChild(pChild);
return(pChild);
}
}
ASSERT(!__TEXT( " Child not found in child list " ));
return(NULL);
}
CHILD* Layout_CreateChildList (HWND hwndParent, int* pnChildren) {
int i;
HWND hwnd, hwndFirst;
CHILD* pChild, *pChildList;
// Check assumptions.
ASSERT(IsWindow(hwndParent));
ASSERT(pnChildren);
// Count the number of child windows in hwndParent.
hwndFirst = hwnd = GetFirstChild(hwndParent);
for (*pnChildren = 0; IsWindow(hwnd); hwnd = GetNextSibling(hwnd))
(*pnChildren)++;
if (*pnChildren == 0)
return(NULL);
// Allocate memory for the CHILD list. This list will have an entry for
// each child of the dialog, plus a CHILD structure for the parent window
// (lPARENT) and one which acts as a list terminator (IDC_LASTCHILD).
pChildList = (CHILD*)malloc((*pnChildren + 2) * sizeof(CHILD));
ASSERT(pChildList);
if (!pChildList)
return(NULL);
pChild = pChildList;
// Add the special-case parent 'CHILD' structure
pChild- & gt; idc = lPARENT;
GetClientRect(hwndParent, & pChild- & gt; rc);
for (i = 0; i & lt; NUMSIDES; i++)
pChild- & gt; afMetric[i] = KNOWN;
pChild- & gt; afMetric[lpWIDTH] = pChild- & gt; afMetric[lpHEIGHT] = UNKNOWN;
Layout_SolveChild(pChild);
pChild++;
// Add all the real children of the dialog to the list
hwnd = hwndFirst;
for (; IsWindow(hwnd); hwnd = GetNextSibling(hwnd)) {
// Get child's id and bounding rectangle in client coordinates
pChild- & gt; idc = GetWindowID(hwnd);
GetWindowRect(hwnd, & pChild- & gt; rc);
MapWindowRect(HWND_DESKTOP, hwndParent, & pChild- & gt; rc);
for (i = 0; i & lt; NUMSIDES; i++)
pChild- & gt; afMetric[i] = KNOWN;
// Solve for the width and height.
pChild- & gt; afMetric[lpWIDTH] = pChild- & gt; afMetric[lpHEIGHT] = UNKNOWN;
Layout_SolveChild(pChild);
// All children are fixed, initially.
pChild- & gt; fFixed = TRUE;
pChild++;
}
// Terminate and return the list.
pChild- & gt; idc = IDC_LASTCHILD;
return(pChildList);
}
void Layout_ConvertDlgUnits (HWND hwndParent, RULE* pRules, CHILD* pChildList) {
pChildList;
RECT rc = { 0, 0, 0, 0 };
BOOL fVertical=FALSE;
RULE* pRule;
// Check assumptions.
ASSERT(IsWindow(hwndParent));
ASSERT(pRules);
ASSERT(pChildList);
// Traverse the rules list
for (pRule = pRules; pRule- & gt; Action != lEND; pRule++) {
// Simultaneously map the rule's offset value, vertically and
// horizontally, from dialog units to pixels.
rc.right = rc.bottom = pRule- & gt; nOffset;
adgMapDialogRect(hwndParent, & rc);
// Determine if the current rule affects horizontal or vertical
// coordinates. We need to know this because dialog unit space is not
// isometric (horizontal and vertical dialog units are not equivalent).
switch (pRule- & gt; Action) {
case lVCENTER:
fVertical = TRUE;
break;
case lHCENTER:
fVertical = FALSE;
break;
case lMOVE:
case lSTRETCH:
fVertical = Layout_MetricIsVertical(pRule- & gt; ActOn.nMetric);
break;
default:
ASSERT(!__TEXT( " Invalid action " ));
break;
}
// Take the correct mapped value based on the rule being applied
pRule- & gt; nPixelOffset = fVertical ? rc.bottom : rc.right;
}
}
void Layout_MarkUnknowns (HWND hwndParent, RULE* pRules, CHILD* pChildList) {
RULE* pRule;
CHILD* pChildActOn;
HWND hwnd;
int nOtherUnknown, nOppositeSide, idc, idcFirst, idcLast;
// Check assumptions.
ASSERT(IsWindow(hwndParent));
ASSERT(pRules);
ASSERT(pChildList);
// Traverse the rule list, marking unknowns in the child list.
for (pRule = pRules; pRule- & gt; Action != lEND; pRule++) {
// Set metric flags based on the rule's proposed action
switch (pRule- & gt; Action) {
case lSTRETCH: // Metric should be stretched
// Find the child to be acted upon
pChildActOn = Layout_FindChild(pChildList, pRule- & gt; ActOn.idc);
ASSERT(pChildActOn);
// Since the child is going to be acted upon, it is no longer fixed.
pChildActOn- & gt; fFixed = FALSE;
// The part being acted on must be a metric.
ASSERT(ISMETRIC(pRule- & gt; ActOn.nMetric));
// The metric being stretched must be unknown.
pChildActOn- & gt; afMetric[pRule- & gt; ActOn.nMetric] = UNKNOWN;
// If the left/top or right/bottom is unknown, so is the
// width/height. If the width/height is unknown, then the
// right/bottom is also unknown.
nOtherUnknown = Layout_GetOtherUnknownMetric(pRule- & gt; ActOn.nMetric);
pChildActOn- & gt; afMetric[nOtherUnknown] = UNKNOWN;
break;
case lMOVE: // Control should be moved
// Find the child to be acted upon
pChildActOn = Layout_FindChild(pChildList, pRule- & gt; ActOn.idc);
ASSERT(pChildActOn);
// Since the child is going to be acted upon, it is no longer fixed.
pChildActOn- & gt; fFixed = FALSE;
// The part being acted upon must be a side.
ASSERT(ISSIDE(pRule- & gt; ActOn.nSide));
// The side being moved is unknown.
pChildActOn- & gt; afMetric[pRule- & gt; ActOn.nSide] = UNKNOWN;
// So is the opposite side. But, the width/height remains known.
// (Actually, this is the primary reason for having six metrics).
nOppositeSide = Layout_GetOppositeSide(pRule- & gt; ActOn.nSide);
pChildActOn- & gt; afMetric[nOppositeSide] = UNKNOWN;
break;
case lVCENTER: // Vertically center control/group
case lHCENTER: // Horizontally center control/group
// We must be centering a group of one or more controls.
ASSERT(pRule- & gt; ActOn.nPart == lpGROUP);
// Go through the group of one or more controls
idcFirst = pRule- & gt; ActOn.idcFirst;
idcLast = pRule- & gt; ActOn.idcLast;
ASSERT(idcFirst & lt; = idcLast);
hwnd = GetFirstChild(hwndParent);
for (; IsWindow(hwnd); hwnd = GetNextSibling(hwnd)) {
idc = GetWindowID(hwnd);
if (adgINRANGE(idcFirst, idc, idcLast)) {
// Find the child to be acted upon and set the appropriate
// sides to unknown. Width is still known.
pChildActOn = Layout_FindChild(pChildList, idc);
if (pRule- & gt; Action == lHCENTER) {
pChildActOn- & gt; afMetric[lpLEFT] = UNKNOWN;
pChildActOn- & gt; afMetric[lpRIGHT] = UNKNOWN;
} else {
pChildActOn- & gt; afMetric[lpTOP] = UNKNOWN;
pChildActOn- & gt; afMetric[lpBOTTOM] = UNKNOWN;
}
// Child acted upon is no longer fixed.
pChildActOn- & gt; fFixed = FALSE;
}
}
break;
default:
ASSERT(!__TEXT( " Invalid action " ));
break;
}
}
}
int Layout_GetOtherUnknownMetric (int nUnknownMetric) {
int nOtherUnknownMetric = 0;
// Check assumptions.
ASSERT(ISMETRIC(nUnknownMetric));
switch (nUnknownMetric) {
case lpLEFT:
case lpRIGHT:
nOtherUnknownMetric = lpWIDTH;
break;
case lpTOP:
case lpBOTTOM:
nOtherUnknownMetric = lpHEIGHT;
break;
case lpWIDTH:
nOtherUnknownMetric = lpRIGHT;
break;
case lpHEIGHT:
nOtherUnknownMetric = lpBOTTOM;
break;
default:
ASSERT(!__TEXT( " Invalid metric " ));
break;
}
return(nOtherUnknownMetric);
}
BOOL Layout_MetricIsVertical (int nMetric) {
BOOL fMetricIsVertical = FALSE;
// Check assumptions.
ASSERT(ISMETRIC(nMetric));
switch (nMetric) {
case lpLEFT:
case lpRIGHT:
case lpWIDTH:
fMetricIsVertical = FALSE;
break;
case lpTOP:
case lpBOTTOM:
case lpHEIGHT:
fMetricIsVertical = TRUE;
break;
default:
ASSERT(!__TEXT( " Invalid metric " ));
break;
}
return(fMetricIsVertical);
}
void Layout_SolveChild (CHILD* pChild) {
int i;
// Check assumptions.
ASSERT(pChild);
// Loop through all six metrics of a child, computing values for unknown
// metrics from values of known metrics (if any).
for (i = 0; i & lt; NUMMETRICS; i++) {
// If this metric of the child is unknown, see if it can be computed in
// terms of other metrics which we do know.
if (pChild- & gt; afMetric[i] == UNKNOWN) {
// Compute left/top as right/bottom - width/height
if (i & lt; 2) {
if ((pChild- & gt; afMetric[i + 2] == KNOWN) & &
(pChild- & gt; afMetric[i + 4] == KNOWN)) {
pChild- & gt; anMetric[i] = pChild- & gt; anMetric[i + 2] -
pChild- & gt; anMetric[i + 4];
pChild- & gt; afMetric[i] = KNOWN;
}
}
// Compute right/bottom as left/top + width/height
else if (i & lt; 4) {
if ((pChild- & gt; afMetric[i - 2] == KNOWN) & &
(pChild- & gt; afMetric[i + 2] == KNOWN)) {
pChild- & gt; anMetric[i] = pChild- & gt; anMetric[i - 2] +
pChild- & gt; anMetric[i + 2];
pChild- & gt; afMetric[i] = KNOWN;
}
}
// Compute width/height as right/bottom - left/top
else {
if ((pChild- & gt; afMetric[i - 2] == KNOWN) & &
(pChild- & gt; afMetric[i - 4] == KNOWN)) {
pChild- & gt; anMetric[i] = pChild- & gt; anMetric[i - 2] -
pChild- & gt; anMetric[i - 4];
pChild- & gt; afMetric[i] = KNOWN;
}
}
}
}
}
BOOL Layout_CheckChild (CHILD* pChild) {
static TCHAR* pszMetric[] = {
__TEXT( " left " ), __TEXT( " top " ), __TEXT( " right " ),
__TEXT( " bottom " ), __TEXT( " width " ), __TEXT( " height " )
};
int i;
BOOL fOK = TRUE;
TCHAR sz[80];
// Check assumptions.
ASSERT(pChild);
// Any unknown metric indicates a problem with the rules, so we 'assert'.
for (i = 0; i & lt; NUMMETRICS; i++) {
if (pChild- & gt; afMetric[i] == UNKNOWN) {
wsprintf(sz, __TEXT( " Layout couldn't find %s of id=%d " ),
pszMetric[i], pChild- & gt; idc);
adgMB(sz);
fOK = FALSE;
}
}
return(fOK);
}
BOOL Layout_ApplyRule (HWND hwndParent, RULE* pRules,
CHILD* pChildList, RULE* pRule) {
CHILD* pChildRelTo, *pChildActOn, ChildRelTo;
CHILD* pChild, *pChildListNew, *pSrc, *pDest;
int nRules, nMetric, nChildren;
int idcFirst, idcLast, nOffset, nCentered;
RECT rcBounds;
HWND hwnd, hwndFirst;
RULE *pr, *prn, *prNew;
// Check assumptions.
ASSERT(IsWindow(hwndParent));
ASSERT(pRules);
ASSERT(pChildList);
ASSERT(pRule);
// Find the child and part(s) that we are going to act relative to
pChildRelTo = Layout_FindChild(pChildList, pRule- & gt; RelTo.idc);
ASSERT(pChildRelTo);
switch (pRule- & gt; RelTo.nPart) {
case lpLEFT:
case lpTOP:
case lpRIGHT:
case lpBOTTOM:
case lpWIDTH:
case lpHEIGHT:
// We can't apply a rule relative to a metric that is unknown.
if (pChildRelTo- & gt; afMetric[pRule- & gt; RelTo.nMetric] == UNKNOWN)
return(FALSE);
break;
case lpGROUP:
// We can't apply a rule relative to a control unless we know its
// left/top and right/bottom sides (for centering).
ASSERT(pRule- & gt; RelTo.idcFirst == pRule- & gt; RelTo.idcLast);
ASSERT((pRule- & gt; Action == lHCENTER) || (pRule- & gt; Action == lVCENTER));
if (pRule- & gt; Action == lHCENTER) {
if ((pChildRelTo- & gt; afMetric[lpLEFT] == UNKNOWN) ||
(pChildRelTo- & gt; afMetric[lpRIGHT] == UNKNOWN))
return(FALSE);
} else {
if ((pChildRelTo- & gt; afMetric[lpTOP] == UNKNOWN) ||
(pChildRelTo- & gt; afMetric[lpBOTTOM] == UNKNOWN))
return(FALSE);
}
break;
}
// Make a local copy of the child we are relative to. We need to do this
// because we may need to apply a percentage to the width/height metrics
// and we don't want to modify the actual child list.
ChildRelTo = *pChildRelTo;
// Use percentage to modify the width/height of the child we are relative to
if ((pRule- & gt; RelTo.nMetric == lpWIDTH) || (pRule- & gt; RelTo.nMetric == lpHEIGHT)) {
ChildRelTo.anMetric[pRule- & gt; RelTo.nMetric] *= pRule- & gt; RelTo.nPercent;
ChildRelTo.anMetric[pRule- & gt; RelTo.nMetric] /= 100;
Layout_SolveChild( & ChildRelTo);
}
// Apply our rule based on the action field
switch (pRule- & gt; Action) {
case lSTRETCH: // Metric should be stretched
// The part being acted on must be a metric. If it is a width/height
// metric, it must be 100% of the width/height.
ASSERT(ISMETRIC(pRule- & gt; ActOn.nMetric));
ASSERT(ISSIDE(pRule- & gt; ActOn.nSide) ||
(pRule- & gt; ActOn.nPercent == 100));
// The part being acted relative to must be a metric.
ASSERT(ISMETRIC(pRule- & gt; RelTo.nMetric));
// Find the child being acted on and stretch the specified metric.
pChildActOn = Layout_FindChild(pChildList, pRule- & gt; ActOn.idc);
ASSERT(pChildActOn);
pChildActOn- & gt; anMetric[pRule- & gt; ActOn.nMetric] =
ChildRelTo.anMetric[pRule- & gt; RelTo.nMetric] + pRule- & gt; nPixelOffset;
pChildActOn- & gt; afMetric[pRule- & gt; ActOn.nMetric] = KNOWN;
Layout_SolveChild(pChildActOn);
pRule- & gt; fState = APPLIED;
return(TRUE);
case lMOVE: // Whole control should be moved
// The part being moved must be a side.
ASSERT(ISSIDE(pRule- & gt; ActOn.nSide));
// The part that is being acted relative to must be a metric.
ASSERT(ISMETRIC(pRule- & gt; RelTo.nMetric));
// Find the child being acted on and move the specified side.
pChildActOn = Layout_FindChild(pChildList, pRule- & gt; ActOn.idc);
ASSERT(pChildActOn);
pChildActOn- & gt; anMetric[pRule- & gt; ActOn.nSide] =
ChildRelTo.anMetric[pRule- & gt; RelTo.nMetric] + pRule- & gt; nPixelOffset;
pChildActOn- & gt; afMetric[pRule- & gt; ActOn.nSide] = KNOWN;
Layout_SolveChild(pChildActOn);
pRule- & gt; fState = APPLIED;
return(TRUE);
case lVCENTER: // Vertically center a control/group
case lHCENTER: // Horizontally center a control/group
// We can only center a group of one or more controls relative to
// another control (a single control is a 'group' of one control).
ASSERT(pRule- & gt; ActOn.nPart == lpGROUP);
ASSERT(pRule- & gt; RelTo.nPart == lpGROUP);
ASSERT(pRule- & gt; RelTo.idcFirst == pRule- & gt; RelTo.idcLast);
// First id in group must be less than or equal to the last id
idcFirst = pRule- & gt; ActOn.idcFirst;
idcLast = pRule- & gt; ActOn.idcLast;
ASSERT(idcFirst & lt; = idcLast);
// Ensure that the width/height is known for each control in the
// group before proceeding with any centering.
hwndFirst = GetFirstChild(hwndParent);
for (hwnd = hwndFirst; IsWindow(hwnd); hwnd = GetNextSibling(hwnd)) {
int idc = GetWindowID(hwnd);
if (adgINRANGE(idcFirst, idc, idcLast)) {
pChildActOn = Layout_FindChild(pChildList, idc);
if (pRule- & gt; Action == lHCENTER) {
if (pChildActOn- & gt; afMetric[lpWIDTH] == UNKNOWN)
return(FALSE);
} else {
if (pChildActOn- & gt; afMetric[lpHEIGHT] == UNKNOWN)
return(FALSE);
}
}
}
// Create a new list of rules which contains the subset of rules
// which act on controls in the centered group.
for (nRules = 0, pr = pRules; pr- & gt; Action != lEND; pr++)
nRules++;
nRules++;
prNew = (RULE*)_alloca(nRules * sizeof(RULE));
prn = prNew;
for (pr = pRules; pr- & gt; Action != lEND; pr++) {
if (adgINRANGE(idcFirst, pr- & gt; ActOn.idc, idcLast)) {
if (pRule- & gt; Action == lHCENTER) {
if ((pr- & gt; ActOn.nPart == lpLEFT) ||
(pr- & gt; ActOn.nPart == lpRIGHT)) {
*prn++ = *pr;
}
} else {
if ((pr- & gt; ActOn.nPart == lpTOP) ||
(pr- & gt; ActOn.nPart == lpBOTTOM)) {
*prn++ = *pr;
}
}
}
}
prn- & gt; Action = lEND;
// Make a local copy of the child list and set everything to KNOWN.
nChildren = 0;
for (pChild = pChildList; pChild- & gt; idc != IDC_LASTCHILD; pChild++)
nChildren++;
nChildren++;
pChildListNew = (CHILD*)_alloca(nChildren * sizeof(CHILD));
MoveMemory(pChildListNew, pChildList, nChildren * sizeof(CHILD));
for (pChild = pChildListNew; pChild- & gt; idc != IDC_LASTCHILD; pChild++)
for (nMetric = 0; nMetric & lt; NUMMETRICS; nMetric++)
pChild- & gt; afMetric[nMetric] = KNOWN;
// Solve for the children being centered as a sub-problem.
if (!Layout_ApplyRules (hwndParent, prNew, pChildListNew)) {
ASSERT(!__TEXT( " Unable to apply rules to centered children " ));
return(FALSE);
}
// Compute the bounding rectangle of the group
SetRectEmpty( & rcBounds);
hwndFirst = GetFirstChild(hwndParent);
for (hwnd = hwndFirst; IsWindow(hwnd); hwnd = GetNextSibling(hwnd)) {
int idc = GetWindowID(hwnd);
if (adgINRANGE(idcFirst, idc, idcLast)) {
pChildActOn = Layout_FindChild(pChildListNew, idc);
UnionRect( & rcBounds, & rcBounds, & pChildActOn- & gt; rc);
}
}
// Find the offset required to center the group's bounding rectangle
// against the control we are relative to.
if (pRule- & gt; Action == lHCENTER) {
nCentered = ChildRelTo.anMetric[lpLEFT] +
((ChildRelTo.anMetric[lpWIDTH] -
(rcBounds.right - rcBounds.left)) / 2);
nOffset = nCentered - rcBounds.left;
} else {
nCentered = ChildRelTo.anMetric[lpTOP] +
((ChildRelTo.anMetric[lpHEIGHT] -
(rcBounds.bottom - rcBounds.top)) / 2);
nOffset = nCentered - rcBounds.top;
}
// Add in any additional offset from the rule.
nOffset += pRule- & gt; nPixelOffset;
// Go through the new child list, moving each control.
ASSERT(pRule- & gt; ActOn.idcFirst & lt; = pRule- & gt; ActOn.idcLast);
for (hwnd = hwndFirst; IsWindow(hwnd); hwnd = GetNextSibling(hwnd)) {
int idc = GetWindowID(hwnd);
if (adgINRANGE(idcFirst, idc, idcLast)) {
pChildActOn = Layout_FindChild(pChildListNew, idc);
if (pRule- & gt; Action == lHCENTER) {
pChildActOn- & gt; anMetric[lpLEFT] += nOffset;
pChildActOn- & gt; anMetric[lpRIGHT] += nOffset;
} else {
pChildActOn- & gt; anMetric[lpTOP] += nOffset;
pChildActOn- & gt; anMetric[lpBOTTOM] += nOffset;
}
}
}
// Now modify the real child list based on pChildListNew.
for (pSrc = pChildListNew, pDest = pChildList;
pSrc- & gt; idc != IDC_LASTCHILD; pSrc++, pDest++) {
if (adgINRANGE(idcFirst, pSrc- & gt; idc, idcLast)) {
if (pRule- & gt; Action == lHCENTER) {
pDest- & gt; anMetric[lpLEFT] = pSrc- & gt; anMetric[lpLEFT];
pDest- & gt; anMetric[lpRIGHT] = pSrc- & gt; anMetric[lpRIGHT];
pDest- & gt; afMetric[lpLEFT] = KNOWN;
pDest- & gt; afMetric[lpRIGHT] = KNOWN;
} else {
pDest- & gt; anMetric[lpTOP] = pSrc- & gt; anMetric[lpTOP];
pDest- & gt; anMetric[lpBOTTOM] = pSrc- & gt; anMetric[lpBOTTOM];
pDest- & gt; afMetric[lpTOP] = KNOWN;
pDest- & gt; afMetric[lpBOTTOM] = KNOWN;
}
}
}
pRule- & gt; fState = APPLIED;
return(TRUE);
default:
ASSERT(!__TEXT( " Invalid action " ));
return(FALSE);
}
}
BOOL Layout_ApplyRules (HWND hwndParent, RULE* pRules, CHILD* pChildList) {
RULE* pRule;
BOOL fAppliedAtLeastOneRule, fOK = TRUE;
// Check assumptions.
ASSERT(IsWindow(hwndParent));
ASSERT(pRules);
ASSERT(pChildList);
// Based on the list of rules, mark all unknown child metrics as UNKNOWN.
Layout_MarkUnknowns(hwndParent, pRules, pChildList);
// Traverse the rule list, converting offsets from dialog units to pixels.
Layout_ConvertDlgUnits(hwndParent, pRules, pChildList);
// Mark all the rules as unapplied before attempting to apply them.
for (pRule = pRules; pRule- & gt; Action != lEND; pRule++)
pRule- & gt; fState = UNAPPLIED;
// Loop through the rule list for as long as we are able to apply at least
// one rule (if we make a pass through the entire list, and we are unable
// to apply any rule, we are finished).
do {
fAppliedAtLeastOneRule = FALSE;
for (pRule = pRules; pRule- & gt; Action != lEND; pRule++) {
if (pRule- & gt; fState != APPLIED) {
if (Layout_ApplyRule(hwndParent, pRules, pChildList, pRule))
fAppliedAtLeastOneRule = TRUE;
}
}
} while (fAppliedAtLeastOneRule);
// Verify that all rules have been successfully applied.
for (pRule = pRules; pRule- & gt; Action != lEND; pRule++) {
ASSERT(pRule- & gt; fState == APPLIED);
if (pRule- & gt; fState != APPLIED)
fOK = FALSE;
}
return(fOK);
}
BOOL WINAPI Layout_ComputeLayout (HWND hwndParent, RULE* pRules) {
HDWP hdwp;
BOOL fOK = TRUE;
CHILD* pChild, *pChildList;
int nChildren;
// Check assumptions.
ASSERT(IsWindow(hwndParent));
ASSERT(pRules);
// Don't do anything to a minimized window.
if (IsIconic(hwndParent))
return(TRUE);
// Enumerate all child windows of the dialog, allocating a CHILD structure
// for each child, with all six metric flags set to KNOWN. To simplify
// coding, we also add a special CHILD structure for the parent window with
// the id lPARENT (defined in layout.h). If there are no children, or
// memory cannot be allocated for the child list, we do nothing.
pChildList = Layout_CreateChildList(hwndParent, & nChildren);
if (pChildList == NULL)
return(FALSE);
if (nChildren == 0)
return(TRUE);
// Apply the rules from the rule list to solve for the locations of all the
// child controls.
if (!Layout_ApplyRules(hwndParent, pRules, pChildList)) {
ASSERT(!__TEXT( " Unable to apply rules " ));
return(FALSE);
}
// Simultaneously relocate all the children using DeferWindowPos.
hdwp = BeginDeferWindowPos(0);
ASSERT(hdwp);
// Move each child in the CHILD list. We enumerate the child list starting
// at pChildList + 1, because the first CHILD is lPARENT.
for (pChild = pChildList + 1; pChild- & gt; idc != IDC_LASTCHILD; pChild++) {
// Check child for any still-unsolved metrics. You may want to remove or
// #ifdef out this check once your rules are known to be working.
if (!Layout_CheckChild(pChild))
fOK = FALSE;
// Add child to DeferWindowPos list if it is not fixed.
if (!pChild- & gt; fFixed) {
HWND hwndChild = GetDlgItem(hwndParent, pChild- & gt; idc);
// ASSERT(pChild- & gt; anMetric[lpWIDTH] & gt; = 0);
// ASSERT(pChild- & gt; anMetric[lpHEIGHT] & gt; = 0);
hdwp = DeferWindowPos(hdwp, hwndChild, NULL,
pChild- & gt; anMetric[lpLEFT], pChild- & gt; anMetric[lpTOP],
pChild- & gt; anMetric[lpWIDTH], pChild- & gt; anMetric[lpHEIGHT],
SWP_NOZORDER);
ASSERT(hdwp);
// Invalidation is necessary here because some controls (edit
// controls in particular) don't repaint correctly under Windows NT
// when they are moved with DeferWindowPos.
InvalidateRect(hwndChild, NULL, TRUE);
}
}
// It is this function call which actually moves all the windows.
EndDeferWindowPos(hdwp);
// Free the allocated list of CHILD structures
free(pChildList);
return(fOK);
}
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__FAD27263_5E57_4863_9DAB_A8D25896C813__INCLUDED_)
#define AFX_STDAFX_H__FAD27263_5E57_4863_9DAB_A8D25896C813__INCLUDED_
#if _MSC_VER & gt; 1000
#pragma once
#endif // _MSC_VER & gt; 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include & lt; afxwin.h & gt; // MFC core and standard components
#include & lt; afxext.h & gt; // MFC extensions
#include & lt; afxcview.h & gt;
#include & lt; afxdisp.h & gt; // MFC Automation classes
#include & lt; afxdtctl.h & gt; // MFC support for Internet Explorer 4 Common Controls
#include & lt; afxtempl.h & gt;
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include & lt; afxcmn.h & gt; // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include " Global.h "
// Format of pSection
// " Key1 = data1\0Key2 = data2\0....Keyn = datan\0\0 "
int EnumKeys(LPCTSTR pSection,CStringArray* pKeys);
long GetDigit(LPCTSTR lpszText);
void GetModuleFilePath( HMODULE hModule, LPTSTR lpszAppPath );
BOOL CreateDeepDirectory(LPCTSTR lpszDir);
BOOL GetFilePathInfo(LPCTSTR lpszFile, CStringArray & agInfo);
int SplitStr(LPCTSTR lpszStr,CStringArray & agStrs,TCHAR chSeparate = _T(','));
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__FAD27263_5E57_4863_9DAB_A8D25896C813__INCLUDED_)
#if !defined(AFX_EDITEX_H__491E6B45_E6B4_42AC_BFC0_6579B8EBF1F3__INCLUDED_)
#define AFX_EDITEX_H__491E6B45_E6B4_42AC_BFC0_6579B8EBF1F3__INCLUDED_
#if _MSC_VER & gt; 1000
#pragma once
#endif // _MSC_VER & gt; 1000
// EditEx.h : header file
//
enum {
EX_FMT_NORMAL,
EX_FMT_DEC,
EX_FMT_HEX,
EX_FMT_MAX
};
/////////////////////////////////////////////////////////////////////////////
// CEditEx window
class CEditEx : public CEdit
{
// Construction
public:
CEditEx();
void SetFmtMode(UINT nMode);
long GetDigit();
// Attributes
protected:
// When you want to change the
// edit content,m_strOldText contains
// the current content of the edit
CString m_strOldText;
// If your input is invalid,the content will
// be restore.m_bReturn is used to avoid enter
// the update function again
BOOL m_bReturn;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEditEx)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CEditEx();
// Generated message map functions
protected:
//{{AFX_MSG(CEditEx)
//afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnUpdate();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
UINT m_nFmtMode;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EDITEX_H__491E6B45_E6B4_42AC_BFC0_6579B8EBF1F3__INCLUDED_)
#if !defined(AFX_DLGPACKETSETTING_H__C0B7BCE4_4BCD_4F12_9452_20F13E53194B__INCLUDED_)
#define AFX_DLGPACKETSETTING_H__C0B7BCE4_4BCD_4F12_9452_20F13E53194B__INCLUDED_
#if _MSC_VER & gt; 1000
#pragma once
#endif // _MSC_VER & gt; 1000
// DlgPacketSetting.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CDlgPacketSetting dialog
class CDlgPacketSetting : public CDialog
{
// Construction
public:
CDlgPacketSetting(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CDlgPacketSetting)
enum { IDD = IDD_DLG_PAKET_SETTING };
CEdit m_edtPrdAlias;
CEdit m_edtVersion;
CEdit m_edtPath;
CString m_strPath;
CString m_strVersion;
CString m_strPrdName;
CString m_strPrdAlias;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgPacketSetting)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CDlgPacketSetting)
virtual void OnOK();
afx_msg void OnBtnBrowse();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DLGPACKETSETTING_H__C0B7BCE4_4BCD_4F12_9452_20F13E53194B__INCLUDED_)
// FileDlg.h: interface for the CFileDlg class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_FILEDLG_H__32FC0DB1_80B1_484A_B696_F14CEA1C38D8__INCLUDED_)
#define AFX_FILEDLG_H__32FC0DB1_80B1_484A_B696_F14CEA1C38D8__INCLUDED_
#if _MSC_VER & gt; 1000
#pragma once
#endif // _MSC_VER & gt; 1000
// µ¯³ö¶Ô»°¿ò£¬ÊµÏÖÎļþºÍĿ¼ѡÔñ¹¦ÄÜ£¬¿É²Î¿¼MFCµÄCFileDialogµÄʵÏֺͰïÖú
class CFileDlg
{
public:
void SetFileFilter( LPCTSTR pszFilter ) { m_strFilter = pszFilter; }
void SetFileExt( LPCTSTR pszExt ) { m_strExt = pszExt; }
void SetHwnOwner(HWND hwnd) {m_hwndOwner = hwnd;}
// »ñÈ¡ÎļþµÄ·¾¶Ãû£¬Èç¹ûÎļþ²»´æÔÚ£¬·µ»ØΪ¿Õ( " " )
CString GetPathName(void);
// »ñȡĿ¼£¬Ä¿Â¼²»´æÔÚ·µ»ØֵΪ¿Õ( " " )£¬Ä¿Â¼ÃûµÄ×îºó²»º¬\ "
CString GetSelectDir();
public:
CFileDlg(BOOL bOpen = TRUE);
~CFileDlg();
private:
static int CALLBACK BrowseProc( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData );
CString m_strFilter;
CString m_strExt;
HWND m_hwndOwner;
BOOL m_bOpen;
static _TCHAR SZ_SEL_DIR[ _MAX_PATH ];
};
#endif // !defined(AFX_FILEDLG_H__32FC0DB1_80B1_484A_B696_F14CEA1C38D8__INCLUDED_)