Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
1654 lines
61 KiB
C++
1654 lines
61 KiB
C++
// DlgObjectProperties.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "Balancer.h"
|
|
#include <stdarg.h>
|
|
#include <stuff\stuff.hpp>
|
|
#include "DlgObjectProperties.h"
|
|
using namespace Stuff;
|
|
|
|
const int c_Max_Objects_Supported = 100;
|
|
extern CBalancerApp theApp;
|
|
|
|
//
|
|
// User passes in an array of data to the dialog at startup.
|
|
// this array type is...CDOPPROPERTIES_TO_EDIT_ARRAY
|
|
//
|
|
|
|
|
|
|
|
LPCSTR MyLoadStringTempBuffer(UINT uiID);
|
|
//
|
|
// This function needs to be moved somewhere more generic
|
|
//
|
|
//
|
|
LPCSTR MyLoadStringTempBuffer(UINT uiID)
|
|
{
|
|
static TCHAR strings[10][1024];
|
|
static nNext = 0;
|
|
nNext = (nNext + 1) % 10;
|
|
::LoadString(NULL, uiID, strings[nNext], 1023);
|
|
return strings[nNext];
|
|
|
|
}
|
|
|
|
|
|
|
|
// puts a backslash as the last char unless it's an empty string, ends in a slash already, or ends with a ':'
|
|
void EndDirectoryWithBackSlash(CString & strDir)
|
|
{
|
|
int nLen = strDir.GetLength();
|
|
if (!nLen)
|
|
return;
|
|
if (strDir.GetAt(nLen-1) == '\\' || strDir.GetAt(nLen -1) == ':')
|
|
return;
|
|
strDir += '\\';
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgObjectProperties dialog
|
|
|
|
|
|
//
|
|
// Rather than have the calling function have to fill in the structure manually they can call this
|
|
// function with all the propeties they want to edit. Then they just pass this in to the appropriate
|
|
// function to specify what properties to get. They will have to clear up the memory with free though
|
|
//
|
|
CDOPPROPERTIES_TO_EDIT_ARRAY * CDlgObjectProperties::CreatePropertiesToEditArray(int nCount, ...)
|
|
{
|
|
|
|
va_list marker;
|
|
CDOPPROPERTIES_TO_EDIT_ARRAY * pRet = Allocate_CDOPPROPERTIES_TO_EDIT_ARRAY(nCount);
|
|
|
|
|
|
va_start( marker, nCount ); /* Initialize variable arguments. */
|
|
pRet->nCount = nCount;
|
|
for (int i = 0 ; i < nCount; i++)
|
|
{
|
|
pRet->ppProperties_To_Edit_Entry[i]->ePropertyType = va_arg(marker, CDOPVARTYPE);
|
|
strcpy(pRet->ppProperties_To_Edit_Entry[i]->szPropertyTag, va_arg(marker, char *));
|
|
strcpy(pRet->ppProperties_To_Edit_Entry[i]->szPropertyTagForDisplay, va_arg(marker, char *));
|
|
pRet->ppProperties_To_Edit_Entry[i]->uiReserved1_CTRLID = 0;
|
|
}
|
|
va_end( marker ); /* Reset variable arguments. */
|
|
return pRet;
|
|
}
|
|
//
|
|
// Since I am using a pointer to represent an array the structure has to be allocated with enough size to
|
|
// store the array. In addition the internal pointer variable must be directed to within
|
|
// the allocation itself. This way I can use array notation To then on.
|
|
//
|
|
CDOPPROPERTIES_TO_EDIT_ARRAY * CDlgObjectProperties::Allocate_CDOPPROPERTIES_TO_EDIT_ARRAY(int nPropertyCount, CDOPPROPERTIES_TO_EDIT_ARRAY * * ppCDOPPROPERTIES_TO_EDIT_ARRAY)
|
|
{
|
|
CDOPPROPERTIES_TO_EDIT_ARRAY * pNew = (CDOPPROPERTIES_TO_EDIT_ARRAY *)
|
|
malloc(sizeof(CDOPPROPERTIES_TO_EDIT_ARRAY) + (nPropertyCount) * sizeof(CDOPPROPERTIES_TO_EDIT_ENTRY *) +
|
|
(nPropertyCount) * sizeof(CDOPPROPERTIES_TO_EDIT_ENTRY)); // we could - 1 from the count since one is allocated as part of the structure, but
|
|
// I'm electing to have the 4 byte buffer instead of worrying about nPropertyCount == 0
|
|
|
|
for (int i = 0; i < nPropertyCount; i++)
|
|
{
|
|
pNew->ppProperties_To_Edit_Entry[i] = (CDOPPROPERTIES_TO_EDIT_ENTRY *)(void *)(((DWORD)&(pNew->ppProperties_To_Edit_Entry)) +
|
|
sizeof(CDOPPROPERTIES_TO_EDIT_ENTRY *) * (nPropertyCount) + i * sizeof(CDOPPROPERTIES_TO_EDIT_ENTRY));
|
|
}
|
|
if (ppCDOPPROPERTIES_TO_EDIT_ARRAY)
|
|
*ppCDOPPROPERTIES_TO_EDIT_ARRAY = pNew;
|
|
return pNew;
|
|
}
|
|
|
|
//
|
|
// Since I am using a pointer to represent an array the structure has to be allocated with enough size to
|
|
// store the array. In addition the internal pointer variable must be directed to within
|
|
// the allocation itself. This way I can use array notation To then on.
|
|
//
|
|
CDOPPROPERTIES_OBJECT_PROPERTIES * CDlgObjectProperties::Allocate_CDOPPROPERTIES_OBJECT_PROPERTIES(int nPropertyCount, CDOPPROPERTIES_OBJECT_PROPERTIES * * ppCDOPPROPERTIES_OBJECT_PROPERTIES)
|
|
{
|
|
CDOPPROPERTIES_OBJECT_PROPERTIES * pNew = (CDOPPROPERTIES_OBJECT_PROPERTIES *)
|
|
malloc (sizeof(CDOPPROPERTIES_OBJECT_PROPERTIES) + nPropertyCount * sizeof(CDOPPROPERTYVALUE *) +
|
|
nPropertyCount * sizeof(CDOPPROPERTYVALUE));
|
|
for (int i = 0 ; i < nPropertyCount; i++)
|
|
{
|
|
pNew->ppObjectProperties[i] = (CDOPPROPERTYVALUE * )(void *)(((DWORD)&(pNew->ppObjectProperties)) +
|
|
sizeof(CDOPPROPERTYVALUE *) * nPropertyCount + sizeof(CDOPPROPERTYVALUE) * i);
|
|
}
|
|
if (ppCDOPPROPERTIES_OBJECT_PROPERTIES)
|
|
*ppCDOPPROPERTIES_OBJECT_PROPERTIES = pNew;
|
|
return pNew;
|
|
}
|
|
|
|
//
|
|
// Since I am using a pointer to represent an array the structure has to be allocated with enough size to
|
|
// store the array. In addition the internal pointer variable must be directed to within
|
|
// the allocation itself. This way I can use array notation To then on.
|
|
//
|
|
CDOPPROPERTIES_OBJECT_LIST * CDlgObjectProperties::Allocate_CDOPPROPERTIES_OBJECT_LIST(int nObjectCount, int nPropertyCount, CDOPPROPERTIES_OBJECT_LIST ** ppCDOPPROPERTIES_OBJECT_LIST )
|
|
{
|
|
|
|
// This one is the most complex since it has to allocate enough room for all the objects, to have all the properties and have
|
|
// all the data for those properties
|
|
|
|
CDOPPROPERTIES_OBJECT_LIST * pNew = (CDOPPROPERTIES_OBJECT_LIST *)
|
|
malloc(sizeof(CDOPPROPERTIES_OBJECT_LIST) + nObjectCount * sizeof(CDOPPROPERTIES_OBJECT_PROPERTIES *)
|
|
+(nObjectCount * (sizeof(CDOPPROPERTIES_OBJECT_PROPERTIES) + nPropertyCount * sizeof(CDOPPROPERTYVALUE *)))
|
|
+(nObjectCount * (nPropertyCount * sizeof(CDOPPROPERTYVALUE)))
|
|
);
|
|
for (int i = 0; i < nObjectCount; i++)
|
|
{
|
|
// For the object array set up the pointers to each properties array
|
|
pNew->ppPropertiesArray[i] = (CDOPPROPERTIES_OBJECT_PROPERTIES * )(void *)(((DWORD)&(pNew->ppPropertiesArray))
|
|
+sizeof(CDOPPROPERTIES_OBJECT_PROPERTIES * ) * nObjectCount
|
|
+ i * (sizeof(CDOPPROPERTIES_OBJECT_PROPERTIES) + nPropertyCount * (sizeof(CDOPPROPERTYVALUE *))
|
|
+nPropertyCount * sizeof(CDOPPROPERTYVALUE)));
|
|
// For each object set up the pointer list for the properties array
|
|
for (int j = 0; j < nPropertyCount; j++)
|
|
{
|
|
pNew->ppPropertiesArray[i]->ppObjectProperties[j] = (CDOPPROPERTYVALUE *)(void *)(((DWORD)&(pNew->ppPropertiesArray[i]->ppObjectProperties))
|
|
+ nPropertyCount * sizeof(CDOPPROPERTYVALUE *)
|
|
+ j * sizeof(CDOPPROPERTYVALUE));
|
|
}
|
|
}
|
|
|
|
if (ppCDOPPROPERTIES_OBJECT_LIST)
|
|
*ppCDOPPROPERTIES_OBJECT_LIST = pNew;
|
|
return pNew;
|
|
|
|
}
|
|
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::Copy_CDOPPROPERTIES_TO_EDIT_ARRAY(CDOPPROPERTIES_TO_EDIT_ARRAY * pCDOPPROPERTIES_TO_EDIT_ARRAY_DEST, CDOPPROPERTIES_TO_EDIT_ARRAY * pCDOPPROPERTIES_TO_EDIT_ARRAY_SRC)
|
|
{
|
|
pCDOPPROPERTIES_TO_EDIT_ARRAY_DEST->nCount = pCDOPPROPERTIES_TO_EDIT_ARRAY_SRC->nCount;
|
|
for (int i = 0; i < pCDOPPROPERTIES_TO_EDIT_ARRAY_SRC->nCount; i++)
|
|
{
|
|
memcpy(pCDOPPROPERTIES_TO_EDIT_ARRAY_DEST->ppProperties_To_Edit_Entry[i],
|
|
pCDOPPROPERTIES_TO_EDIT_ARRAY_SRC->ppProperties_To_Edit_Entry[i],
|
|
sizeof(CDOPPROPERTIES_TO_EDIT_ENTRY));
|
|
|
|
}
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::Copy_CDOPPROPERTIES_OBJECT_PROPERTIES(CDOPPROPERTIES_OBJECT_PROPERTIES * pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST, CDOPPROPERTIES_OBJECT_PROPERTIES * pCDOPPROPERTIES_OBJECT_PROPERTIES_SRC)
|
|
{
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST->fDirty = pCDOPPROPERTIES_OBJECT_PROPERTIES_SRC->fDirty;
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST->fReadOnly = pCDOPPROPERTIES_OBJECT_PROPERTIES_SRC->fReadOnly;
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST->nProperties = pCDOPPROPERTIES_OBJECT_PROPERTIES_SRC->nProperties;
|
|
memcpy(pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST->szObjectName,
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES_SRC->szObjectName,
|
|
sizeof(pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST->szObjectName));
|
|
|
|
for (int i = 0 ; i < pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST->nProperties; i++)
|
|
{
|
|
memcpy(pCDOPPROPERTIES_OBJECT_PROPERTIES_DEST->ppObjectProperties[i],
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES_SRC->ppObjectProperties[i],
|
|
sizeof(CDOPPROPERTYVALUE));
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::Copy_CDOPPROPERTIES_OBJECT_LIST(CDOPPROPERTIES_OBJECT_LIST * pCDOPPROPERTIES_OBJECT_LIST_DEST, CDOPPROPERTIES_OBJECT_LIST * pCDOPPROPERTIES_OBJECT_LIST_SRC)
|
|
{
|
|
pCDOPPROPERTIES_OBJECT_LIST_DEST->nObjectCount = pCDOPPROPERTIES_OBJECT_LIST_SRC->nObjectCount;
|
|
for (int i = 0; i < pCDOPPROPERTIES_OBJECT_LIST_DEST->nObjectCount; i++)
|
|
{
|
|
Copy_CDOPPROPERTIES_OBJECT_PROPERTIES(pCDOPPROPERTIES_OBJECT_LIST_DEST->ppPropertiesArray[i],
|
|
pCDOPPROPERTIES_OBJECT_LIST_SRC->ppPropertiesArray[i]);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::IsEqual_CDOPPROPERTIES_TO_EDIT_ARRAY(CDOPPROPERTIES_TO_EDIT_ARRAY * pCDOPPROPERTIES_TO_EDIT_ARRAY1, CDOPPROPERTIES_TO_EDIT_ARRAY * pCDOPPROPERTIES_TO_EDIT_ARRAY2)
|
|
{
|
|
if (pCDOPPROPERTIES_TO_EDIT_ARRAY1->nCount != pCDOPPROPERTIES_TO_EDIT_ARRAY2->nCount)
|
|
return FALSE;
|
|
|
|
for (int i = 0; i < pCDOPPROPERTIES_TO_EDIT_ARRAY1->nCount; i++)
|
|
{
|
|
if (memcmp(pCDOPPROPERTIES_TO_EDIT_ARRAY1->ppProperties_To_Edit_Entry[i],
|
|
pCDOPPROPERTIES_TO_EDIT_ARRAY2->ppProperties_To_Edit_Entry[i],
|
|
sizeof(CDOPPROPERTIES_TO_EDIT_ENTRY)))
|
|
return FALSE;
|
|
|
|
}
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::IsEqual_CDOPPROPERTIES_OBJECT_PROPERTIES(CDOPPROPERTIES_OBJECT_PROPERTIES * pCDOPPROPERTIES_OBJECT_PROPERTIES1, CDOPPROPERTIES_OBJECT_PROPERTIES * pCDOPPROPERTIES_OBJECT_PROPERTIES2)
|
|
{
|
|
if (pCDOPPROPERTIES_OBJECT_PROPERTIES1->nProperties != pCDOPPROPERTIES_OBJECT_PROPERTIES2->nProperties ||
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES1->fDirty != pCDOPPROPERTIES_OBJECT_PROPERTIES2->fDirty ||
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES1->fReadOnly != pCDOPPROPERTIES_OBJECT_PROPERTIES2->fReadOnly ||
|
|
memcmp(pCDOPPROPERTIES_OBJECT_PROPERTIES1->szObjectName,
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES2->szObjectName,
|
|
sizeof(pCDOPPROPERTIES_OBJECT_PROPERTIES2->szObjectName)))
|
|
return FALSE;
|
|
|
|
|
|
for (int i = 0 ; i < pCDOPPROPERTIES_OBJECT_PROPERTIES2->nProperties; i++)
|
|
{
|
|
if (memcmp(pCDOPPROPERTIES_OBJECT_PROPERTIES1->ppObjectProperties[i],
|
|
pCDOPPROPERTIES_OBJECT_PROPERTIES2->ppObjectProperties[i],
|
|
sizeof(CDOPPROPERTYVALUE)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::IsEqual_CDOPPROPERTIES_OBJECT_LIST(CDOPPROPERTIES_OBJECT_LIST * pCDOPPROPERTIES_OBJECT_LIST1, CDOPPROPERTIES_OBJECT_LIST * pCDOPPROPERTIES_OBJECT_LIST2)
|
|
{
|
|
if (pCDOPPROPERTIES_OBJECT_LIST1->nObjectCount != pCDOPPROPERTIES_OBJECT_LIST2->nObjectCount)
|
|
return FALSE;
|
|
|
|
for (int i = 0 ; i < pCDOPPROPERTIES_OBJECT_LIST2->nObjectCount; i++)
|
|
{
|
|
if (!IsEqual_CDOPPROPERTIES_OBJECT_PROPERTIES(pCDOPPROPERTIES_OBJECT_LIST1->ppPropertiesArray[i],
|
|
pCDOPPROPERTIES_OBJECT_LIST2->ppPropertiesArray[i]))
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
CDlgObjectProperties::~CDlgObjectProperties()
|
|
{
|
|
if (m_pObjectList)
|
|
{
|
|
free(m_pObjectList);
|
|
}
|
|
}
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
CDlgObjectProperties::CDlgObjectProperties(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CDlgObjectProperties::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CDlgObjectProperties)
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_pObjectList = NULL;
|
|
ClearObjectDataSet();
|
|
m_nCurSel = LB_ERR; // nothing selected, important to start here since we have no data loaded in the dialog yet
|
|
|
|
// This will be passed in later with a list of properties to edit
|
|
m_paPropertiesToEdit = NULL;
|
|
|
|
m_fnFilterFunction = NULL;
|
|
m_fShowFullObjectName = FALSE;
|
|
m_fShowFullPropertyName = FALSE;
|
|
m_eSearchType = eSingleSubdirectory;
|
|
m_popCurObjectPropertiesArray = NULL;
|
|
m_fDirty = FALSE;
|
|
|
|
m_nLastControlID = IDC_DOP_PROPNAME;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
int CDlgObjectProperties::DoModal()
|
|
{
|
|
//
|
|
// Check to make sure we have all the data set that we need
|
|
//
|
|
if (
|
|
m_strFileNameToSearchSubdirectoriesFor.IsEmpty() ||
|
|
m_strObjectFilesRootDirectory.IsEmpty() ||
|
|
m_paPropertiesToEdit == NULL ||
|
|
!m_paPropertiesToEdit->nCount // have to have at least one property
|
|
)
|
|
{
|
|
return IDABORT;
|
|
}
|
|
return CDialog::DoModal();
|
|
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
void CDlgObjectProperties::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CDlgObjectProperties)
|
|
DDX_Control(pDX, IDC_OBJECTLIST, m_lbObjectList);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgObjectProperties, CDialog)
|
|
//{{AFX_MSG_MAP(CDlgObjectProperties)
|
|
ON_LBN_SELCHANGE(IDC_OBJECTLIST, OnSelchangeObjectlist)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgObjectProperties message handlers
|
|
|
|
BOOL CDlgObjectProperties::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
m_nCurSel = LB_ERR;
|
|
m_fDirty = FALSE;
|
|
ClearObjectDataSet();
|
|
|
|
//
|
|
// For now we just have a fixed size data set maximum. Otherwise we would have to
|
|
// iterate all the files once or create a link list of objects instead of an array.
|
|
// Any of these can be done, the array was simply created to save time getting this
|
|
// code up to speed.
|
|
//
|
|
if (m_pObjectList)
|
|
free(m_pObjectList);
|
|
m_pObjectList = Allocate_CDOPPROPERTIES_OBJECT_LIST(c_Max_Objects_Supported, m_paPropertiesToEdit->nCount);
|
|
m_pObjectList->nObjectCount = 0; // this many being used currently
|
|
|
|
//
|
|
// Search for the weapons subsytem files
|
|
//
|
|
LoadObjectData(m_strObjectFilesRootDirectory, m_eSearchType);
|
|
|
|
|
|
//
|
|
// Create all the sub-controls that represent the data that we are going to be editting in the
|
|
// dialog
|
|
// Note: We are not allowed to get here if we don't have a properties list since DoModal should kick
|
|
// us out, and this dialog is not meant to be modeless.
|
|
CreateSubControlsForProperties();
|
|
|
|
|
|
UpdateData(FALSE);
|
|
m_lbObjectList.SetCurSel(0); // get the ball rolling by showing the first weapon in the list
|
|
OnSelchangeObjectlist();
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
void CDlgObjectProperties::CreateSubControlsForProperties()
|
|
{
|
|
//
|
|
// Go through the list of properties we are editting and place all the controls.
|
|
// Use the reserved value in the property array passed in to store the starting ID
|
|
// of each properties control set. Offsets To there are based on the type of variable
|
|
// that is being used.
|
|
m_nLastControlID = IDC_DOP_PROPNAME;
|
|
|
|
//
|
|
// The following hidden objects have been added to the resource dialog in order to
|
|
// make formatting fully adjustable without having to modify constants in the code
|
|
// We get the base size, and position for all controls To these
|
|
// IDC_DOP_PROPNAME, IDC_DOP_PROPPRESENT, IDC_DOP_PROPEDIT1, IDC_DOP_PROPEDIT2, IDC_DOP_PROPEDIT3
|
|
//
|
|
// Use the dummy hidden controls to place our new ones, unhide the dummy controls
|
|
// for the first property, and then build the rest
|
|
CWnd * pControlPropName = GetDlgItem(IDC_DOP_PROPNAME);
|
|
CWnd * pControlPropPresent = GetDlgItem(IDC_DOP_PROPPRESENT);
|
|
CWnd * pControlPropEdit1 = GetDlgItem(IDC_DOP_PROPEDIT1);
|
|
CWnd * pControlPropEdit2 = GetDlgItem(IDC_DOP_PROPEDIT2);
|
|
CWnd * pControlPropEdit3 = GetDlgItem(IDC_DOP_PROPEDIT3);
|
|
if (!pControlPropName || !pControlPropPresent || !pControlPropEdit1 || !pControlPropEdit2 || !pControlPropEdit3)
|
|
return; // badness has occurred, but no way out of it at this point
|
|
|
|
CFont * pFontControlPropName = pControlPropName->GetFont();
|
|
CFont * pFontControlPropPresent = pControlPropPresent->GetFont();
|
|
CFont * pFontControlPropEdit1 = pControlPropEdit1->GetFont();
|
|
CFont * pFontControlPropEdit2 = pControlPropEdit2->GetFont();
|
|
CFont * pFontControlPropEdit3 = pControlPropEdit3->GetFont();
|
|
|
|
|
|
|
|
CRect crRectDlg;
|
|
CRect crRectPropName;
|
|
CRect crRectPropPresent;
|
|
CRect crRectPropEdit1;
|
|
CRect crRectPropEdit2;
|
|
CRect crRectPropEdit3;
|
|
|
|
GetWindowRect(crRectDlg);
|
|
pControlPropName->GetWindowRect(crRectPropName);
|
|
pControlPropPresent->GetWindowRect(crRectPropPresent);
|
|
pControlPropEdit1->GetWindowRect(crRectPropEdit1);
|
|
pControlPropEdit2->GetWindowRect(crRectPropEdit2);
|
|
pControlPropEdit3->GetWindowRect(crRectPropEdit3);
|
|
|
|
//
|
|
// Offset the rects relative to the dialog
|
|
//
|
|
::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT) (LPRECT)crRectPropName, 2);
|
|
::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT) (LPRECT)crRectPropPresent, 2);
|
|
::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT) (LPRECT)crRectPropEdit1, 2);
|
|
::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT) (LPRECT)crRectPropEdit2, 2);
|
|
::MapWindowPoints(NULL, GetSafeHwnd(), (LPPOINT) (LPRECT)crRectPropEdit3, 2);
|
|
|
|
// crRectPropName.OffsetRect(-crRectDlg.left, -crRectDlg.top);
|
|
// crRectPropPresent.OffsetRect(-crRectDlg.left, -crRectDlg.top);
|
|
// crRectPropEdit1.OffsetRect(-crRectDlg.left, -crRectDlg.top);
|
|
// crRectPropEdit2.OffsetRect(-crRectDlg.left, -crRectDlg.top);
|
|
// crRectPropEdit3.OffsetRect(-crRectDlg.left, -crRectDlg.top);
|
|
|
|
// for the first property we just unhide the appropriate boxes and set the property name
|
|
int nCurrentProperty = 0;
|
|
// if we didn't have at least one item in the property list DoModal() should have kicked us out
|
|
// so it should be safe to reference this without checking here.
|
|
pControlPropName->ShowWindow(SW_SHOW);
|
|
|
|
const char * szStaticText = NULL;
|
|
if (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[0]->szPropertyTagForDisplay[0])
|
|
{
|
|
szStaticText = m_paPropertiesToEdit->ppProperties_To_Edit_Entry[0]->szPropertyTagForDisplay;
|
|
}
|
|
else
|
|
{
|
|
szStaticText =
|
|
m_fShowFullPropertyName ?
|
|
m_paPropertiesToEdit->ppProperties_To_Edit_Entry[0]->szPropertyTag :
|
|
GetEntryNameToPropertyName(m_paPropertiesToEdit->ppProperties_To_Edit_Entry[0]->szPropertyTag );
|
|
}
|
|
|
|
|
|
pControlPropName->SetWindowText(szStaticText);
|
|
pControlPropPresent->ShowWindow(SW_SHOW);
|
|
pControlPropEdit1->ShowWindow(SW_SHOW);
|
|
|
|
// Next root ID is 1 after this set
|
|
int nCurrID = IDC_DOP_PROPNAME + 3;
|
|
|
|
// now see if we need to add the others
|
|
if (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[0]->ePropertyType == eVector3D)
|
|
{
|
|
pControlPropEdit2->ShowWindow(SW_SHOW);
|
|
pControlPropEdit3->ShowWindow(SW_SHOW);
|
|
}
|
|
else
|
|
{
|
|
pControlPropEdit2->ShowWindow(SW_HIDE);
|
|
pControlPropEdit3->ShowWindow(SW_HIDE);
|
|
}
|
|
|
|
nCurrID += 2; // this has to be incremented no matter what since the controls are actually there.
|
|
|
|
m_paPropertiesToEdit->ppProperties_To_Edit_Entry[0]->uiReserved1_CTRLID = IDC_DOP_PROPNAME;
|
|
|
|
int nDiffY = crRectPropEdit1.Height() + 5; // constant used for vertical padding (use largest control type, edit box)
|
|
HWND hWndTemp = NULL;
|
|
while (++nCurrentProperty < m_paPropertiesToEdit->nCount)
|
|
{
|
|
CWnd wndControlPropName ;
|
|
CWnd wndControlPropPresent ;
|
|
CWnd wndControlPropEdit1 ;
|
|
CWnd wndControlPropEdit2 ;
|
|
CWnd wndControlPropEdit3 ;
|
|
// BOOL fIsNumberOnly = m_paPropertiesToEdit->ppProperties_To_Edit_Entry[nCurrentProperty]->ePropertyType != eLPSTR;
|
|
|
|
// we have to store off the ID for these properties
|
|
m_paPropertiesToEdit->ppProperties_To_Edit_Entry[nCurrentProperty]->uiReserved1_CTRLID = nCurrID;
|
|
|
|
crRectPropName.OffsetRect( 0, nDiffY);
|
|
crRectPropPresent.OffsetRect(0, nDiffY);
|
|
crRectPropEdit1.OffsetRect( 0, nDiffY);
|
|
crRectPropEdit2.OffsetRect( 0, nDiffY);
|
|
crRectPropEdit3.OffsetRect( 0, nDiffY);
|
|
|
|
if (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[nCurrentProperty]->szPropertyTagForDisplay[0])
|
|
{
|
|
szStaticText = m_paPropertiesToEdit->ppProperties_To_Edit_Entry[nCurrentProperty]->szPropertyTagForDisplay;
|
|
}
|
|
else
|
|
{
|
|
szStaticText =
|
|
m_fShowFullPropertyName ?
|
|
m_paPropertiesToEdit->ppProperties_To_Edit_Entry[nCurrentProperty]->szPropertyTag :
|
|
GetEntryNameToPropertyName(m_paPropertiesToEdit->ppProperties_To_Edit_Entry[nCurrentProperty]->szPropertyTag );
|
|
}
|
|
hWndTemp = ::CreateWindow("STATIC",
|
|
szStaticText,
|
|
WS_VISIBLE | SS_LEFT | WS_CHILD,
|
|
crRectPropName.left, crRectPropName.top, crRectPropName.Width(), crRectPropName.Height(),
|
|
GetSafeHwnd(), (HMENU)nCurrID, theApp.m_hInstance, NULL);
|
|
// ::SetWindowLong(hWndTemp, nCurrID, GWL_ID);
|
|
|
|
::SendMessage(hWndTemp, WM_SETFONT, (WPARAM)(HFONT)*pFontControlPropName, (LPARAM)FALSE);
|
|
|
|
|
|
/* wndControlPropName.Create("STATIC",
|
|
szStaticText,
|
|
WS_VISIBLE | SS_LEFT | WS_CHILD,
|
|
crRectPropName,
|
|
this,
|
|
nCurrID,
|
|
NULL);
|
|
wndControlPropName.Detach();
|
|
*/
|
|
nCurrID++;
|
|
|
|
|
|
hWndTemp = ::CreateWindow("BUTTON",
|
|
"",
|
|
WS_VISIBLE | BS_CHECKBOX | WS_CHILD | BS_AUTOCHECKBOX,
|
|
crRectPropPresent.left, crRectPropPresent.top, crRectPropPresent.Width(), crRectPropPresent.Height(),
|
|
GetSafeHwnd(), (HMENU)nCurrID, theApp.m_hInstance, NULL);
|
|
// ::SetWindowLong(hWndTemp, nCurrID, GWL_ID);
|
|
::SendMessage(hWndTemp, WM_SETFONT, (WPARAM)(HFONT)*pFontControlPropPresent, (LPARAM)FALSE);
|
|
|
|
/* wndControlPropPresent.Create("BUTTON",
|
|
_T(""),
|
|
WS_VISIBLE | BS_CHECKBOX | WS_CHILD,
|
|
crRectPropPresent,
|
|
this,
|
|
nCurrID,
|
|
NULL);
|
|
wndControlPropPresent.Detach();
|
|
*/
|
|
nCurrID++;
|
|
hWndTemp = ::CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_NOPARENTNOTIFY, "EDIT",
|
|
"",
|
|
WS_VISIBLE | WS_BORDER | ES_LEFT | WS_CHILD ,
|
|
crRectPropEdit1.left, crRectPropEdit1.top, crRectPropEdit1.Width(), crRectPropEdit1.Height(),
|
|
GetSafeHwnd(), (HMENU)nCurrID, theApp.m_hInstance, NULL);
|
|
// ::SetWindowLong(hWndTemp, nCurrID, GWL_ID);
|
|
::SendMessage(hWndTemp, WM_SETFONT, (WPARAM)(HFONT)*pFontControlPropEdit1, (LPARAM)FALSE);
|
|
/* wndControlPropEdit1.Create("EDIT",
|
|
_T(""),
|
|
WS_VISIBLE | ES_LEFT | WS_CHILD |
|
|
(fIsNumberOnly ? ES_NUMBER : 0), // keep them To entering wrong info
|
|
crRectPropEdit1,
|
|
this,
|
|
nCurrID,
|
|
NULL);
|
|
wndControlPropEdit1.Detach();
|
|
*/
|
|
nCurrID++;
|
|
|
|
if (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[nCurrentProperty]->ePropertyType == eVector3D)
|
|
{
|
|
|
|
hWndTemp = ::CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_NOPARENTNOTIFY, "EDIT",
|
|
"",
|
|
WS_VISIBLE | WS_BORDER | ES_LEFT | WS_CHILD,
|
|
crRectPropEdit2.left, crRectPropEdit2.top, crRectPropEdit2.Width(), crRectPropEdit2.Height(),
|
|
GetSafeHwnd(), (HMENU)nCurrID, theApp.m_hInstance, NULL);
|
|
// ::SetWindowLong(hWndTemp, nCurrID, GWL_ID);
|
|
::SendMessage(hWndTemp, WM_SETFONT, (WPARAM)(HFONT)*pFontControlPropEdit2, (LPARAM)FALSE);
|
|
/* wndControlPropEdit2.Create("EDIT",
|
|
_T(""),
|
|
WS_VISIBLE | ES_LEFT | WS_CHILD |
|
|
ES_NUMBER, // keep them To entering wrong info
|
|
crRectPropEdit2,
|
|
this,
|
|
nCurrID,
|
|
NULL);
|
|
wndControlPropEdit2.Detach();
|
|
*/
|
|
nCurrID++;
|
|
|
|
hWndTemp = ::CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_NOPARENTNOTIFY, "EDIT",
|
|
"",
|
|
WS_VISIBLE | WS_BORDER | ES_LEFT | WS_CHILD,
|
|
crRectPropEdit3.left, crRectPropEdit3.top, crRectPropEdit3.Width(), crRectPropEdit3.Height(),
|
|
GetSafeHwnd(), (HMENU)nCurrID, theApp.m_hInstance, NULL);
|
|
// ::SetWindowLong(hWndTemp, nCurrID, GWL_ID);
|
|
::SendMessage(hWndTemp, WM_SETFONT, (WPARAM)(HFONT)*pFontControlPropEdit3, (LPARAM)FALSE);
|
|
/* wndControlPropEdit3.Create("EDIT",
|
|
_T(""),
|
|
WS_VISIBLE | ES_LEFT | WS_CHILD |
|
|
ES_NUMBER, // keep them To entering wrong info
|
|
crRectPropEdit3,
|
|
this,
|
|
nCurrID,
|
|
NULL);
|
|
wndControlPropEdit3.Detach();
|
|
*/
|
|
nCurrID++;
|
|
|
|
} // if we are entering a eVector3D property here
|
|
} // while we are iterating through the properties
|
|
m_nLastControlID = nCurrID;
|
|
} // end of CreateSubControlsForProperties()
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
void CDlgObjectProperties::OnOK()
|
|
{
|
|
//
|
|
// Validate the data and save any changes made since the last sel change
|
|
//
|
|
MoveCurSelDataToOrFromControls(FALSE);
|
|
//
|
|
// Ask them if they want to commit the changes? Or should pressing OK be enough? Should there be a
|
|
// safety net?
|
|
//
|
|
if (m_fDirty)
|
|
{
|
|
int ret = MessageBox( MyLoadStringTempBuffer(IDS_SAVE_WEAPONS_CHANGES), MyLoadStringTempBuffer(IDS_SAVE_WEAPONS_CHANGES_CAPTION), MB_YESNO);
|
|
if (ret != IDYES)
|
|
{
|
|
return;
|
|
}
|
|
//
|
|
// save the changes, exit if failed without ending the dialog
|
|
//
|
|
if (!SaveObjectData())
|
|
{
|
|
MessageBox(MyLoadStringTempBuffer(IDS_SAVE_WEAPONS_FAILED), MyLoadStringTempBuffer(IDS_ERROR_CAPTION), MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we got here, everything should be saved
|
|
//
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
void CDlgObjectProperties::OnCancel()
|
|
{
|
|
//
|
|
// It's safe to exit, as long as all the notation files are closed out, which should be the case
|
|
//
|
|
CDialog::OnCancel();
|
|
}
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
// Sets the root directory to search under. Only goes one level deep currently
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SetObjectFilesDirectory(LPCSTR lpszDirectoryPath)
|
|
{
|
|
m_strObjectFilesRootDirectory = lpszDirectoryPath;
|
|
EndDirectoryWithBackSlash(m_strObjectFilesRootDirectory );
|
|
return TRUE;
|
|
}
|
|
//****************************************************************************************
|
|
//
|
|
// Sets the root file name type to search for like "*.data"
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SetFileNameToSearchSubdirectoriesFor(LPCSTR lpszFileSearchString)
|
|
{
|
|
m_strFileNameToSearchSubdirectoriesFor = lpszFileSearchString;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
void CDlgObjectProperties::ClearObjectDataSet()
|
|
{
|
|
//
|
|
// If you didn't allocate this structure as a whole you have to walk the tree and kill the internal
|
|
// pointer memory before you do this, but if you used the allocate_... function provided above it was
|
|
// all allocated as one huge chunk instead of in parts.
|
|
//
|
|
if (m_pObjectList)
|
|
{
|
|
free(m_pObjectList);
|
|
m_pObjectList = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
LPCSTR CDlgObjectProperties::GetPageNameToPropertyName(LPCSTR szPropertyName)
|
|
{
|
|
static char s_szPageNameBuffer[128];
|
|
// get everything up to the first \ in the string
|
|
const char * pTempSrc = szPropertyName;
|
|
char * pTempDest = s_szPageNameBuffer;
|
|
|
|
while (*pTempSrc && *pTempSrc != '\\') *(pTempDest++) = *(pTempSrc++);
|
|
*pTempDest = '\0';
|
|
return s_szPageNameBuffer;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
LPCSTR CDlgObjectProperties::GetEntryNameToPropertyName(LPCSTR szPropertyName)
|
|
{
|
|
static char s_szEntryNameBuffer[128];
|
|
// get everything after the last \ in the string
|
|
const char * pTempSrc = szPropertyName;
|
|
const char * pLastBackSlash = szPropertyName;
|
|
while (*pTempSrc)
|
|
{
|
|
if (*pTempSrc == '\\')
|
|
pLastBackSlash = pTempSrc;
|
|
pTempSrc++;
|
|
}
|
|
if (*pLastBackSlash == '\\')
|
|
pLastBackSlash++;
|
|
|
|
strcpy(s_szEntryNameBuffer, pLastBackSlash);
|
|
return s_szEntryNameBuffer;
|
|
}
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
// Save weapons data will save all the information back to the appropriate notation files. It only saves
|
|
// out the weapons that are changed.
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SaveObjectData()
|
|
{
|
|
int nFailures = 0;
|
|
|
|
for (int i = 0; i< m_pObjectList->nObjectCount;i++)
|
|
{
|
|
if (!m_pObjectList->ppPropertiesArray[i]->fDirty) // not an error condition, just a shortcut
|
|
continue; // don't worry about saving this one if it hasn't changed.
|
|
if (!m_pObjectList->ppPropertiesArray[i]->szObjectName[0])
|
|
{
|
|
nFailures++;
|
|
continue;
|
|
}
|
|
if (m_pObjectList->ppPropertiesArray[i]->fReadOnly) // shouldn't have been allowed to change this
|
|
{
|
|
nFailures++;
|
|
continue;
|
|
}
|
|
//
|
|
// Loop through all the properties and save them
|
|
//
|
|
Page * page = NULL;
|
|
char szCurrentPageName[128] = ""; // used to prevent repetitively searching for the same page
|
|
NotationFile outfile((LPCSTR)m_pObjectList->ppPropertiesArray[i]->szObjectName, NotationFile::Raw);
|
|
for (int j=0; j < m_pObjectList->ppPropertiesArray[i]->nProperties; j++)
|
|
{
|
|
const char * szPageName = GetPageNameToPropertyName(m_paPropertiesToEdit->ppProperties_To_Edit_Entry[j]->szPropertyTag);
|
|
if (!page || strcmp(szCurrentPageName, szPageName))
|
|
{
|
|
strcpy(szCurrentPageName, szPageName);
|
|
page = outfile.FindPage(szPageName);
|
|
if (!page) // if for some reason we can't find the page, jump out
|
|
continue;
|
|
}
|
|
const char * szEntryName = GetEntryNameToPropertyName(m_paPropertiesToEdit->ppProperties_To_Edit_Entry[j]->szPropertyTag);
|
|
//
|
|
// For each item in the data list, if it shouldn't be there, delete it. If it supposed to be there set it
|
|
// Assumption is made that there are not two of any particular value key
|
|
//
|
|
if (!m_pObjectList->ppPropertiesArray[i]->ppObjectProperties[j]->fPresent)
|
|
{
|
|
page->DeleteNote(szEntryName);
|
|
}
|
|
else
|
|
{
|
|
page->DeleteNote(szEntryName); // temporary kludge to force the dirty bit. This can be removed
|
|
// after we decide if it is safe to make "SetEntry" set the dirty bit itself
|
|
switch (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[j]->ePropertyType)
|
|
{
|
|
case efloat:
|
|
page->SetEntry(szEntryName, m_pObjectList->ppPropertiesArray[i]->ppObjectProperties[j]->uPropValue.fltValue);
|
|
break;
|
|
case eint:
|
|
page->SetEntry(szEntryName, m_pObjectList->ppPropertiesArray[i]->ppObjectProperties[j]->uPropValue.nValue);
|
|
break;
|
|
case eLPSTR:
|
|
page->SetEntry(szEntryName, m_pObjectList->ppPropertiesArray[i]->ppObjectProperties[j]->uPropValue.szValue);
|
|
break;
|
|
case eBOOL:
|
|
page->SetEntry(szEntryName, m_pObjectList->ppPropertiesArray[i]->ppObjectProperties[j]->uPropValue.fValue);
|
|
break;
|
|
case eVector3D:
|
|
{
|
|
Vector3D v3D(m_pObjectList->ppPropertiesArray[i]->ppObjectProperties[j]->uPropValue.v3dValues.x,
|
|
m_pObjectList->ppPropertiesArray[i]->ppObjectProperties[j]->uPropValue.v3dValues.y,
|
|
m_pObjectList->ppPropertiesArray[i]->ppObjectProperties[j]->uPropValue.v3dValues.z);
|
|
page->SetEntry(szEntryName, (Vector3D)v3D);
|
|
break;
|
|
}
|
|
} // switch for property type
|
|
} // else, we are setting a property instead of removing one (ie.. fPresent true)
|
|
} // for loop iterating properties
|
|
|
|
outfile.Save();
|
|
} // for loop iterating objects
|
|
|
|
return (!nFailures);
|
|
}
|
|
|
|
//****************************************************************************************
|
|
// LoadObjectData()
|
|
//
|
|
// This routine will search the content\weaponsubsystems directory for subdirectories containing .data files
|
|
// It will then open those .data files to read in weapon data. It is a simplistic algorithm that should be replaced
|
|
// by either searching through resources.build or some other weapons reference file if they are made to be fully up
|
|
// to date with their references to the weapons.
|
|
//
|
|
// Recursive function so watch what kind of initializations you do, or how you effect
|
|
// global variables.
|
|
//
|
|
// Directory passed in must end in a backslash
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::LoadObjectData(LPCSTR szDirectoryToSearchFor, DIRECTORYSEARCHTYPE eSearchType)
|
|
{
|
|
CString strRootDirSearchString = szDirectoryToSearchFor;
|
|
strRootDirSearchString += "*.*";
|
|
CString strFullSubdirectoryName ;
|
|
BOOL fRet = TRUE;
|
|
//
|
|
// If we are only supposed to seach in the root directory pass this to the next function that finds
|
|
// the actual files
|
|
//
|
|
if (eSearchType == eRootOnly)
|
|
{
|
|
fRet = LoadDataFilesFromSubdirectory(szDirectoryToSearchFor);
|
|
return fRet; // return so we don't do any more searching
|
|
}
|
|
|
|
//
|
|
// If we are doing all directories then we should search in the root as well, then
|
|
// proceed down to the next level.
|
|
//
|
|
if (eSearchType == eAllSubdirectories)
|
|
{
|
|
fRet = LoadDataFilesFromSubdirectory(szDirectoryToSearchFor);
|
|
}
|
|
//
|
|
// If we got an error, exit now, we don't continue searching the subdirectories
|
|
//
|
|
if (!fRet)
|
|
return fRet;
|
|
|
|
//
|
|
// If we got here we need to search for subdirectories of the current one
|
|
// Then call this function recursively on each of those directories
|
|
//
|
|
|
|
//
|
|
// Now we iterate through the current directory looking for subdirectories.
|
|
//
|
|
//
|
|
WIN32_FIND_DATA wfdFindFileData;
|
|
|
|
HANDLE hFileSearch = FindFirstFile((LPCSTR)strRootDirSearchString , &wfdFindFileData);
|
|
if (hFileSearch == INVALID_HANDLE_VALUE)
|
|
{
|
|
// strOutput.Format("\r\nError : Didn't find any files in the source dir to copy.");
|
|
// OutputString(strOutput);
|
|
return TRUE;
|
|
}
|
|
if (wfdFindFileData.cFileName[0] == '\0')
|
|
{
|
|
// strOutput.Format("\r\nError : Didn't find any files in the source dir to copy.");
|
|
// OutputString(strOutput);
|
|
FindClose(hFileSearch);
|
|
return TRUE;
|
|
}
|
|
while (wfdFindFileData.cFileName[0])
|
|
{
|
|
if (!stricmp(wfdFindFileData.cFileName, ".") || !stricmp(wfdFindFileData.cFileName, ".."))
|
|
{
|
|
goto NextFile;
|
|
}
|
|
|
|
if (!(wfdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
|
{
|
|
goto NextFile;
|
|
}
|
|
|
|
strFullSubdirectoryName = szDirectoryToSearchFor;
|
|
strFullSubdirectoryName += wfdFindFileData.cFileName;
|
|
EndDirectoryWithBackSlash(strFullSubdirectoryName);
|
|
if (eSearchType == eAllSubdirectories)
|
|
{
|
|
LoadObjectData(strFullSubdirectoryName, eAllSubdirectories);
|
|
}
|
|
else // since eRootOnly was already weeded out above, this means "eSingleSubdirectory"
|
|
{
|
|
LoadObjectData(strFullSubdirectoryName, eRootOnly);
|
|
}
|
|
|
|
|
|
|
|
NextFile:
|
|
|
|
if (!FindNextFile(hFileSearch, &wfdFindFileData))
|
|
{
|
|
break;
|
|
}
|
|
|
|
} // while
|
|
|
|
FindClose(hFileSearch);
|
|
|
|
fRet = TRUE;
|
|
//
|
|
// Now the list box should be updated. We need a default selection, and then that will trigger the
|
|
// the fields to update correctly on the dialog box.
|
|
//
|
|
return fRet;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::LoadDataFilesFromSubdirectory(CString strSubdirectory)
|
|
{
|
|
EndDirectoryWithBackSlash(strSubdirectory);
|
|
CString strFullFilename ;
|
|
CString strRootDirSearchString = strSubdirectory;
|
|
|
|
strRootDirSearchString += m_strFileNameToSearchSubdirectoriesFor;
|
|
//
|
|
// Now we iterate through the subdirectory looking for files
|
|
//
|
|
//
|
|
|
|
WIN32_FIND_DATA wfdFindFileData;
|
|
|
|
HANDLE hFileSearch = FindFirstFile((LPCSTR)strRootDirSearchString , &wfdFindFileData);
|
|
if (hFileSearch == INVALID_HANDLE_VALUE)
|
|
{
|
|
// strOutput.Format("\r\nError : Didn't find any files in the source dir to copy.");
|
|
// OutputString(strOutput);
|
|
return TRUE;
|
|
}
|
|
if (wfdFindFileData.cFileName[0] == '\0')
|
|
{
|
|
// strOutput.Format("\r\nError : Didn't find any files in the source dir to copy.");
|
|
// OutputString(strOutput);
|
|
FindClose(hFileSearch);
|
|
return TRUE;
|
|
}
|
|
while (wfdFindFileData.cFileName[0])
|
|
{
|
|
if (!stricmp(wfdFindFileData.cFileName, ".") || !stricmp(wfdFindFileData.cFileName, ".."))
|
|
{
|
|
goto NextFile;
|
|
}
|
|
|
|
if (wfdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
goto NextFile;
|
|
}
|
|
|
|
strFullFilename = strSubdirectory;
|
|
strFullFilename += wfdFindFileData.cFileName;
|
|
|
|
//
|
|
// See if there is an additional filter function to call, and if so, call it
|
|
//
|
|
if (m_fnFilterFunction && !m_fnFilterFunction((LPCSTR)strFullFilename))
|
|
{
|
|
goto NextFile;
|
|
}
|
|
//
|
|
// We have a .data file, so see if it is appropriately setup and load into a data structure and
|
|
// add to the list box. We need to know if it is read only so we know whether or not we can
|
|
// alter the data
|
|
// The data structure will also have to store a variable to know if the data has been altered.
|
|
//
|
|
if (LoadObjectDataFromFile(strFullFilename , (wfdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)))
|
|
{
|
|
//
|
|
// If we successfully loaded the weapon, add it to the list box
|
|
//
|
|
// Alias some of the data for readability of the code
|
|
int nCurrObject = m_pObjectList->nObjectCount;
|
|
CDOPPROPERTIES_OBJECT_PROPERTIES * pObjectPropertiesArray = (m_pObjectList->ppPropertiesArray[nCurrObject]);
|
|
|
|
//
|
|
// CString is used to remove the directory info To the weapons name. Find the last \
|
|
//
|
|
CString strObjectNameOnly(pObjectPropertiesArray->szObjectName);
|
|
int nPos = 0;
|
|
if (!m_fShowFullObjectName)
|
|
{
|
|
nPos = strObjectNameOnly.ReverseFind('\\');
|
|
nPos ++; // goes to 0 if not found, otherwise the character after the \ or the null terminator if that's last
|
|
}
|
|
|
|
int nSel = m_lbObjectList.AddString((pObjectPropertiesArray->szObjectName + nPos));
|
|
m_lbObjectList.SetItemData(nSel, (DWORD) pObjectPropertiesArray);
|
|
m_pObjectList->nObjectCount++; // only increment on success since we don't want the index off in the list
|
|
}
|
|
|
|
|
|
|
|
NextFile:
|
|
|
|
if (!FindNextFile(hFileSearch, &wfdFindFileData))
|
|
{
|
|
break;
|
|
}
|
|
|
|
} // while
|
|
|
|
FindClose(hFileSearch);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::LoadObjectDataFromFile(CString strFullObjectFilename, BOOL fReadOnly )
|
|
{
|
|
// CString strOutput;
|
|
|
|
NotationFile infile(strFullObjectFilename, NotationFile::Raw);
|
|
|
|
//
|
|
// Alias some of the data for readability of the code
|
|
int nCurrObject = m_pObjectList->nObjectCount;
|
|
CDOPPROPERTIES_OBJECT_PROPERTIES * pObjectPropertiesArray = (m_pObjectList->ppPropertiesArray[nCurrObject]);
|
|
int nTotalProperties = m_paPropertiesToEdit->nCount;
|
|
//
|
|
// allocate the memory for the properties for this object
|
|
//
|
|
pObjectPropertiesArray->fDirty = FALSE;
|
|
pObjectPropertiesArray->fReadOnly = fReadOnly;
|
|
pObjectPropertiesArray->nProperties = nTotalProperties;
|
|
strcpy(pObjectPropertiesArray->szObjectName, (LPCSTR)strFullObjectFilename);
|
|
|
|
// already allocated
|
|
// pObjectPropertiesArray->ppObjectProperties = Allocate_CDOPPROPERTIES_OBJECT_PROPERTIES(nTotalProperties);
|
|
|
|
//
|
|
// Now go through and for each item in the properties list we need to get the page and entry
|
|
// we will cache the page name so we don't keep getting the same one if it repeats
|
|
//
|
|
|
|
|
|
Page * page = NULL;
|
|
char szCurrentPageName[128] = ""; // used to prevent repetitively searching for the same page
|
|
for (int j=0; j < nTotalProperties; j++)
|
|
{
|
|
pObjectPropertiesArray->ppObjectProperties[j]->fPresent = FALSE; // by default...
|
|
|
|
switch (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[j]->ePropertyType)
|
|
{
|
|
case efloat:
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.fltValue = 0.0f;
|
|
break;
|
|
case eint:
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.nValue = 0;
|
|
break;
|
|
case eLPSTR:
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.szValue[0] = 0;
|
|
break;
|
|
case eBOOL:
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.fValue = FALSE;
|
|
break;
|
|
case eVector3D:
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.v3dValues.x = 0.0f;
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.v3dValues.y = 0.0f;
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.v3dValues.z = 0.0f;
|
|
break;
|
|
} // switch for property type
|
|
|
|
const char * szPageName = GetPageNameToPropertyName(m_paPropertiesToEdit->ppProperties_To_Edit_Entry[j]->szPropertyTag);
|
|
if (!page || strcmp(szCurrentPageName, szPageName))
|
|
{
|
|
strcpy(szCurrentPageName, szPageName);
|
|
page = infile.FindPage(szPageName);
|
|
if (!page) // if for some reason we can't find the page, jump out
|
|
continue;
|
|
}
|
|
const char * szEntryName = GetEntryNameToPropertyName(m_paPropertiesToEdit->ppProperties_To_Edit_Entry[j]->szPropertyTag);
|
|
//
|
|
// For each item in the data list, if it shouldn't be there, delete it. If it supposed to be there set it
|
|
// Assumption is made that there are not two of any particular value key
|
|
//
|
|
switch (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[j]->ePropertyType)
|
|
{
|
|
case efloat:
|
|
if (page->GetEntry(szEntryName, &(pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.fltValue)))
|
|
{
|
|
pObjectPropertiesArray->ppObjectProperties[j]->fPresent = TRUE;
|
|
}
|
|
break;
|
|
case eint:
|
|
if (page->GetEntry(szEntryName, &(pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.nValue)))
|
|
{
|
|
pObjectPropertiesArray->ppObjectProperties[j]->fPresent = TRUE;
|
|
}
|
|
break;
|
|
case eLPSTR:
|
|
{
|
|
const char * szTemp;
|
|
if (page->GetEntry(szEntryName, &szTemp))
|
|
{
|
|
strcpy(pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.szValue, szTemp) ;
|
|
pObjectPropertiesArray->ppObjectProperties[j]->fPresent = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
case eBOOL:
|
|
if (page->GetEntry(szEntryName, &(pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.fValue)))
|
|
{
|
|
pObjectPropertiesArray->ppObjectProperties[j]->fPresent = TRUE;
|
|
}
|
|
break;
|
|
case eVector3D:
|
|
{
|
|
Vector3D v3D(0.0f, 0.0f, 0.0f);
|
|
if (page->GetEntry(szEntryName, (Vector3D *)&v3D))
|
|
{
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.v3dValues.x = v3D.x;
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.v3dValues.y = v3D.y;
|
|
pObjectPropertiesArray->ppObjectProperties[j]->uPropValue.v3dValues.z = v3D.z;
|
|
pObjectPropertiesArray->ppObjectProperties[j]->fPresent = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
} // switch for property type
|
|
|
|
} // for loop iterating properties
|
|
|
|
|
|
//
|
|
// This is a good place to make any known automated updates to the data. If we have just made them all
|
|
// add a new variable, or we removed a line, or we changed the type of data stored, we can do it at load
|
|
// time, then mark the dirty flag. Beware to honor the readonly flag here though. We don't want the read only
|
|
// and the dirty bit set at the same time.
|
|
//
|
|
|
|
//
|
|
// Note that we don't increment the weapon count here as we have to make sure we added to the list box
|
|
// since they are kept in sync by the index in the list box.
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
void CDlgObjectProperties::OnSelchangeObjectlist()
|
|
{
|
|
//
|
|
// First check what the old focus was, see if the data has changed, and if it has then we can
|
|
// update the weapons data structure and move to the next selection
|
|
//
|
|
|
|
// Load the current data into the variables, then copy that data to a weaponinfo structure
|
|
|
|
MoveCurSelDataToOrFromControls(FALSE);
|
|
|
|
//
|
|
// If we have selected something then we need to update info to the controls
|
|
//
|
|
m_nCurSel = m_lbObjectList.GetCurSel();
|
|
if(m_nCurSel!=-1)
|
|
{
|
|
m_popCurObjectPropertiesArray = (CDOPPROPERTIES_OBJECT_PROPERTIES * )(void *)m_lbObjectList.GetItemData(m_nCurSel);
|
|
MoveCurSelDataToOrFromControls(TRUE);
|
|
EnableControlsForCurrentSelection();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::DisableAllControls()
|
|
{
|
|
|
|
for (UINT i = IDC_DOP_PROPNAME; i < m_nLastControlID ; i++)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(i);
|
|
if (pWnd)
|
|
pWnd->EnableWindow(FALSE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::EnableControlsForCurrentSelection()
|
|
{
|
|
// In addition to enabling disabling the various controls...
|
|
// We also have to set the read only text properly when we are done
|
|
//
|
|
|
|
|
|
// if there is not a current selection then disable all and move on
|
|
if (m_popCurObjectPropertiesArray == NULL)
|
|
{
|
|
DisableAllControls();
|
|
SetDlgItemText(IDC_READONLY, MyLoadStringTempBuffer(IDS_READONLY));
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL fReadOnly = m_popCurObjectPropertiesArray->fReadOnly;
|
|
//
|
|
// If we got here then we have a selected item and need to enable/disable the controls properly
|
|
// based on the data object info structures
|
|
//
|
|
for (int i = 0; i < m_paPropertiesToEdit->nCount; i++)
|
|
{
|
|
// First is the first ID of the controls for this property. End is the first control of the next
|
|
// property.
|
|
UINT uiFirst = m_paPropertiesToEdit->ppProperties_To_Edit_Entry[i]->uiReserved1_CTRLID;
|
|
CWnd * pWnd = GetDlgItem(uiFirst);
|
|
BOOL fPresent = m_popCurObjectPropertiesArray->ppObjectProperties[i]->fPresent;
|
|
|
|
if (pWnd)
|
|
{
|
|
pWnd->EnableWindow(!fReadOnly);
|
|
}
|
|
pWnd = GetDlgItem(uiFirst+1);
|
|
if (pWnd)
|
|
{
|
|
pWnd->EnableWindow(!fReadOnly);
|
|
}
|
|
pWnd = GetDlgItem(uiFirst+2);
|
|
if (pWnd)
|
|
{
|
|
pWnd->EnableWindow(!fReadOnly && fPresent);
|
|
}
|
|
if (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[i]->ePropertyType == eVector3D)
|
|
{
|
|
pWnd = GetDlgItem(uiFirst+3);
|
|
if (pWnd)
|
|
{
|
|
pWnd->EnableWindow(!fReadOnly && fPresent);
|
|
}
|
|
|
|
pWnd = GetDlgItem(uiFirst+4);
|
|
if (pWnd)
|
|
{
|
|
pWnd->EnableWindow(!fReadOnly && fPresent);
|
|
}
|
|
} // if for vector3d property type
|
|
|
|
} // for loop for property list
|
|
|
|
|
|
|
|
SetDlgItemText(IDC_READONLY, (fReadOnly ? MyLoadStringTempBuffer(IDS_READONLY) : _T("")));
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::MoveCurSelDataToOrFromControls(BOOL fToControls)
|
|
{
|
|
|
|
|
|
// if there is not a current selection then disable all and move on
|
|
if (m_popCurObjectPropertiesArray == NULL)
|
|
{
|
|
DisableAllControls();
|
|
SetDlgItemText(IDC_READONLY, MyLoadStringTempBuffer(IDS_READONLY));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If we are retrieving To the controls we need to save off what we have and
|
|
// see if it changed.
|
|
//
|
|
|
|
CDOPPROPERTIES_OBJECT_PROPERTIES * pPropertyArray = NULL;
|
|
if (!fToControls)
|
|
{
|
|
pPropertyArray = Allocate_CDOPPROPERTIES_OBJECT_PROPERTIES(
|
|
m_paPropertiesToEdit->nCount);
|
|
Copy_CDOPPROPERTIES_OBJECT_PROPERTIES(pPropertyArray, m_popCurObjectPropertiesArray);
|
|
}
|
|
UpdateControlData(fToControls); // put the data in the controls based on the current data pointer
|
|
|
|
|
|
//
|
|
// See if the data changed if we are reading To the controls
|
|
//
|
|
if (!fToControls)
|
|
{
|
|
if (!IsEqual_CDOPPROPERTIES_OBJECT_PROPERTIES(pPropertyArray, m_popCurObjectPropertiesArray))
|
|
{
|
|
m_popCurObjectPropertiesArray->fDirty = TRUE; // it changed
|
|
m_fDirty = TRUE; // at least one object has changed.
|
|
}
|
|
free(pPropertyArray);
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
|
|
BOOL CDlgObjectProperties::GetBOOLFromButton(UINT uiID, BOOL * pfDest)
|
|
{
|
|
CButton * pWnd = (CButton *)GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
*pfDest = pWnd->GetCheck();
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::GetBOOLFromControl(UINT uiID, BOOL * pfDest)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
GetDlgItemText(uiID, szTemp, 255);
|
|
|
|
*pfDest = FALSE;
|
|
if (!stricmp(szTemp, "true") ||
|
|
!stricmp(szTemp, "yes") ||
|
|
!stricmp(szTemp, "1"))
|
|
{
|
|
*pfDest = TRUE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::GetfloatFromControl(UINT uiID, float * pfltDest)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
GetDlgItemText(uiID, szTemp, 255);
|
|
*pfltDest = (float)atof(szTemp);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::GetLPSTRFromControl(UINT uiID, LPSTR pszDest)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
GetDlgItemText(uiID, szTemp, 255);
|
|
szTemp[255] = 0;
|
|
strcpy(pszDest, szTemp);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::GetintFromControl(UINT uiID, int * pnDest)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
GetDlgItemText(uiID, szTemp, 255);
|
|
*pnDest = atoi(szTemp);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::GetVector3DFromControl(UINT uiID, float * pfltx, float * pflty, float * pfltz)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
GetDlgItemText(uiID, szTemp, 255);
|
|
*pfltx = (float)atof(szTemp);
|
|
pWnd = GetDlgItem(uiID +1);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
GetDlgItemText(uiID+1, szTemp, 255);
|
|
*pflty = (float)atof(szTemp);
|
|
pWnd = GetDlgItem(uiID +2);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
GetDlgItemText(uiID+2, szTemp, 255);
|
|
*pfltz = (float)atof(szTemp);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SetBOOLToButton(UINT uiID, BOOL fDest)
|
|
{
|
|
CButton * pWnd = (CButton *)GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
pWnd->SetCheck(fDest);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SetBOOLToControl(UINT uiID, BOOL fSrc)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
sprintf(szTemp, fSrc ? "true" : "false");
|
|
SetDlgItemText(uiID, szTemp);
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SetfloatToControl(UINT uiID, float fltSrc)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
sprintf(szTemp, "%f", (double) fltSrc);
|
|
SetDlgItemText(uiID, szTemp);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SetLPSTRToControl(UINT uiID, LPSTR pszSrc)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
SetDlgItemText(uiID, pszSrc);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SetintToControl(UINT uiID, int nSrc)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
sprintf(szTemp, "%d", nSrc);
|
|
SetDlgItemText(uiID, szTemp);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::SetVector3DToControl(UINT uiID, float fltx, float flty, float fltz)
|
|
{
|
|
CWnd * pWnd = GetDlgItem(uiID);
|
|
if (!pWnd)
|
|
return FALSE;
|
|
char szTemp[256];
|
|
sprintf(szTemp, "%f", (double) fltx);
|
|
SetDlgItemText(uiID, szTemp);
|
|
|
|
sprintf(szTemp, "%f", (double) flty);
|
|
SetDlgItemText(uiID + 1, szTemp);
|
|
|
|
sprintf(szTemp, "%f", (double) fltz);
|
|
SetDlgItemText(uiID + 2, szTemp);
|
|
return TRUE;
|
|
}
|
|
|
|
//****************************************************************************************
|
|
//
|
|
//****************************************************************************************
|
|
BOOL CDlgObjectProperties::UpdateControlData(BOOL fToControls)
|
|
{
|
|
if (!m_popCurObjectPropertiesArray)
|
|
return FALSE;
|
|
BOOL fReadOnly = m_popCurObjectPropertiesArray->fReadOnly;
|
|
if (fReadOnly && !fToControls)
|
|
return FALSE; // don't bother reading if we don't have to
|
|
//
|
|
//
|
|
for (int i = 0; i < m_paPropertiesToEdit->nCount; i++)
|
|
{
|
|
// First is the first ID of the controls for this property. End is the first control of the next
|
|
// property.
|
|
UINT uiFirst = m_paPropertiesToEdit->ppProperties_To_Edit_Entry[i]->uiReserved1_CTRLID;
|
|
if (!fToControls)
|
|
{
|
|
GetBOOLFromButton(uiFirst + 1,&(m_popCurObjectPropertiesArray->ppObjectProperties[i]->fPresent) );
|
|
switch (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[i]->ePropertyType)
|
|
{
|
|
case efloat:
|
|
GetfloatFromControl(uiFirst + 2,&(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.fltValue));
|
|
break;
|
|
case eint:
|
|
GetintFromControl(uiFirst + 2,&(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.nValue));
|
|
break;
|
|
case eLPSTR:
|
|
GetLPSTRFromControl(uiFirst + 2,(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.szValue));
|
|
break;
|
|
case eBOOL:
|
|
GetBOOLFromControl(uiFirst + 2,&(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.fValue));
|
|
break;
|
|
case eVector3D:
|
|
GetVector3DFromControl(uiFirst + 2,&(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.v3dValues.x),
|
|
&(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.v3dValues.y),
|
|
&(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.v3dValues.z));
|
|
break;
|
|
} // switch on property type
|
|
} // if !fFromControls
|
|
else
|
|
{
|
|
SetBOOLToButton(uiFirst + 1,(m_popCurObjectPropertiesArray->ppObjectProperties[i]->fPresent) );
|
|
switch (m_paPropertiesToEdit->ppProperties_To_Edit_Entry[i]->ePropertyType)
|
|
{
|
|
case efloat:
|
|
SetfloatToControl(uiFirst + 2,(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.fltValue));
|
|
break;
|
|
case eint:
|
|
SetintToControl(uiFirst + 2,(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.nValue));
|
|
break;
|
|
case eLPSTR:
|
|
SetLPSTRToControl(uiFirst + 2,(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.szValue));
|
|
break;
|
|
case eBOOL:
|
|
SetBOOLToControl(uiFirst + 2,(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.fValue));
|
|
break;
|
|
case eVector3D:
|
|
SetVector3DToControl(uiFirst + 2,(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.v3dValues.x),
|
|
(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.v3dValues.y),
|
|
(m_popCurObjectPropertiesArray->ppObjectProperties[i]->uPropValue.v3dValues.z));
|
|
break;
|
|
} // switch on property type
|
|
}
|
|
} // for loop for property list
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|