ENGNLIST.CXX

//+--------------------------------------------------------------------------- 
//
// Microsoft Windows
// Copyright 1992 - 1998 Microsoft Corporation.
//
// File: engnlist.cxx
//
// Contents: implementation for CEngineList
//
// Classes: CEngineList
//
// Functions:
//
// History: 4-14-94 stevebl Created
//
//----------------------------------------------------------------------------

#include "engnlist.h"
#include <mandcid.h>
#include <juliacid.h>
#include <plasmcid.h>
#include <rgencid.h>

//+---------------------------------------------------------------------------
//
// Member: CEngineList::CEngineList
//
// Synopsis: constructor
//
// Arguments: [hmenuOuter] - handle to the menu where the list of engines
// will be attached
//
// History: 4-14-94 stevebl Created
//
//----------------------------------------------------------------------------

CEngineList::CEngineList(HMENU hmenuOuter)
{
_hmenuOuter = hmenuOuter;
_hMenu = NULL;
_rgCID = NULL;
_rgszName = NULL;
_nEntries = 0;
}

//+---------------------------------------------------------------------------
//
// Member: CEngineList::~CEngineList
//
// Synopsis: destructor
//
// History: 4-14-94 stevebl Created
//
//----------------------------------------------------------------------------

CEngineList::~CEngineList()
{
if (_rgCID)
{
delete(_rgCID);
}
if (_rgszName)
{
for (unsigned x = _nEntries; x--;)
{
delete[](_rgszName[x]);
}
delete[](_rgszName);
}
if (_hMenu)
{
DestroyMenu(_hMenu);
}
}

//+---------------------------------------------------------------------------
//
// Member: CEngineList::Read
//
// Synopsis: Reads the list of engines from the registry.
//
// If there are no entries in the registry for MFract then this
// routine creates some entries with the default set of
// fractal engines.
//
// Returns: S_OK on success
// E_FAIL if there was a problem
//
// History: 4-14-94 stevebl Created
//
//----------------------------------------------------------------------------

