|
|
/* ICONS.C
Resident Code Segment // Tweak: make non-resident?
Initing and painting icons in preview sample
Frosting: Master Theme Selector for Windows '95 Copyright (c) 1994-1998 Microsoft Corporation. All rights reserved. */
// ---------------------------------------------
// Brief file history:
// Alpha:
// Beta:
// Bug fixes
// ---------
#include "windows.h"
#include "stdlib.h"
#include "frost.h"
#include "global.h"
#include "schedule.h" // IsPlatformNT()
#include "nc.h"
extern int FAR WriteBytesToBuffer(LPTSTR);
#define ICONSIZE 32
#define NUM_ICONS 4
#define MYDOC_INDEX 3 // Index to MyDocs icon subkey in fsRoot & fsCUIcons
// Keep in sync with KEYS.H!!
POINT ptIconOrigin[NUM_ICONS]; RECT rLabels[NUM_ICONS]; TCHAR szLabelText[NUM_ICONS][MAX_STRLEN+1];
#define bThemed (*lpszThemeFile)
BOOL FAR PASCAL IconsPreviewInit(void) { int xOrg, iter;
// icons are centered, evenly spaced, in the icon rectangle in the RC file
// you can get x origins of icons from the icon area rect
xOrg = rPreviewIcons.left + (rPreviewIcons.right - rPreviewIcons.left - ICONSIZE) / 2; for (iter = 0; iter < NUM_ICONS; iter++) { ptIconOrigin[iter].x = xOrg; } // y origins depend on font height in theme
// load icon label texts
for (iter = 0; iter < NUM_ICONS; iter++) { LoadString(hInstApp, STR_MYCOMPUTER+iter, (LPTSTR)(szLabelText[iter]), MAX_STRLEN); }
return (TRUE); } void FAR PASCAL IconsPreviewDestroy(void) { }
void FAR PASCAL IconsPreviewDraw(HDC hdcDraw, LPTSTR lpszThemeFile) { UINT uret; ICONMETRICS imTheme; extern TCHAR szMetrics[]; extern TCHAR szIM[]; HFONT hIconFont, hOldFont; HICON hTempIcon; TEXTMETRIC tmLabel; int yLabel, yCushion, yIconSpacing; int iter, iTemp; int index; extern FROST_SUBKEY fsRoot[]; // Win95/Plus95 icon keys
extern FROST_SUBKEY fsCUIcons[]; // Win98/Plus98 icon keys
extern TCHAR c_szSoftwareClassesFmt[]; // WinNT reg path from keys.h
LPTSTR lpszIndex; SIZE sizeText; COLORREF rgbLabel, rgbLabelText, rgbOldText; HBRUSH hbrLabel; TCHAR szNTReg[MAX_PATH]; #ifdef UNICODE
CHAR szTempA[10]; #endif
//
// Inits
//
// Get the icon font; use it to figure y positions of icons and labels;
// setup DC with font; get lable brush/text color.
//
//
// get the icon font
// first get the iconmetrics struct
// if (bThemed && bCBStates[FC_ICONS]) { // icon fonts go with icons cb, not fonts
if (bThemed && bCBStates[FC_FONTS]) { // icon fonts go with _fonts_ now !!!!
uret = (UINT) GetPrivateProfileString((LPTSTR)szMetrics, (LPTSTR)szIM, (LPTSTR)szNULL, (LPTSTR)pValue, MAX_VALUELEN, lpszThemeFile); Assert(uret, TEXT("problem getting stored icon metrics for icon preview draw\n")); // translate stored data string to ICONMETRICS bytes
WriteBytesToBuffer((LPTSTR)pValue); // char str read from and binary bytes
// written to pValue. It's OK.
// get it into global ICONMETRICS struct
#ifdef UNICODE
// ICONMETRICS are stored in ANSI format in the Theme file so we
// need to convert to UNICODE
ConvertIconMetricsToWIDE((LPICONMETRICSA)pValue, (LPICONMETRICSW)&imTheme); #else
// Not UNICODE so no need to convert...
imTheme = *((LPICONMETRICS)pValue); #endif
} else { imTheme.cbSize = sizeof(imTheme); SystemParametersInfo(SPI_GETICONMETRICS, sizeof(imTheme), (void far *)(LPICONMETRICS)&imTheme, FALSE); }
// then create the font
hIconFont = CreateFontIndirect(&imTheme.lfFont);
// and use it in this DC
if (hIconFont) hOldFont = SelectObject(hdcDraw, hIconFont);
//
// now that we have the font, we can get the y origins for the icons
// and the y extremities of the text labels
// figure label height
GetTextMetrics(hdcDraw, &tmLabel); // yLabel = (tmLabel.tmHeight*13)/9; // very good estimate; else try 11/9
yLabel = tmLabel.tmHeight; // no, just text height will do
// and cushion between bottom of icons and their labels
yCushion = (yLabel*4)/13; // pretty good guess
// icons are centered, evenly spaced, in the icon rectangle in the RC file
yIconSpacing = ( rPreviewIcons.bottom - rPreviewIcons.top - NUM_ICONS * (yLabel + yCushion + ICONSIZE) ) / NUM_ICONS; Assert(yIconSpacing > 0, TEXT("neg yIconSpacing implies icon preview rect too short\n")); ptIconOrigin[0].y = rPreviewIcons.top + yIconSpacing/2; for (iter = 1; iter < NUM_ICONS; iter ++) { ptIconOrigin[iter].y = ptIconOrigin[iter-1].y + ICONSIZE + yCushion + yLabel + yIconSpacing; }
// labels are where you now expect them
for (iter = 0; iter < NUM_ICONS; iter ++) { rLabels[iter].top = ptIconOrigin[iter].y + ICONSIZE + yCushion; rLabels[iter].bottom = rLabels[iter].top + yLabel; }
//
// final init involves colors (and brush) for labels and label text
// get desktop background color
if (bThemed && bCBStates[FC_COLORS]) { // getting from selected theme
GetPrivateProfileString((LPTSTR)TEXT("Control Panel\\Colors"), (LPTSTR)TEXT("Background"), (LPTSTR)szNULL, (LPTSTR)szMsg, MAX_MSGLEN, lpszThemeFile); // translate to color
rgbLabel = RGBStringToColor((LPTSTR)szMsg); } else // using cur windows settings
rgbLabel = GetSysColor(COLOR_BACKGROUND);
// then make that the nearest solid color for label background
rgbLabel = GetNearestColor(hdcDraw, rgbLabel);
// now use a HACK HACK HACK HACK brilliant method for getting text color
if ((GetRValue(rgbLabel) > 128) || (GetGValue(rgbLabel) > 128) || (GetBValue(rgbLabel) > 128) ) rgbLabelText = RGB(0,0,0); // black text on lighter label
else rgbLabelText = RGB(255,255,255); // white text on darker label
// and then create the background brush and set the text color
hbrLabel = CreateSolidBrush(rgbLabel); rgbOldText = SetTextColor(hdcDraw, rgbLabelText); SetBkMode(hdcDraw, TRANSPARENT);
//
// now we can get each of the icons and draw them at the right spot
// and while you're at it draw the labels
for (iter = 0; iter < NUM_ICONS; iter ++) {
// first get filename into temp global buffer szMsg
if (bThemed && bCBStates[FC_ICONS]) { // getting from selected theme
GetPrivateProfileString((LPTSTR)fsCUIcons[iter].szSubKey, // SPECIAL UGLY CASE FOR TRASH CAN
(LPTSTR)(iter == 2 ? TEXT("full") : FROST_DEFSTR), (LPTSTR)szNULL, (LPTSTR)szMsg, MAX_MSGLEN, lpszThemeFile);
// If the key is null we might have an "old" Plus95 *.Theme file
// so let's use the Win95 keyname instead
if (!*szMsg) { GetPrivateProfileString((LPTSTR)fsRoot[iter].szSubKey, // SPECIAL UGLY CASE FOR TRASH CAN
(LPTSTR)(iter == 2 ? TEXT("full") : FROST_DEFSTR), (LPTSTR)szNULL, (LPTSTR)szMsg, MAX_MSGLEN, lpszThemeFile); }
// PLUS98 bug 1042
// If this is the MyDocs icon and there is no setting for
// it in the Theme file then we need to default to the
// szMyDocsDefault icon.
if ((MYDOC_INDEX == iter) && (!*szMsg)) { lstrcpy(szMsg, MYDOC_DEFSTR); } // expand filename string as necessary
InstantiatePath((LPTSTR)szMsg, MAX_MSGLEN);
// search for file if necessary, see if found
// ConfirmFile on NULL string returns "CF_EXISTS" so have
// added "|| !*szMsg" case to this conditional to check for it
if ((ConfirmFile((LPTSTR)szMsg, TRUE) == CF_NOTFOUND) || !*szMsg) { // if file not found, nothing applied --> keeps cur sys setting
szMsg[0] = TEXT('\0'); HandGet(HKEY_CURRENT_USER, (LPTSTR)fsCUIcons[iter].szSubKey, // SPECIAL UGLY CASE FOR TRASH CAN
(LPTSTR)(iter == 2 ? TEXT("full") : szNULL), // null gives default string
(LPTSTR)szMsg);
// If we failed to get a string from the CURRENT_USER branch
// go try the CLASSES_ROOT branch instead.
if (!*szMsg) { HandGet(HKEY_CLASSES_ROOT, (LPTSTR)fsRoot[iter].szSubKey, // SPECIAL UGLY CASE FOR TRASH CAN
(LPTSTR)(iter == 2 ? TEXT("full") : szNULL), // null gives default string
(LPTSTR)szMsg); } } } else { // using cur windows settings
// First try getting the icon from the appropriate
// CURRENT_USER branch for this platform
szMsg[0] = TEXT('\0');
if (IsPlatformNT()) {
lstrcpy(szNTReg, c_szSoftwareClassesFmt); lstrcat(szNTReg, fsRoot[iter].szSubKey); HandGet(HKEY_CURRENT_USER, (LPTSTR)szNTReg, // SPECIAL UGLY CASE FOR TRASH CAN
(LPTSTR)(iter == 2 ? TEXT("full") : szNULL), // null gives default string
(LPTSTR)szMsg); } else // not NT
{ HandGet(HKEY_CURRENT_USER, (LPTSTR)fsCUIcons[iter].szSubKey, // SPECIAL UGLY CASE FOR TRASH CAN
(LPTSTR)(iter == 2 ? TEXT("full") : szNULL), // null gives default string
(LPTSTR)szMsg);
} // If we got a NULL string from the CURRENT_USER branch then
// try the CLASSES_ROOT branch instead
if (!*szMsg) { HandGet(HKEY_CLASSES_ROOT, (LPTSTR)fsRoot[iter].szSubKey, // SPECIAL UGLY CASE FOR TRASH CAN
(LPTSTR)(iter == 2 ? TEXT("full") : szNULL), // null gives default string
(LPTSTR)szMsg); } }
// now load the icon; may have index into file. format: "file,index"
lpszIndex = FindChar((LPTSTR)szMsg, TEXT(',')); if (*lpszIndex) { // if found a comma, then indexed icon
#ifdef UNICODE
// latoi doesn't like wide strings -- convert to ANSI before calling
wcstombs(szTempA, CharNext(lpszIndex), sizeof(szTempA)); index = latoi(szTempA); #else
index = latoi(CharNext(lpszIndex)); #endif
*lpszIndex = 0; // got index then null term filename in szMsg
} else { // just straight icon file or no index
index = 0; } // Get proper res ICON from file
ExtractPlusColorIcon(szMsg, index, &hTempIcon, 0, 0);
// draw the icon at the right spot
if (hTempIcon) DrawIconEx(hdcDraw, ptIconOrigin[iter].x, ptIconOrigin[iter].y, hTempIcon, ICONSIZE, ICONSIZE, 0, NULL, DI_NORMAL);
// figure the label width for the font and text string
GetTextExtentPoint32(hdcDraw, (LPTSTR)(szLabelText[iter]), lstrlen((LPTSTR)(szLabelText[iter])), (LPSIZE)&sizeText); iTemp = (rPreviewIcons.right - rPreviewIcons.left - (int)(sizeText.cx)) / 2; rLabels[iter].left = rPreviewIcons.left + iTemp - (yLabel*3)/13; // very good estimate
rLabels[iter].right = rPreviewIcons.right - iTemp + (yLabel*3)/13; // very good estimate
// draw label background in solid color version of dt bkgd color
FillRect(hdcDraw, (LPRECT)&(rLabels[iter]), hbrLabel);
// draw actual text string there, too
DrawText(hdcDraw, (LPTSTR)(szLabelText[iter]), lstrlen((LPTSTR)(szLabelText[iter])), (LPRECT)&(rLabels[iter]), DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_SINGLELINE );
// individual icon draw Cleanup
if (hTempIcon) DestroyIcon(hTempIcon); }
//
// cleanup
if (hbrLabel) DeleteObject(hbrLabel); if (rgbOldText != CLR_INVALID) SetTextColor(hdcDraw, rgbOldText); if (hIconFont) { SelectObject(hdcDraw, hOldFont); DeleteObject(hIconFont); }
}
|