/* BKGD.C
   Resident Code Segment      // Tweak: make non-resident?

   Most of this code is taken from the display CPLs adjusted to
   work with the Theme Switcher and cleaned up a little.

   Routines for painting the preview box in the main window
      Desktop (wallpaper/pattern/color)
      Icons
      Windows

   Frosting: Master Theme Selector for Windows '95
   Copyright (c) 1994-1998 Microsoft Corporation
*/

// ---------------------------------------------
// Brief file history:
// Alpha:
// Beta:
// Bug fixes
// ---------

#include "windows.h"
#include "frost.h"
#include "global.h"
#include "adutil.h"

#include "bkgd.h"
#include "LoadImag.h"
#include "htmlprev.h"
#include "schedule.h"  // IsPlatormNT and GetCurrentUser

// #define BMPOUT 333         // debugging aid
#ifdef BMPOUT
#define BmpOut(x,y,z);    hbmDebOld=SelectObject(hdcDeb,x);BitBlt(hdcOut,0,0,y,z,hdcDeb,0,0,SRCCOPY);SelectObject(hdcDeb,hbmDebOld);
#define PrevOut();    BitBlt(hdcOut,0,0,dxPreview,dyPreview,g_hdcMem,0,0,SRCCOPY);
#endif

// globals
extern BOOL bInGrphFilter;   // frost.c Currently in a graphics filter?
TCHAR szCP_DT[]    = TEXT("Control Panel\\Desktop");
TCHAR szWP[]       = TEXT("Wallpaper");
TCHAR szTileWP[]   = TEXT("TileWallpaper");
extern TCHAR szWPStyle[];
TCHAR szPat[]      = TEXT("Pattern");
extern TCHAR szSS_Active[];

extern HPALETTE hpal3D;         // fakewin.c

HBITMAP  g_hbmPreview = NULL;	// the bitmap used for previewing
HDC      g_hdcMem = NULL;

HBITMAP  g_hbmWall = NULL;      // bitmap image of wallpaper
HDC      g_hdcWall = NULL;      // memory DC with g_hbmWall selected
HPALETTE g_hpalWall = NULL;     // palette that goes with hbmWall bitmap
HBRUSH   g_hbrBack = NULL;      // brush for the desktop background

HBITMAP g_hbmDefault = NULL;
DWORD dwStyle = 0;              // WP Style for new ActiveDesktop interface

// L o c a l   R o u t i n e s
COLORREF GetThemeColor(LPTSTR, int);

extern TCHAR szFrostSection[];
extern TCHAR szThemeBPP[];
extern TCHAR szImageBPP[];
       TCHAR szImageDither[] = TEXT("Dither");
       TCHAR szImageStretch[] = TEXT("Stretch");
       TCHAR szPlusKey[] = TEXT("Software\\Microsoft\\Plus!\\Themes");

//
// if the theme is 8bpp only load 8bpp images (bpp=8)
// otherwise load the best for the display (bpp=-1)
//
// currently this is kind of bogus, we should mark the 8bit themes
// as 8bit not the other way around!
//
// return
//      -1      load the image at the depth of the display
//      8       load the image at 8bpp
//
int GetImageBPP(LPCTSTR lpszThemeFile)
{
    int bpp = -1;

    if (*lpszThemeFile && bCBStates[FC_WALL]) {

        bpp = GetPrivateProfileInt(szFrostSection, szImageBPP, -1, lpszThemeFile);

        if (bpp != 8)
            bpp = -1;
    }

    return bpp;
}

//
//
// When applying wallpaper (if decompressed from a .jpg), first check:
// are user profiles enabled?
// HKLM\Network\Logon, UserProfiles=<dword> will be non-zero if
// profiles are enabled.
//
// then
// Call WNetGetUser to get the username
// then look under:
// HKLM\Software\Microsoft\Windows\CurrentVersion\ProfileList\<username>
//  there should be a value ProfileImagePath which is the local path.
//
//then store Plus!.bmp there

