/* 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; }