windows-nt/Source/XPSP1/NT/shell/osshell/themes/themesw/init.c
2020-09-26 16:20:57 +08:00

814 lines
28 KiB
C

/* INIT.C
Resident Code Segment // Tweak: make non-resident
Initialization and destroy routines
InitFrost()
CloseFrost()
Frosting: Master Theme Selector for Windows '95
Copyright (c) 1994-1999 Microsoft Corporation. All rights reserved.
*/
// ---------------------------------------------
// Brief file history:
// Alpha:
// Beta:
// Bug fixes
// ---------
//
// ---------------------------------------------
#include "windows.h"
#include "frost.h"
#include "global.h"
#include "schedule.h"
#include "htmlprev.h"
// Local Routines
BOOL InitInstance(HINSTANCE, HINSTANCE, int);
BOOL GetRotateTheme(LPTSTR);
// Globals
TCHAR szPlus_CurTheme[] = TEXT("Software\\Microsoft\\Plus!\\Themes\\Current");
TCHAR szPlus_CBs[] = TEXT("Software\\Microsoft\\Plus!\\Themes\\Apply");
#define bThemed (*szCurThemeFile)
// Reg paths for finding potential Theme directories
#define PLUS95_KEY TEXT("Software\\Microsoft\\Plus!\\Setup")
#define PLUS95_PATH TEXT("DestPath")
#define PLUS98_KEY TEXT("Software\\Microsoft\\Plus!98")
#define PLUS98_PATH TEXT("Path")
#define KIDS_KEY TEXT("Software\\Microsoft\\Microsoft Kids\\Kids Plus!")
#define KIDS_PATH TEXT("InstallDir")
#define PROGRAMFILES_KEY TEXT("Software\\Microsoft\\Windows\\CurrentVersion")
#define PROGRAMFILES_PATH TEXT("ProgramFilesDir")
// ProcessCmdLine
//
// Very basic commandline: "/s themefile" to apply theme
// "themefile" to open app with theme selected
// and curdir to be that file's dir
//
// Return: TRUE if we should exit the app
// FALSE to continue execution
//
BOOL ProcessCmdLine(LPTSTR lpCmdLine)
{
extern TCHAR szFrostSection[], szMagic[], szVerify[];
BOOL fSetTheme = FALSE;
BOOL fRotateTheme = FALSE;
LPTSTR lpszThemeFile;
BOOL fStopOnQuote = FALSE;
WIN32_FIND_DATA wfdFind;
HANDLE hFind;
TCHAR szRotateTheme[MAX_PATH];
// TCHAR szThemesExe[MAX_PATH];
DWORD dwRet;
HKEY hKey;
extern TCHAR szPlus_CurTheme[];
Assert(0, TEXT("Cmd line: '"));
Assert(0, lpCmdLine);
Assert(0, TEXT("'\n"));
// Skip leading whitespace.
while (*lpCmdLine && (*lpCmdLine != TEXT('/')))
lpCmdLine = CharNext(lpCmdLine);
// Check for special switches.
if (*lpCmdLine == TEXT('/')) {
lpCmdLine = CharNext(lpCmdLine);
switch (*lpCmdLine) {
// "Set" theme as active.
case TEXT('s'):
case TEXT('S'):
fSetTheme = TRUE;
lpCmdLine = CharNext(lpCmdLine);
break;
case TEXT('r'):
case TEXT('R'):
fRotateTheme = TRUE;
lpCmdLine = CharNext(lpCmdLine);
break;
default:
return FALSE; // invalid flag so continue execution EXIT
}
while (*lpCmdLine == TEXT(' '))
lpCmdLine = CharNext(lpCmdLine);
}
// Handle quoted long file names. Even if the name isn't quoted, we'll
// still parse to the end of the commandline.
if (*lpCmdLine == TEXT('\"')) {
fStopOnQuote = TRUE;
lpCmdLine = CharNext(lpCmdLine);
}
lpszThemeFile = lpCmdLine;
// Parse until end of line or we find the closing quote.
while (*lpCmdLine && !(fStopOnQuote && *lpCmdLine == TEXT('\"')))
lpCmdLine = CharNext(lpCmdLine);
// Back up to the last non-whitespace character.
while (lpCmdLine > lpszThemeFile && *(lpCmdLine-1) == TEXT(' '))
lpCmdLine = CharPrev(lpszThemeFile, lpCmdLine);
// If there's anything after the closing quote, so what?
*lpCmdLine = TEXT('\0');
// This is our chance to fake a theme rotation "/r" into the
// "/s" paradigm. Let's get a string to the next theme in the
// rotation.
if (fRotateTheme) {
if (GetRotateTheme(szRotateTheme)) {
fSetTheme = TRUE;
lpszThemeFile = szRotateTheme;
}
// GetRotateTheme failed. If we fall through we're likely
// to display the main dialog and we don't want to do that
// in the "/r" case. Just exit the app.
else return TRUE;
}
// After all that work, nothing was specified on the commandline.
if (lpszThemeFile == lpCmdLine)
return FALSE; // no filename so continue execution EXIT
//
// OK: you've got a theme file. if it is for real, save it for use.
// first check existence
hFind = FindFirstFile(lpszThemeFile, (LPWIN32_FIND_DATA)&wfdFind);
if (INVALID_HANDLE_VALUE == hFind)
return (TRUE); // file doesn't exist so continue execution EXIT
// PLUS98 BUG 1293 -- this used to return FALSE
// and open the Theme applet if /s had an invalid
// file. Now we return TRUE which closes Themes
// then check for magic string
GetPrivateProfileString((LPTSTR)szFrostSection,
(LPTSTR)szMagic,
(LPTSTR)szNULL,
(LPTSTR)szMsg, MAX_MSGLEN,
lpszThemeFile);
// magic str check
if (lstrcmp((LPTSTR)szMsg, (LPTSTR)szVerify)) {
// No magic string so this must not be a real theme file.
// If this was from a "/r" rotate we want to return TRUE and
// bail out. Otherwise return FALSE so we open the Theme
// app. (this was the existing Plus 95 behavior):
if (fRotateTheme) return (TRUE);
else return (FALSE);
}
//
// get the confirmed theme into the necessary globals
// save theme file using the long filename
lstrcpy(szCurThemeFile, lpszThemeFile); // actual pathname verified
// save cur dir (not theme dir)
lstrcpy(szCurDir, szCurThemeFile);
*(FileFromPath(szCurDir)) = 0;
// save theme name
lstrcpy(szCurThemeName, wfdFind.cFileName); // make sure long filename
TruncateExt(szCurThemeName);
// now maybe we just want to apply the theme and exit
if (fSetTheme) {
// Make sure there is even enough space to do theme
// But don't complain, if there isn't
if (! CheckSpace (NULL, FALSE)) // definition in Regutils.c
return FALSE;
// Make the apply code write out everything.
InitCheckboxes();
// Simulate a left shift keypress to wake up the screensaver.
// Otherwise if the SS is running and we apply a new SS you
// can wind up with dueling savers...
keybd_event(VK_LSHIFT, 0, 0, 0);
keybd_event(VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0);
ApplyThemeFile(lpszThemeFile);
// APPCOMPAT -- Plus95 Themes was not updating the Current Theme
// setting in the registry on this codepath. Need to fix that
// here.
dwRet = RegOpenKeyEx(HKEY_CURRENT_USER, szPlus_CurTheme,
(DWORD)0, KEY_SET_VALUE, (PHKEY)&hKey );
if (dwRet != ERROR_SUCCESS) {
DWORD dwDisposition;
Assert(FALSE, TEXT("couldn't RegOpenKey save theme file\n"));
dwRet = RegCreateKeyEx( HKEY_CURRENT_USER, szPlus_CurTheme,
(DWORD)0, (LPTSTR)szNULL, REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE, (LPSECURITY_ATTRIBUTES)NULL,
(PHKEY)&hKey, (LPDWORD)&dwDisposition );
}
// if open or create worked
if (dwRet == ERROR_SUCCESS) {
dwRet = RegSetValueEx(hKey, (LPTSTR)NULL, // default value
0,
(DWORD)REG_SZ,
(LPBYTE)lpszThemeFile,
(DWORD)( SZSIZEINBYTES((LPTSTR)szCurThemeFile) + 1 ));
RegCloseKey(hKey);
}
Assert(dwRet == ERROR_SUCCESS, TEXT("couldn't open, set or create Registry save theme file\n"));
return TRUE; // set the theme so now just exit app EXIT
} // end if fSetTheme
return FALSE; // continue execution
}
// InitFrost
// Since there are no window classes to register, this routine just loads
// the strings and, since there's only one instance, calls InitInstance().
//
// Returns: success of initialization
BOOL FAR InitFrost(hPrevInstance, hInstance, lpCmdLine, nCmdShow)
HINSTANCE hPrevInstance;
HINSTANCE hInstance; /* Current instance identifier. */
LPTSTR lpCmdLine;
int nCmdShow; /* Param for first ShowWindow() call. */
{
LPTSTR lpScan, lpTemp;
WNDCLASS WndClass;
BOOL bret;
BOOL bGotThemeDir;
HDC hdc;
//
// Get initial strings
// (Gauranteed enough mem at app init for these loads)
InitNoMem(hInstance);
LoadString(hInstance, STR_APPNAME, szAppName, MAX_STRLEN);
LoadString(hInstance, STR_CURSET, szCurSettings, MAX_STRLEN);
LoadString(hInstance, STR_PREVSET, szPrevSettings, MAX_STRLEN);
LoadString(hInstance, STR_PREVSETFILE, szPrevSettingsFilename, MAX_STRLEN);
LoadString(hInstance, STR_OTHERTHM, szOther, MAX_STRLEN);
LoadString(hInstance, STR_THMEXT, szExt, MAX_STRLEN);
LoadString(hInstance, STR_PREVIEWTITLE, szPreviewTitle, MAX_STRLEN);
LoadString(hInstance, STR_HELPFILE, szHelpFile, MAX_STRLEN);
LoadString(hInstance, STR_HELPFILE98, szHelpFile98, MAX_STRLEN);
LoadString(hInstApp, STR_SUGGEST, szNewFile, MAX_STRLEN);
LoadString(hInstApp, STR_SAVETITLE, szSaveTitle, MAX_STRLEN);
LoadString(hInstApp, STR_OPENTITLE, szOpenTitle, MAX_STRLEN);
LoadString(hInstApp, STR_FILETYPE, szFileTypeDesc, MAX_STRLEN);
WndClass.style = CS_DBLCLKS | CS_BYTEALIGNWINDOW | CS_GLOBALCLASS;
WndClass.lpfnWndProc = DefDlgProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = DLGWINDOWEXTRA;
WndClass.hInstance = hInstApp;
WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(FROST_ICON));
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = szClassName;
if (!RegisterClass(&WndClass))
return FALSE;
// Initialize our g_bGradient flag
hdc = GetDC(NULL);
g_bGradient = (BOOL)(GetDeviceCaps(hdc, BITSPIXEL) > 8);
ReleaseDC(NULL, hdc);
//
// build file search string
lpScan = (LPTSTR)szFileTypeDesc;
while (*lpScan) {
if (2 == CompareString(LOCALE_USER_DEFAULT, NORM_IGNOREWIDTH,
(LPTSTR)TEXT("|"), 1, lpScan, 1)) {
lpTemp = lpScan;
lpScan = CharNext(lpScan);
*lpTemp = 0;
}
else
lpScan = CharNext(lpScan);
}
//
// init directory strings
// theme directory - for now it is subdir of EXE dir
GetModuleFileName(hInstApp, (LPTSTR)szThemeDir, MAX_PATHLEN);
*(FileFromPath((LPTSTR)szThemeDir)) = 0; // leaves trailing '\'
// Save this path momentarily -- if we can't find any good Themes
// directory we're going to fall back to this directory.
lstrcpy(szCurDir, szThemeDir);
// Tack a "Themes" onto the path
LoadString(hInstance, STR_THEMESUBDIR, // includes trailing '\'
(LPTSTR)(szThemeDir + lstrlen((LPTSTR)szThemeDir)), MAX_STRLEN);
// Find out if this ThemeDir even exists. If it doesn't we need
// to get creative in finding our ThemeDir by searching the
// following locales:
//
// Plus!98 Install Path\Themes
// Plus!95 Install Path\Themes
// Kids for Plus! Install Path\Themes
// Program Files\Plus!\Themes
bGotThemeDir = FALSE;
Assert(0, TEXT("Themes.exe\\Themes path: "));
Assert(0, szThemeDir);
Assert(0, TEXT("\n"));
if (0xFFFFFFFF != GetFileAttributes(szThemeDir)) bGotThemeDir = TRUE;
if (!bGotThemeDir)
{
// Haven't found ThemeDir yet. Try the Plus!98 location
bret = HandGet(HKEY_LOCAL_MACHINE, PLUS98_KEY,
PLUS98_PATH, (LPTSTR)szThemeDir);
if (bret)
{
// Tack a "Themes" onto the path
lstrcat(szThemeDir, TEXT("\\"));
LoadString(hInstance, STR_THEMESUBDIR,
(szThemeDir + lstrlen((LPTSTR)szThemeDir)), MAX_STRLEN);
Assert(0, TEXT("Plus! 98 path: "));
Assert(0, szThemeDir);
Assert(0, TEXT("\n"));
if (0xFFFFFFFF != GetFileAttributes(szThemeDir)) bGotThemeDir = TRUE;
}
}
if (!bGotThemeDir)
{
// Still haven't found ThemeDir. Try the Plus! 95 location
bret = HandGet(HKEY_LOCAL_MACHINE, PLUS95_KEY,
PLUS95_PATH, (LPTSTR)szThemeDir);
if (bret)
{
// Tack on a "Themes" onto the path
// Plus!95 DestPath has "Plus!.dll" on the end so get rid
// of that.
*(FileFromPath(szThemeDir)) = 0;
LoadString(hInstance, STR_THEMESUBDIR,
(szThemeDir + lstrlen((LPTSTR)szThemeDir)), MAX_STRLEN);
Assert(0, TEXT("Plus! 95 path: "));
Assert(0, szThemeDir);
Assert(0, TEXT("\n"));
if (0xFFFFFFFF != GetFileAttributes(szThemeDir)) bGotThemeDir = TRUE;
}
}
if (!bGotThemeDir)
{
// Still haven't found ThemeDir. Try the Kids for Plus! location
bret = HandGet(HKEY_LOCAL_MACHINE, KIDS_KEY,
KIDS_PATH, (LPTSTR)szThemeDir);
if (bret)
{
// Tack a "\Plus! for Kids\Themes" onto the path
lstrcat(szThemeDir, TEXT("\\Plus! for Kids\\"));
LoadString(hInstance, STR_THEMESUBDIR,
(szThemeDir + lstrlen((LPTSTR)szThemeDir)), MAX_STRLEN);
Assert(0, TEXT("Kids Plus! path: "));
Assert(0, szThemeDir);
Assert(0, TEXT("\n"));
if (0xFFFFFFFF != GetFileAttributes(szThemeDir)) bGotThemeDir = TRUE;
}
}
if (!bGotThemeDir)
{
// Still haven't found ThemeDir. Try the Program Files\Plus! location
bret = HandGet(HKEY_LOCAL_MACHINE, PROGRAMFILES_KEY,
PROGRAMFILES_PATH, (LPTSTR)szThemeDir);
if (bret)
{
// Tack a "Plus!\Themes" onto the path
lstrcat(szThemeDir, TEXT("\\Plus!\\"));
LoadString(hInstance, STR_THEMESUBDIR,
(szThemeDir + lstrlen((LPTSTR)szThemeDir)), MAX_STRLEN);
Assert(0, TEXT("Program Files path: "));
Assert(0, szThemeDir);
Assert(0, TEXT("\n"));
if (0xFFFFFFFF != GetFileAttributes(szThemeDir)) bGotThemeDir = TRUE;
}
}
if (!bGotThemeDir)
{
// After all that searching we still haven't found a good Theme
// dir. So we'll just use the directory where Themes.exe is
// located -- we saved this in szCurDir before we started this
// search process.
lstrcpy(szThemeDir, szCurDir);
Assert(0, TEXT("Themes.exe path: "));
Assert(0, szThemeDir);
Assert(0, TEXT("\n"));
}
// default current dir
lstrcpy((LPTSTR)szCurDir, (LPTSTR)szThemeDir);
// Windows directory
GetWindowsDirectory((LPTSTR)szWinDir, MAX_PATHLEN);
if (TEXT('\\') != szWinDir[lstrlen((LPTSTR)szWinDir)-1])
lstrcat((LPTSTR)szWinDir, (LPTSTR)TEXT("\\"));
//
// see if there is a previous theme file to return to
bret = HandGet(HKEY_CURRENT_USER, szPlus_CurTheme,
(LPTSTR)NULL, (LPTSTR)szMsg);
Assert(bret, TEXT("no previous theme file in Registry!\n"));
if (bret) {
// get init cur dir from prev theme file
lstrcpy(szCurDir, szMsg);
*(FileFromPath(szCurDir)) = 0;
// Used to actually set the cur theme file/name to prev theme.
// Now we just use the directory if there is a prev theme.
// No longer care if it is a real file or a theme file or not.
#ifdef REVERT
WIN32_FIND_DATA wfdFind;
HANDLE hFind;
extern TCHAR szFrostSection[], szMagic[], szVerify[];
TCHAR szMagicTest[MAX_STRLEN+1];
// first check if it is for real: existence
hFind = FindFirstFile(szMsg, (LPWIN32_FIND_DATA)&wfdFind);
if (INVALID_HANDLE_VALUE != hFind) {
// then check if it is for real: theme file magic string
GetPrivateProfileString((LPTSTR)szFrostSection,
(LPTSTR)szMagic,
(LPTSTR)szNULL,
(LPTSTR)szMagicTest, MAX_STRLEN,
szMsg);
if (!lstrcmp((LPTSTR)szMagicTest, (LPTSTR)szVerify)) {
//
// now you're convinced that the prev theme file is legit
//
// then use it to set some globals
lstrcpy(szCurThemeFile, szMsg);
// save cur dir (not theme dir)
lstrcpy(szCurDir, szCurThemeFile);
*(FileFromPath(szCurDir)) = 0;
// save theme name
lstrcpy(szCurThemeName, FileFromPath(szCurThemeFile));
TruncateExt(szCurThemeName);
}
}
#endif // REVERT
}
// then look if there is a command line that may override things
if (ProcessCmdLine(lpCmdLine))
return TRUE; // don't run app EXIT, hWndApp==NULL as flag
// Single-instance application can call InitInstance() here
// Return success of inst initialization
return(InitInstance(hPrevInstance, hInstance, nCmdShow));
}
// InitInstance
// Create main window; assign globals for instance and window handles.
//
// Returns: success of initialization
BOOL InitInstance(hPrevInstance, hInstance, nCmdShow)
HINSTANCE hPrevInstance;
HINSTANCE hInstance; /* Current instance identifier. */
int nCmdShow; /* Param for first ShowWindow() call. */
{
RECT rWndApp, rWorkArea;
TCHAR szThemesExe[MAX_PATH];
// assign global instance handle
hInstApp = hInstance;
// create main window and assign global window handle
bNoMem = FALSE; // clear out of mem flag
hWndApp = CreateDialog( hInstApp,
MAKEINTRESOURCE(DLG_MAIN),
(HWND)NULL,
PreviewDlgProc
);
if (!hWndApp || bNoMem) // if problems, then bail
return (FALSE);
InitHTMLBM(); // Init the IThumbnail interface for HTML wallpaper support
// have to init preview painting stuff after create dlg
if (!PreviewInit()) {
DestroyWindow(hWndApp);
return (FALSE); // low mem on dc/bmp create EXIT
}
// this doesn't work from WM_INITDIALOG, so added here, too
InitCheckboxes(); // init stored values
RestoreCheckboxes(); // init actual cbs from stored values
if (bThemed) // kinda kludgy to put here but it works
EnableWindow(GetDlgItem(hWndApp, PB_SAVE), FALSE);
// also, can now make init Preview bmp for init paint
BuildPreviewBitmap((LPTSTR)szCurThemeFile);
// center main window on screen
GetWindowRect(hWndApp, (LPRECT)&rWndApp);
SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)(LPRECT)&rWorkArea, 0);
MoveWindow(hWndApp,
((rWorkArea.right-rWorkArea.left) - (rWndApp.right-rWndApp.left))/2,
((rWorkArea.bottom-rWorkArea.top) - (rWndApp.bottom-rWndApp.top))/2,
// (GetSystemMetrics(SM_CXSCREEN) - (rWndApp.right-rWndApp.left))/2,
// (GetSystemMetrics(SM_CYSCREEN) - (rWndApp.bottom-rWndApp.top))/2,
rWndApp.right-rWndApp.left, rWndApp.bottom-rWndApp.top,
FALSE); // don't repaint
// Make the main window visible; update its client area
ShowWindow(hWndApp, nCmdShow); /* Show the window */
UpdateWindow(hWndApp); /* Sends WM_PAINT message */
// Check to see if CB_SCHEDULE is checked and verify that Task
// Scheduler is running and the Themes task exists as appropriate
if (bCBStates[FC_SCHEDULE]) {
if (IsTaskSchedulerRunning()) {
if (!IsThemesScheduled()) {
GetModuleFileName(hInstApp, (LPTSTR)szThemesExe, MAX_PATH);
if (!AddThemesTask(szThemesExe, TRUE /*Show errors*/)) {
// Couldn't add task -- ATT gave error but need to clear
// SCHEDULE CB
bCBStates[FC_SCHEDULE] = FALSE;
RestoreCheckboxes();
SaveStates(); // Write checkbox states to registry
}
} // Themes.job exists so do nothing
}
else {
// Zonk -- Task Scheduler isn't running. Start it.
if (StartTaskScheduler(TRUE /*prompt user*/)) {
// Task scheduler started -- check if themes task already
// exists
if (!IsThemesScheduled()) {
GetModuleFileName(hInstApp, (LPTSTR)szThemesExe, MAX_PATH);
if (!AddThemesTask(szThemesExe, TRUE /*Show errors*/)) {
// Couldn't add task -- ATT gave error but need to clear
// SCHEDULE CB
bCBStates[FC_SCHEDULE] = FALSE;
RestoreCheckboxes();
SaveStates(); // Write checkbox states to registry
}
} //TS is running now and Themes.job exists
}
else {
// Couldn't start TS -- STS() gave error. Need to clear
// SCHEDULE CB and HandDelete any existing Themes.job.
// CheckDlgButton(hdlg, CB_SCHEDULE, BST_UNCHECKED);
bCBStates[FC_SCHEDULE] = FALSE;
RestoreCheckboxes();
SaveStates(); // Write checkbox states to the registry
HandDeleteThemesTask();
}
} // END ELSE Task Scheduler isn't running
}
else { // bCBStates[FC_CHECKBOX] != TRUE
// SCHEDULE Checkbox is clear -- should delete Themes task.
if (IsTaskSchedulerRunning()) DeleteThemesTask();
else HandDeleteThemesTask();
}
// cleanup
return (TRUE); // success
}
// CloseFrost
//
// Cleanup your objects, thunks, etc.
//
void FAR CloseFrost()
{
// just extra tidy housekeeping
hWndApp = NULL;
hInstApp = NULL;
PreviewDestroy();
}
// SaveStates
//
// Remember persistent states: currently checkboxes.
// Last applied theme is remembered at Apply time.
//
void FAR SaveStates()
{
LONG lret;
HKEY hKey;
int iter;
//
// checkboxes
//
lret = RegOpenKeyEx(HKEY_CURRENT_USER, szPlus_CBs,
(DWORD)0, KEY_SET_VALUE, (PHKEY)&hKey );
if (lret != ERROR_SUCCESS) {
DWORD dwDisposition;
Assert(FALSE, TEXT("couldn't RegOpenKey save checkboxes\n"));
lret = RegCreateKeyEx( HKEY_CURRENT_USER, szPlus_CBs,
(DWORD)0, (LPTSTR)szNULL, REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE, (LPSECURITY_ATTRIBUTES)NULL,
(PHKEY)&hKey, (LPDWORD)&dwDisposition );
}
// if open or create worked
if (lret == ERROR_SUCCESS) {
for (iter = 0; iter < MAX_FCHECKS; iter ++) {
if (bThemed)
RegSetValueEx(hKey, (LPTSTR)szCBNames[iter],
0,
(DWORD)REG_SZ,
(LPBYTE)(IsDlgButtonChecked(hWndApp, iCBIDs[iter]) ?
TEXT("1") : TEXT("0")),
(DWORD)2*sizeof(TCHAR));
else // cur win settings --> real states saved in bCBStates[]
RegSetValueEx(hKey, (LPTSTR)szCBNames[iter],
0,
(DWORD)REG_SZ,
(LPBYTE)(bCBStates[iter] ? TEXT("1") : TEXT("0")),
(DWORD)2*sizeof(TCHAR));
}
// close when finished
RegCloseKey(hKey);
}
else {
Assert(FALSE, TEXT("couldn't open or create Registry save checkboxes\n"));
}
}
BOOL GetRotateTheme(LPTSTR lpszRotateTheme)
{
BOOL bRet = FALSE;
TCHAR szThemesdir[MAX_PATH];
HANDLE hFF;
WIN32_FIND_DATA FindData;
// WARNING -- If "next" .Theme file is not valid theme file we'll never rotate!
// See if there is a current theme.
szThemesdir[0] = TEXT('\0');
bRet = HandGet(HKEY_CURRENT_USER, szPlus_CurTheme,
(LPTSTR)NULL, (LPTSTR)szThemesdir);
// Do we have a current Theme?
hFF = INVALID_HANDLE_VALUE;
if (szThemesdir[0]) {
// Yes we do, so do a FindFirst on it and make sure we've
// got the long filename.
ZeroMemory(&FindData, sizeof(WIN32_FIND_DATA));
hFF = FindFirstFile(szThemesdir, &FindData);
}
// Did we find the file on FindFirst? If so, proceed with finding
// the next Theme in that directory else assume that the registry's
// Current Theme setting is bogus and look in the default dir.
if (INVALID_HANDLE_VALUE != hFF) {
// Copy long filename.
lstrcpy(lpszRotateTheme, FindData.cFileName);
FindClose(hFF);
// We've got the longfilename to the current Theme
// Now do a FF/FN on *.Theme in the Theme dir until
// we find the current theme.
// Strip the theme file off the path.
*(FileFromPath(szThemesdir)) = 0;
lstrcat(szThemesdir, TEXT("*\0"));
LoadString(NULL, STR_THMEXT, (szThemesdir + lstrlen(szThemesdir)),
MAX_PATH);
ZeroMemory(&FindData, sizeof(WIN32_FIND_DATA));
hFF = FindFirstFile(szThemesdir, &FindData);
if (INVALID_HANDLE_VALUE == hFF) {
// We shouldn't hit this since we just found our current
// theme in this directory. If we do, just bail out.
lpszRotateTheme[0] = TEXT('\0');
return FALSE;
}
// Step through the .Theme files in this dir until we find our
// current theme file.
bRet = TRUE;
while (lstrcmp(FindData.cFileName, lpszRotateTheme) && bRet) {
bRet = FindNextFile(hFF, &FindData);
}
if (lstrcmp(FindData.cFileName, lpszRotateTheme)) {
// We ran out of files before finding the current theme!?!?
// Not likely... Bail out.
FindClose(hFF);
lpszRotateTheme[0] = TEXT('\0');
return FALSE;
}
// Assume the FindNext file is our current theme. Let's
// get the Next .Theme file -- that's what we're rotating to...
if (FindNextFile(hFF, &FindData)) {
*(FileFromPath(szThemesdir)) = 0;
lstrcat(szThemesdir, FindData.cFileName);
lstrcpy(lpszRotateTheme, szThemesdir);
FindClose(hFF);
return TRUE;
}
// OK, we failed to find another Theme file in the current dir
// so assume our current Theme is the last in the list. Go
// back to the beginning and use the first Theme file we find
// as our "rotate to" theme.
else {
FindClose(hFF);
ZeroMemory(&FindData, sizeof(WIN32_FIND_DATA));
hFF = FindFirstFile(szThemesdir, &FindData);
if (INVALID_HANDLE_VALUE == hFF) {
// This shouldn't fail since we just found our current
// theme in this dir. If it does, bail out.
lpszRotateTheme[0] = TEXT('\0');
return FALSE;
}
// This is our new/rotate file
*(FileFromPath(szThemesdir)) = 0;
lstrcat(szThemesdir, FindData.cFileName);
lstrcpy (lpszRotateTheme, szThemesdir);
FindClose(hFF);
return TRUE;
}
}
// No current theme applied or the Current Theme setting in the
// registry is bogus so use the global szThemeDir setting and
// look for a theme in that directory.
else {
lstrcpy(szThemesdir, szThemeDir);
lstrcat(szThemesdir, TEXT("*\0"));
LoadString(NULL, STR_THMEXT, (szThemesdir + lstrlen(szThemesdir)),
MAX_PATH);
ZeroMemory(&FindData, sizeof(WIN32_FIND_DATA));
hFF = FindFirstFile(szThemesdir, &FindData);
if (INVALID_HANDLE_VALUE == hFF) {
// Apparently there are no themes available in the default
// Themes directory. We're hosed -- no rotation today.
lpszRotateTheme[0] = TEXT('\0');
return FALSE;
}
// This is our new/rotate file
*(FileFromPath(szThemesdir)) = 0;
lstrcat(szThemesdir, FindData.cFileName);
lstrcpy (lpszRotateTheme, szThemesdir);
FindClose(hFF);
return TRUE;
}
return FALSE;
}