void GetPlusBitmapName(LPTSTR szPlus)
{
    HKEY hkey;
    DWORD dw;
    UINT cb;
    TCHAR key[80];
    TCHAR ach[80];

    if (!GetWindowsDirectory(szPlus, MAX_PATH))
    {
        szPlus[0] = 0;
    }

    if (IsPlatformNT())
    {
       // User profiles are always enabled un NT so find the correct
       // path
       TCHAR szAccount[MAX_PATH];
       TCHAR szDomain[MAX_PATH];

       GetCurrentUser(szAccount, ARRAYSIZE(szAccount),
                      szDomain, ARRAYSIZE(szDomain),
                      szPlus, MAX_PATH);

       InstantiatePath(szPlus, ARRAYSIZE(szPlus));
       Assert(FALSE, TEXT("Plus!.BMP path: "));
       Assert(FALSE, szPlus);
       Assert(FALSE, TEXT("\n"));
    }
    else if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Network\\Logon"), &hkey) == 0)
    {
        cb = sizeof(dw); dw = 0;
        RegQueryValueEx(hkey, TEXT("UserProfiles"), NULL, NULL, (LPVOID)&dw, &cb);
        RegCloseKey(hkey);

        if (dw != 0)
        {
            cb = ARRAYSIZE(ach); ach[0] = 0;
            WNetGetUser(NULL, ach, &cb);

            if (ach[0])
            {
                wsprintf(key, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\ProfileList\\%s"), ach);
                if (RegOpenKey(HKEY_LOCAL_MACHINE, key, &hkey) == 0)
                {
                    cb = sizeof(ach); ach[0] = 0;
                    RegQueryValueEx(hkey, TEXT("ProfileImagePath"), NULL, NULL, (LPBYTE)ach, &cb);
                    RegCloseKey(hkey);

                    if (ach[0] && GetFileAttributes(ach) != -1)
                    {
                        lstrcpy(szPlus, ach);
                        Assert(FALSE, TEXT("Plus!.BMP path: "));
                        Assert(FALSE, szPlus);
                        Assert(FALSE, TEXT("\n"));
                    }
                }
            }
        }
    }

    lstrcat(szPlus, TEXT("\\Plus!.bmp"));
}

//
//  LoadWallpaper
//
HBITMAP LoadWallpaper(LPTSTR szWallpaper, LPTSTR szThemeFile, BOOL fPreview)
{
    HBITMAP hbm=NULL;
    TCHAR plus_bmp[MAX_PATH];  //DSCHOTT switched from 128 to MAX_PATH
    TCHAR ach[MAX_PATH];       //DSCHOTT switched from 128 to MAX_PATH
    int dx, dy;
    DWORD dw;
    int bpp    = GetImageBPP(szThemeFile);
    int dither = DITHER_CUSTOM;
    int tile   = GetRegInt(HKEY_CURRENT_USER, szCP_DT, szTileWP, 0);
    int stretch= GetRegInt(HKEY_CURRENT_USER, szCP_DT, szWPStyle, 0) & 2;

    // If a theme is selected, and we are using a plus wall paper then
    // find out if tiling is on, and what style to use from the ini file.
    // Otherwise, we already got the information from the registry.
    if (szThemeFile && *szThemeFile && bCBStates[FC_WALL])
    {
        tile   = GetPrivateProfileInt(szCP_DT, szTileWP, tile, szThemeFile);
        stretch= GetPrivateProfileInt(szCP_DT, szWPStyle, stretch, szThemeFile) & 2;
        dither = GetPrivateProfileInt(szFrostSection, szImageDither, dither, szThemeFile);
        stretch= GetPrivateProfileInt(szFrostSection, szImageStretch, stretch, szThemeFile);
    }

    //
    // allow the user to override theme switches
    //
    bpp    = GetRegInt(HKEY_CURRENT_USER, szPlusKey, szImageBPP, bpp);
    dither = GetRegInt(HKEY_CURRENT_USER, szPlusKey, szImageDither, dither);

    // First try getting this stretch value from IActiveDesktop if
    // it's on.
    if (IsActiveDesktopOn()) {
       if (GetADWPOptions(&dw)) if (WPSTYLE_STRETCH == dw) stretch = 1;
    }
    // AD is off so get the Stretch value from the registry
    else stretch= GetRegInt(HKEY_CURRENT_USER, szPlusKey,
                                           szImageStretch, stretch);


    // If our wallpaper is an HTML page we need to force stretching
    // on and tiling off

    if (szWallpaper && ((lstrcmpi(FindExtension(szWallpaper),TEXT(".htm")) == 0) ||
                        (lstrcmpi(FindExtension(szWallpaper),TEXT(".html")) == 0)))
    {
       tile = 0;
       stretch = 1;
    }

    //
    // if the stretch wallpaper option is set (style & 2) then load the
    // wallpaper the size of our preview window, else we need to load the
    // wallpaper in the right proportion (passing a <0 size to
    // LoadImageFromFile will cause it to stretch it)
    //

    if (!tile && stretch)
    {
        dx  = fPreview ? dxPreview : GetSystemMetrics(SM_CXSCREEN);
        dy  = fPreview ? dyPreview : GetSystemMetrics(SM_CYSCREEN);
    }
    else
    {
        dx = fPreview ? -dxPreview : 0;
        dy = fPreview ? -dyPreview : 0;
    }

    // Build a full path to the plus!.bmp file
    GetPlusBitmapName(plus_bmp);
    ach[0] = 0;
    dw = GetImageTitle(plus_bmp, ach, sizeof(ach));

    //
    // see if we can use Plus!.bmp
    //
    if (ach[0] && lstrcmpi(ach, szWallpaper) == 0 && (dx==0 || (int)dw==MAKELONG(dx,dy)))
    {
        szWallpaper = plus_bmp;
    }
    return CacheLoadImageFromFile(szWallpaper, dx, dy, bpp, dither);
}

// PaintPreview
//
// This is the routine that draws the entire preview area: the
// background image, three icons, and the sample window preview.
// The sample window is drawn with MS-supplied code.
//
void FAR PaintPreview(HWND hDlg, HDC hdc, PRECT prect)
{
   HBITMAP hbmOld;

   //
   // inits
   //
   hbmOld = SelectObject(g_hdcMem, g_hbmPreview);
   if (g_hpalWall)
   {
       SelectPalette(hdc, g_hpalWall, FALSE);
       RealizePalette(hdc);
   }

   //
   // painting: assume clip rect set correctly already
   BitBlt(hdc, rView.left, rView.top, dxPreview, dyPreview, g_hdcMem, 0, 0, SRCCOPY);

   //
   // cleanup
   if (g_hpalWall)
      SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), TRUE);
   SelectObject(g_hdcMem, hbmOld);
}