HRESULT CEngineList::Read()
{
HRESULT hr = S_OK;
if (FAILED(hr))
{
return(hr);
}
DWORD dwDisposition;
HKEY hkSoftware;
LONG lReturn = RegCreateKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("Software"),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ,
NULL,
&hkSoftware,
&dwDisposition);
if (lReturn == ERROR_SUCCESS)
{
HKEY hkMicrosoft;
lReturn = RegCreateKeyEx(
hkSoftware,
TEXT("Microsoft"),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ |
KEY_WRITE,
NULL,
&hkMicrosoft,
&dwDisposition);
if (lReturn == ERROR_SUCCESS)
{
HKEY hkApp;
lReturn = RegCreateKeyEx(
hkMicrosoft,
TEXT(APP_TITLE),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ |
KEY_WRITE |
KEY_SET_VALUE,
NULL,
&hkApp,
&dwDisposition);
if (lReturn == ERROR_SUCCESS)
{
HKEY hkFractalTypes;
lReturn = RegCreateKeyEx(
hkApp,
TEXT("Fractal Types"),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ |
KEY_WRITE |
KEY_SET_VALUE,
NULL,
&hkFractalTypes,
&dwDisposition);
if (lReturn == ERROR_SUCCESS)
{
if (dwDisposition == REG_OPENED_EXISTING_KEY)
{
// Enumerate the values in this key to build our list
DWORD cchClass = 0;
DWORD cSubkeys;
DWORD cchMaxSubkey;
DWORD cchMaxClass;
DWORD cValues;
DWORD cchMaxValueName;
DWORD cbMaxValueData;
DWORD cbSecurityDescriptor;
FILETIME ftLastWriteTime;
lReturn = RegQueryInfoKey(
hkFractalTypes,
NULL,
&cchClass,
0,
&cSubkeys,
&cchMaxSubkey,
&cchMaxClass,
&cValues,
&cchMaxValueName,
&cbMaxValueData,
&cbSecurityDescriptor,
&ftLastWriteTime);
_rgCID = new CLSID[cValues];
_rgszName = new TCHAR *[cValues];
for (DWORD uIndex = cValues; uIndex--;)
{
TCHAR * szCLSID = (TCHAR *) new BYTE [cbMaxValueData];
TCHAR * szName = new TCHAR[cchMaxValueName+1];
DWORD cchValue = cchMaxValueName+1;
DWORD cbData = cbMaxValueData;
lReturn = RegEnumValue(
hkFractalTypes,
uIndex,
szName,
&cchValue,
0,
NULL,
NULL,
&cbData);
cchValue++;
_rgszName[uIndex] = new TCHAR[cchValue];
lReturn = RegEnumValue(
hkFractalTypes,
uIndex,
_rgszName[uIndex],
&cchValue,
0,
NULL,
(BYTE *) szCLSID,
&cbData);
#ifdef UNICODE
CLSIDFromString(szCLSID, &_rgCID[uIndex]);
#else
OLECHAR wszCLSID[40]; // should be more than large enough
mbstowcs(wszCLSID, szCLSID, 40);
CLSIDFromString(wszCLSID, &_rgCID[uIndex]);
#endif
delete[] szCLSID;
delete[] szName;
}
_nEntries = cValues;
}
else
{
// This is the first time MFract has been run on this machine.
// Create the default key entries.
_rgCID = new CLSID[4];
_rgszName = new TCHAR * [4];
TCHAR szCLSID[40]; // more than large enough
#ifndef UNICODE
OLECHAR wszCLSID[40];
#endif
#ifdef UNICODE
StringFromGUID2(CLSID_MANDELBROT, szCLSID, 40);
#else
StringFromGUID2(CLSID_MANDELBROT, wszCLSID, 40);
wcstombs(szCLSID, wszCLSID, 40);
#endif
lReturn = RegSetValueEx(
hkFractalTypes,
TEXT("Mandelbrot Fractal"),
0,
REG_SZ,
(BYTE *) szCLSID,
sizeof(TCHAR) * (1 +
#ifdef UNICODE
wcslen(szCLSID)
#else
strlen(szCLSID)
#endif
)
);
memcpy(&_rgCID[0], &CLSID_MANDELBROT, sizeof (CLSID));
_rgszName[0] =
#ifdef UNICODE
_wcsdup(TEXT("Mandelbrot Fractal"));
#else
_strdup(TEXT("Mandelbrot Fractal"));
#endif
#ifdef UNICODE
StringFromGUID2(CLSID_JULIASET, szCLSID, 40);
#else
StringFromGUID2(CLSID_JULIASET, wszCLSID, 40);
wcstombs(szCLSID, wszCLSID, 40);
#endif
lReturn = RegSetValueEx(
hkFractalTypes,
TEXT("Julia Set Fractal"),
0,
REG_SZ,
(BYTE *) szCLSID,
sizeof(TCHAR) * (1 +
#ifdef UNICODE
wcslen(szCLSID)
#else
strlen(szCLSID)
#endif
)
);
memcpy(&_rgCID[1], &CLSID_JULIASET, sizeof (CLSID));
_rgszName[1] =
#ifdef UNICODE
_wcsdup(TEXT("Julia Set Fractal"));
#else
_strdup(TEXT("Julia Set Fractal"));
#endif
#ifdef UNICODE
StringFromGUID2(CLSID_PLASMA, szCLSID, 40);
#else
StringFromGUID2(CLSID_PLASMA, wszCLSID, 40);
wcstombs(szCLSID, wszCLSID, 40);
#endif
lReturn = RegSetValueEx(
hkFractalTypes,
TEXT("Plasma Cloud Fractal"),
0,
REG_SZ,
(BYTE *) szCLSID,
sizeof(TCHAR) * (1 +
#ifdef UNICODE
wcslen(szCLSID)
#else
strlen(szCLSID)
#endif
)
);
memcpy(&_rgCID[2], &CLSID_PLASMA, sizeof (CLSID));
_rgszName[2] =
#ifdef UNICODE
_wcsdup(TEXT("Plasma Cloud Fractal"));
#else
_strdup(TEXT("Plasma Cloud Fractal"));
#endif
#ifdef UNICODE
StringFromGUID2(CLSID_RGEN, szCLSID, 40);
#else
StringFromGUID2(CLSID_RGEN, wszCLSID, 40);
wcstombs(szCLSID, wszCLSID, 40);
#endif
lReturn = RegSetValueEx(
hkFractalTypes,
TEXT("Recursive Generator Fractal"),
0,
REG_SZ,
(BYTE *) szCLSID,
sizeof(TCHAR) * (1 +
#ifdef UNICODE
wcslen(szCLSID)
#else
strlen(szCLSID)
#endif
)
);
memcpy(&_rgCID[3], &CLSID_RGEN, sizeof (CLSID));
_rgszName[3] =
#ifdef UNICODE
_wcsdup(TEXT("Recursive Generator Fractal"));
#else
_strdup(TEXT("Recursive Generator Fractal"));
#endif
_nEntries = 4;
}
RegCloseKey(hkFractalTypes);
}
else
{
// couldn't access registry
hr = E_FAIL;
}
RegCloseKey(hkApp);
}
else
{
// couldn't access registry
hr = E_FAIL;
}
RegCloseKey(hkMicrosoft);
}
else
{
// couldn't access registry
hr = E_FAIL;
}
RegCloseKey(hkSoftware);
}
else
{
// couldn't access registry
hr = E_FAIL;
}
if (_hMenu)
{
DestroyMenu(_hMenu);
}
_hMenu = CreatePopupMenu();
if (_hMenu)
{
for (unsigned u=_nEntries; u--;)
{
if (!InsertMenu(
_hMenu,
0,
MF_BYPOSITION | (MF_CHECKED * (0 == u)),
IDM_FRACTAL_TYPE + u,
_rgszName[u]))
{
// Insert Menu Failed
hr = E_FAIL;
}
}
TCHAR szMenuString[MAX_STRING_LENGTH];
GetMenuString(_hmenuOuter,
IDM_SELECT_TYPE,
szMenuString,
MAX_STRING_LENGTH,
MF_BYCOMMAND);
if (!ModifyMenu(
_hmenuOuter,
IDM_SELECT_TYPE,
MF_BYCOMMAND | MF_POPUP,
(UINT)_hMenu,
szMenuString))
{
// ModifyMenu failed
hr = E_FAIL;
}
}
else
{
// couldn't create menu
hr = E_FAIL;
}
return(hr);
}

//+---------------------------------------------------------------------------
//
// Member: CEngineList::GetEntry
//
// Synopsis: returns the CLSID of the fractal engine at a given index
//
// Arguments: [uIndex] - index of the engine
//
// Returns: CLSID of the fractal engine
//
// History: 4-14-94 stevebl Created
//
//----------------------------------------------------------------------------

CLSID CEngineList::GetEntry(unsigned uIndex)
{
return(_rgCID[uIndex]);
}

//+---------------------------------------------------------------------------
//
// Member: CEngineList::FindEntry
//
// Synopsis: Looks through the list of CLSIDs to find out what engine number
// has this CLSID.
//
// Arguments: [cid] - CLSID of the fractal engine
//
// Returns: >= 0 if the CLSID was found
// -1 if the CLSID was not found
//
// History: 4-14-94 stevebl Created
//
//----------------------------------------------------------------------------

int CEngineList::FindEntry(CLSID cid)
{
for (unsigned u = _nEntries; u--;)
{
if (IsEqualGUID(cid, _rgCID[u]))
{
return((int) u);
}
}
// not found in the list
return(-1);
}