/*--------------------------------------------------------------------
** Build the preview bitmap.

   Gets the settings from the current theme file and inits
   a preview bitmap for later painting.

   Start with the pattern or wallpaper or bkgd color.
   Add the icons and then the sample windows.

   Started with control panel code and did a lot of customization,
   including more comments, especially where made additions.
   Uses settings either from cur theme file, or if that is null
   then from system settings (i.e. for Cur Win Settings).

   Not as robust as I'd like, but seems to be acceptable for CPL.
   Tried to speed some things up, since this gets called on each
   combo box selection.

**--------------------------------------------------------------------*/

// virtual boolean: null theme name means Cur Win Settings, not from theme file
#define bThemed (*lpszThemeFile)


void FAR PASCAL BuildPreviewBitmap(LPTSTR lpszThemeFile)
{
   UINT uret;
   UINT style;
   UINT tile;
   HBRUSH hbr = NULL;
   HBITMAP hbmTemp;
   HBITMAP hbmOld;
   BITMAP bm;
   COLORREF clrOldBk, clrOldText;
   WORD patbits[CXYDESKPATTERN] = {0, 0, 0, 0, 0, 0, 0, 0};
   int     i;
   int     dxWall;          // size of wallpaper
   int     dyWall;

   #ifdef BMPOUT
   HDC hdcOut;
   HDC hdcDeb;
   HBITMAP hbmDebOld;

   hdcOut = GetDC(NULL);
   hdcDeb = CreateCompatibleDC(hdcOut);
   #endif

   Assert(FALSE, TEXT("Building Preview bitmap: "));
   Assert(FALSE, szCurThemeName);
   Assert(FALSE, TEXT("\n"));

   hbmOld = SelectObject(g_hdcMem, g_hbmPreview);

   /*
   ** first, fill in the pattern all over the bitmap
   */

	// get rid of old brush if there was one
   if (g_hbrBack)
	   DeleteObject(g_hbrBack);
   g_hbrBack = NULL;

   // get pattern from current theme file
   if (bThemed && bCBStates[FC_WALL]) {    // theme file and checkbox
      uret = (UINT) GetPrivateProfileString((LPTSTR)szCP_DT, (LPTSTR)szPat,
                                          (LPTSTR)szNULL,
                                          (LPTSTR)pValue, MAX_VALUELEN,
                                          lpszThemeFile);
      Assert(uret, TEXT("problem getting stored pattern for preview bmp\n"));
   }
   // or, from the system
   else {            // cur system settings
      // If ActiveDesktop is enabled we'll get the current settings
      // from the IActiveDesktop interface otherwise we'll do it
      // the "old" way by reading directly from the registry.
      if (IsActiveDesktopOn()) {
         if (!GetADWPPattern(pValue)) {
            // Failed to get pattern so invalidate the pattern
            // by making string look like (None).
            pValue[0] = TEXT('(');
         }
      }
      else {
         // No AD so do it the old way.
         GetRegString(HKEY_CURRENT_USER, szCP_DT, szPat,
                                   szNULL, pValue, (MAX_VALUELEN * sizeof(TCHAR)));
      }
   }

   // if you got a pattern, use it
        if (*pValue && (pValue[0] != TEXT('(')))  // INTERNATIONAL? null or (None) cases
                     // 5/95: "(None)" no longer written to registry by Win95
	{
      TranslatePattern(pValue, patbits);	
	   hbmTemp = CreateBitmap(8, 8, 1, 1, patbits);
	   if (hbmTemp)
	   {
         #ifdef BMPOUT
         BmpOut(hbmTemp,8,8);
         #endif

		   g_hbrBack = CreatePatternBrush(hbmTemp);
		   DeleteObject(hbmTemp);
	   }
	}
	else              // no pattern, so make a background brush
	{
      if (bThemed && bCBStates[FC_COLORS])   // theme file and checkbox
   	   g_hbrBack = CreateSolidBrush(GetThemeColor(lpszThemeFile, COLOR_BACKGROUND));
      else           // cur system settings
   	   g_hbrBack = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));
	}
	if (!g_hbrBack)
	   g_hbrBack = GetStockObject(BLACK_BRUSH);

   //
   // now do the actual pattern painting
   if (bThemed && bCBStates[FC_COLORS]) {    // theme file and checkbox
      clrOldText = SetTextColor(g_hdcMem, GetThemeColor(lpszThemeFile, COLOR_BACKGROUND));
      clrOldBk = SetBkColor(g_hdcMem, GetThemeColor(lpszThemeFile, COLOR_WINDOWTEXT));
   }
   else {            // cur system settings
      clrOldText = SetTextColor(g_hdcMem, GetSysColor(COLOR_BACKGROUND));
      clrOldBk = SetBkColor(g_hdcMem, GetSysColor(COLOR_WINDOWTEXT));
   }
   hbr = SelectObject(g_hdcMem, g_hbrBack);
   PatBlt(g_hdcMem, 0, 0, dxPreview, dyPreview, PATCOPY);
   SelectObject(g_hdcMem, hbr);

   #ifdef BMPOUT
   BmpOut(g_hbmPreview,dxPreview,dyPreview);
   PrevOut();
   #endif

   SetTextColor(g_hdcMem, clrOldText);
   SetBkColor(g_hdcMem, clrOldBk);

   /*
   ** now, position the wallpaper appropriately
   */

   // get rid of old wallpaper if there is any
   if (g_hbmWall)
   {
       SelectObject(g_hdcWall, g_hbmDefault);
       CacheDeleteBitmap(g_hbmWall);
       g_hbmWall = NULL;

       if (g_hpalWall)
       {
            if (g_hpalWall != hpal3D)
                DeleteObject(g_hpalWall);
            g_hpalWall = NULL;
       }
   }

   // call this early so hpal3D get setup (we will need it
   // to build the preview bitmap)
   FakewinSetTheme(lpszThemeFile);

   // get wallpaper bitmap from current theme file
   if (bThemed && bCBStates[FC_WALL]) {    // theme file and checkbox
      uret = (UINT) GetPrivateProfileString((LPTSTR)szCP_DT, (LPTSTR)szWP,
                                          (LPTSTR)szNULL,
                                          (LPTSTR)pValue, MAX_VALUELEN,
                                          lpszThemeFile);
//      Assert(uret, TEXT("problem getting stored wallpaper file for preview bmp\n"));
      InstantiatePath((LPTSTR)pValue, MAX_VALUELEN);
      // search for file if necessary, see if found
      if (ConfirmFile((LPTSTR)pValue, TRUE) == CF_NOTFOUND) {
         GetRegString(HKEY_CURRENT_USER, szCP_DT, szWP, NULL, pValue, (MAX_VALUELEN * sizeof(TCHAR)));
      }
   }
   // or, from the system
   else {            // cur system settings
      // If ActiveDesktop is enabled we'll get the current settings
      // from the IActiveDesktop interface otherwise we'll do it
      // the "old" way by reading directly from the registry.
      if (IsActiveDesktopOn()) {
         if (!GetADWallpaper(pValue)) {
            // Failed to get Wallpaper so invalidate the Wallpaper
            pValue[0] = TEXT('\0');
         }
      }
      else {
         // No AD so do it the old way.
         GetRegString(HKEY_CURRENT_USER, szCP_DT, szWP, NULL,
                                                  pValue, (MAX_VALUELEN * sizeof(TCHAR)));
      }
   }

   // If ActiveDesktop is on get the Wallpaper options (Tile/Stretch/Center)
   // from the AD interface.  Otherwise read directly from the registry.
   tile = 0;
   style = 0;
   if (IsActiveDesktopOn()) {
      if (GetADWPOptions(&dwStyle)) {
         if (WPSTYLE_TILE == dwStyle) tile = 1;
         if (WPSTYLE_STRETCH == dwStyle) style = 2;  // 2 means stretch
         // Don't care about center apparently.
      }
   }
   else {
   // AD is not on so get this information from the registry.
      tile  = GetRegInt(HKEY_CURRENT_USER, szCP_DT, szTileWP, 0);
      style = GetRegInt(HKEY_CURRENT_USER, szCP_DT, szWPStyle, 0);
   }

   // check tile flag, get information from theme file
   if (bThemed && bCBStates[FC_WALL]) {    // theme file and checkbox
      tile  = GetPrivateProfileInt(szCP_DT, szTileWP, tile, lpszThemeFile);
      style = GetPrivateProfileInt(szCP_DT, szWPStyle, style, lpszThemeFile);
   }

   if (*pValue && (pValue[0] != TEXT('(')))
        // PLUS98 BUG 1093
        // Don't call into the graphics filter if we're currently in the
        // graphics filter.  Doing so will fault.
        if (!bInGrphFilter) {
           EnableWindow(GetDlgItem(hWndApp, DDL_THEME), FALSE);
           bInGrphFilter = TRUE;
           g_hbmWall = LoadWallpaper(pValue, lpszThemeFile, TRUE);
           bInGrphFilter = FALSE;
           EnableWindow(GetDlgItem(hWndApp, DDL_THEME), TRUE);
           SetFocus(hWndApp);
           SendMessage(hWndApp, DM_SETDEFID, IDOK, 0);
        }

   if (g_hbmWall) {
      SelectObject(g_hdcWall, g_hbmWall); // bitmap stays in this DC
      GetObject(g_hbmWall, sizeof(bm), &bm);
   }

   // get palette if appropriate
   if (GetDeviceCaps(g_hdcMem, RASTERCAPS) & RC_PALETTE) {
      DWORD adw[256+20+1];
      int n=0;

      if (g_hbmWall) {
        g_hpalWall = PaletteFromDS(g_hdcWall);

        // use the Halftone palette if the bitmap does not have one.
        if (g_hpalWall == NULL && bm.bmBitsPixel >= 8)
            g_hpalWall = CreateHalftonePalette(g_hdcMem);

        // now merge the 3D palette and the wallpaper palette.
        // we want the 3D (ie button shadow colors) to be first
        // and the wallpaper colors to be next.
        Assert(g_hpalWall, TEXT("null palette for bmp\n"));
        Assert(GetObject(hpal3D, sizeof(n), &n) && n==20, TEXT("hpal3D not valid or does not have 20 colors\n"));

        GetObject(g_hpalWall, sizeof(n), &n);
        GetPaletteEntries(hpal3D,     0, 20,  (LPPALETTEENTRY)&adw[1]);
        GetPaletteEntries(g_hpalWall, 0, n, (LPPALETTEENTRY)&adw[21]);
        adw[0] = MAKELONG(0x0300, n+20);

        DeleteObject(g_hpalWall); // we dont need this anymore
        g_hpalWall = CreatePalette((LPLOGPALETTE)adw);
        Assert(g_hpalWall, TEXT("CreatePalette failed\n"));
      }
      else {
        g_hpalWall = hpal3D;
      }
   }

   if (g_hpalWall)
   {
       //make sure to select into a windowDC first
       //so a WM_PALETTECHANGE happens.
       HDC hdc = GetDC(hWndApp);
       SelectPalette(hdc, g_hpalWall, FALSE);
       RealizePalette(hdc);
       ReleaseDC(hWndApp, hdc);
       SelectPalette(g_hdcMem, g_hpalWall, FALSE);
       RealizePalette(g_hdcMem);
   }

   // do the painting
   if (g_hbmWall)
   {
      GetObject(g_hbmWall, sizeof(bm), &bm);

//    dxWall = MulDiv(bm.bmWidth, dxPreview, GetDeviceCaps(g_hdcMem, HORZRES));
//    dyWall = MulDiv(bm.bmHeight, dyPreview, GetDeviceCaps(g_hdcMem, VERTRES));

      dxWall = bm.bmWidth;
      dyWall = bm.bmHeight;

      if (dxWall < 1) dxWall = 1;
      if (dyWall < 1) dyWall = 1;

      IntersectClipRect(g_hdcMem, 0, 0, dxPreview, dyPreview);
      SetStretchBltMode(g_hdcMem, COLORONCOLOR);

      if (tile)                     // TRUE for tile flag set
      {
         StretchBlt(g_hdcMem, 0, 0, dxWall, dyWall,
                    g_hdcWall, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);

         for (i = dxWall; i < dxPreview; i+= dxWall)
               BitBlt(g_hdcMem, i, 0, dxWall, dyWall, g_hdcMem, 0, 0, SRCCOPY);

         for (i = 0; i < dyPreview; i += dyWall)
               BitBlt(g_hdcMem, 0, i, dxPreview, dyWall, g_hdcMem, 0, 0, SRCCOPY);
      }
      else if (style & 2)
      {
         StretchBlt(g_hdcMem, 0, 0, dxPreview, dyPreview,
                  g_hdcWall, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
      }
      else
      {
         StretchBlt(g_hdcMem, (dxPreview - dxWall)/2, (dyPreview - dyWall)/2,
                  dxWall, dyWall, g_hdcWall, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
      }

      #ifdef BMPOUT
      BmpOut(g_hbmPreview,dxPreview,dyPreview);
      PrevOut();
      #endif

      // restore dc
      SelectObject(g_hdcWall, g_hbmDefault);
      SelectPalette(g_hdcMem, GetStockObject(DEFAULT_PALETTE), TRUE);
      SelectClipRgn(g_hdcMem, NULL);
   }

   //
   // Now you can add the windows and icons on top of the background
   //

   // icons first
   IconsPreviewDraw(g_hdcMem, lpszThemeFile);

   // sample windows
// FakewinSetTheme(lpszThemeFile);
   FakewinDraw(g_hdcMem);

   //
   // final cleanup
   SelectObject(g_hdcMem, hbmOld);

   // force repaint of preview area
   InvalidateRect(hWndApp, (LPRECT)&rView, FALSE);

   #ifdef BMPOUT
   DeleteDC(hdcDeb);
   ReleaseDC(NULL, hdcOut);
   #endif
}



//
// GetThemeColor
//
// Utility routine that gets a color from the theme.
//

TCHAR szBkgdKey[] = TEXT("Background");
TCHAR szTextKey[] = TEXT("WindowText");

COLORREF GetThemeColor(LPTSTR lpszTheme, int iColorIndex)
{
   COLORREF crRet;
   UINT uret;

   switch (iColorIndex) {
   case COLOR_BACKGROUND:
      uret = (UINT) GetPrivateProfileString((LPTSTR)szColorApp, (LPTSTR)szBkgdKey,
                                            (LPTSTR)szNULL,
                                            (LPTSTR)pValue, MAX_VALUELEN,
                                            lpszTheme);
      Assert(uret, TEXT("problem getting stored theme bkgd color\n"));
      break;
   case COLOR_WINDOWTEXT:
      uret = (UINT) GetPrivateProfileString((LPTSTR)szColorApp, (LPTSTR)szTextKey,
                                            (LPTSTR)szNULL,
                                            (LPTSTR)pValue, MAX_VALUELEN,
                                            lpszTheme);
      Assert(uret, TEXT("problem getting stored theme wintext color\n"));
      break;
   default:
      Assert(0, TEXT("unexpected color request in GetThemeColor()\n"));
      break;
   }

   if (*pValue)
      crRet = RGBStringToColor((LPTSTR)pValue);
   else
      crRet = RGB(0,0,0);

   return (crRet);
}