windows-nt/Source/XPSP1/NT/shell/osshell/control/scrnsave/mystify/ssmyst.c
2020-09-26 16:20:57 +08:00

883 lines
31 KiB
C

/* MYSTIFY.C
**
** Copyright (C) Microsoft, 1991, All Rights Reserved.
**
** Screensaver Control Panel Applet. This type creates one or two polygons
** which bounce around the screen.
**
** History:
** 6/17/91 stevecat ported to NT Windows
** 2/10/92 stevecat snapped to latest ported to NT Windows
*/
#define OEMRESOURCE
#include <windows.h>
#include <commctrl.h>
#include <scrnsave.h>
#include "mystify.dlg"
#include "strings.h"
#include "uniconv.h"
// void SetFields (HWND, WORD);
DWORD AdjustColor (DWORD dwSrc, DWORD dwDest, int nInc, int nCnt);
LONG AppOwnerDraw (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
WORD AtoI (LPTSTR lpszConvert);
BOOL DrawBitmap (HDC hdc, int x, int y, HBITMAP hbm, DWORD rop);
VOID DrawPolygon (HDC hDC, HPEN hPen, WORD wPolygon, WORD wLine);
VOID FillR (HDC hdc, LPRECT prc, DWORD rgb);
VOID FrameR (HDC hdc, LPRECT prc, DWORD rgb, int iFrame);
DWORD GenerateColor (VOID);
WORD GenerateVelocity (VOID);
VOID GetFields (VOID);
DWORD GetProfileRgb (LPTSTR szApp, LPTSTR szItem, DWORD rgb);
VOID PatB (HDC hdc, int x, int y, int dx, int dy, DWORD rgb);
WORD rand (VOID);
VOID ShadeWindows (HWND hDlg, WORD wPoly, WORD wPolygon);
VOID srand (DWORD dwSeed);
#define RAND(x) ((rand () % (x))+1)
#define ZRAND(x) (rand () % (x))
#define rgbBlack RGB (0,0,0)
#define rgbWhite RGB (255,255,255)
#define rgbGrey RGB (128,128,128)
#define rgbMenu GetSysColor (COLOR_MENU)
#define rgbMenuText GetSysColor (COLOR_MENUTEXT)
#define BUFFER_SIZE 20
#define BUFFER2_SIZE 20
#define NUMBER_POLYGONS 2
#define MAXXVEL 12
#define MAXYVEL 12
#define MAXLINES 15
#define NUMLINES 8
TCHAR szClearName[] = TEXT("Clear Screen"); // ClearScreen .INI key
DWORD dwRand = 1L; // current Random seed
TCHAR szBuffer[BUFFER_SIZE]; // temp buffer
TCHAR szBuffer2[BUFFER2_SIZE]; // temp buffer
BOOL fOn[NUMBER_POLYGONS]; // flag for Active status of polygon
BOOL fWalk[NUMBER_POLYGONS]; // color usage for each polygon
WORD wLines[NUMBER_POLYGONS]; // number of lines for each polygon
WORD wNumDisplay[2];
WORD wFreeEntry[NUMBER_POLYGONS]; // colors for each polygon
DWORD dwStartColor[NUMBER_POLYGONS];
DWORD dwEndColor[NUMBER_POLYGONS];
DWORD dwCurrentColor[NUMBER_POLYGONS];
DWORD dwDestColor[NUMBER_POLYGONS];
DWORD dwSrcColor[NUMBER_POLYGONS];
WORD wIncColor[NUMBER_POLYGONS];
WORD wCurInc[NUMBER_POLYGONS];
TCHAR cblogpalPal[(MAXLINES*NUMBER_POLYGONS+1)
*sizeof (PALETTEENTRY)+sizeof (LOGPALETTE)];
POINT ptBox[MAXLINES*NUMBER_POLYGONS][4]; // array for points used in polygons
LPLOGPALETTE lplogpalPal;
LPPALETTEENTRY lppePal;
HPALETTE hPalette;
BOOL fClearScreen; // Global flag for ClearScreen state
//
// Help IDs
//
DWORD aMystDlgHelpIds[] = {
((DWORD) -1),((DWORD) -1),
ID_SHAPE_LABEL, IDH_DISPLAY_SCREENSAVER_MYSTIFY_SHAPE,
ID_SHAPE, IDH_DISPLAY_SCREENSAVER_MYSTIFY_SHAPE,
ID_ACTIVE, IDH_DISPLAY_SCREENSAVER_MYSTIFY_ACTIVE,
ID_LINES_LABEL, IDH_DISPLAY_SCREENSAVER_MYSTIFY_LINES,
ID_LINES, IDH_DISPLAY_SCREENSAVER_MYSTIFY_LINES,
ID_LINESARROW, IDH_DISPLAY_SCREENSAVER_MYSTIFY_LINES,
ID_COLORGROUP, ((DWORD) -1),
ID_2COLORS, IDH_DISPLAY_SCREENSAVER_MYSTIFY_TWO_COLORS,
ID_COLOR1, IDH_DISPLAY_SCREENSAVER_MYSTIFY_TWO_COLORS,
ID_COLOR2, IDH_DISPLAY_SCREENSAVER_MYSTIFY_TWO_COLORS,
ID_RANDOMCOLORS, IDH_DISPLAY_SCREENSAVER_MYSTIFY_RANDOM_COLORS,
ID_CLEARSCREEN, IDH_DISPLAY_SCREENSAVER_MYSTIFY_CLEAR_SCREEN,
0,0
};
LRESULT ScreenSaverProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static POINT ptChange[MAXLINES*NUMBER_POLYGONS][4];
static UINT_PTR wTimer;
WORD wLoop1;
WORD wLoop2;
WORD wMainLoop;
static WORD wScreenX;
static WORD wScreenY;
HPEN hPen;
static HPEN hErasePen;
HDC hDC;
HPALETTE hOldPal;
switch (message)
{
// Things to do while setting up the window...
case WM_CREATE:
GetFields ();
wTimer = SetTimer (hWnd, 1, 10, NULL);
// Make sure we use the entire virtual desktop size for multiple
// displays
wScreenX = (WORD) ((LPCREATESTRUCT)lParam)->cx;
wScreenY = (WORD) ((LPCREATESTRUCT)lParam)->cy;
srand (GetCurrentTime ());
for (wMainLoop = 0; wMainLoop < NUMBER_POLYGONS; wMainLoop++)
{
if (fOn[wMainLoop])
{
for (wLoop1 = 0; wLoop1 < 4; wLoop1++)
{
ptBox[wMainLoop*MAXLINES][wLoop1].x = RAND (wScreenX) - 1;
ptBox[wMainLoop*MAXLINES][wLoop1].y = RAND (wScreenY) - 1;
if ((ptChange[wMainLoop*MAXLINES][wLoop1].x =
RAND (MAXXVEL * 2)) > MAXXVEL)
ptChange[wMainLoop*MAXLINES][wLoop1].x =
-(ptChange[wMainLoop*MAXLINES][wLoop1].x
-MAXXVEL);
if ((ptChange[wMainLoop*MAXLINES][wLoop1].y =
RAND (MAXYVEL * 2)) > MAXYVEL)
ptChange[wMainLoop*MAXLINES][wLoop1].y =
-(ptChange[wMainLoop*MAXLINES][wLoop1].y
-MAXYVEL);
}
wNumDisplay[wMainLoop] = 1;
wFreeEntry[wMainLoop] = 0;
wCurInc[wMainLoop] = 0;
wIncColor[wMainLoop] = 0;
if (fWalk[wMainLoop])
dwDestColor[wMainLoop] = GenerateColor ();
else
dwDestColor[wMainLoop] = dwStartColor[wMainLoop];
}
}
lppePal = (LPPALETTEENTRY)(cblogpalPal + 4);
lplogpalPal = (LPLOGPALETTE)cblogpalPal;
lplogpalPal->palVersion = 0x300;
lplogpalPal->palNumEntries = MAXLINES * NUMBER_POLYGONS + 1;
for (wLoop1 = 0; wLoop1 <= MAXLINES * NUMBER_POLYGONS; wLoop1++)
{
lplogpalPal->palPalEntry[wLoop1].peRed = 0;
lplogpalPal->palPalEntry[wLoop1].peGreen = 0;
lplogpalPal->palPalEntry[wLoop1].peBlue = 0;
lplogpalPal->palPalEntry[wLoop1].peFlags = PC_RESERVED;
}
hErasePen = CreatePen (PS_SOLID, 1,
PALETTEINDEX (MAXLINES * NUMBER_POLYGONS));
hPalette = CreatePalette (lplogpalPal);
break;
case WM_SIZE:
wScreenX = LOWORD(lParam);
wScreenY = HIWORD(lParam);
break;
case WM_ERASEBKGND:
if (fClearScreen)
break;
return 0l;
case WM_TIMER:
// Get the display context...
hDC = GetDC (hWnd);
if (hDC != NULL)
{
// Now that we have changed the palette, make sure that it
// gets updated by first unrealizing, and then realizing...
hOldPal = SelectPalette (hDC, hPalette, 0);
RealizePalette (hDC);
for (wMainLoop = 0; wMainLoop < NUMBER_POLYGONS; wMainLoop++)
{
// Check to see if the current loop is on...
if (fOn[wMainLoop])
{
// If our current count is the same as the final count,
// generate a new count...
if (wCurInc[wMainLoop] == wIncColor[wMainLoop])
{
// Set the count to zero...
wCurInc[wMainLoop] = 0;
// Set an new variant...
wIncColor[wMainLoop] = GenerateVelocity ();
// Set up the cycling colors...
dwSrcColor[wMainLoop] = dwDestColor[wMainLoop];
if (fWalk[wMainLoop])
dwDestColor[wMainLoop] = GenerateColor ();
else if (dwSrcColor[wMainLoop] == dwEndColor[wMainLoop])
dwDestColor[wMainLoop] = dwStartColor[wMainLoop];
else
dwDestColor[wMainLoop] = dwEndColor[wMainLoop];
}
else
wCurInc[wMainLoop]++;
// Now adjust the color between the starting and the
// ending values...
dwCurrentColor[wMainLoop] = AdjustColor (dwSrcColor
[wMainLoop], dwDestColor[wMainLoop], wIncColor
[wMainLoop], wCurInc[wMainLoop]);
wLoop2 = wFreeEntry[wMainLoop] + wMainLoop * MAXLINES;
lplogpalPal->palPalEntry[wLoop2].peRed =
GetRValue (dwCurrentColor[wMainLoop]);
lplogpalPal->palPalEntry[wLoop2].peGreen =
GetGValue (dwCurrentColor[wMainLoop]);
lplogpalPal->palPalEntry[wLoop2].peBlue =
GetBValue (dwCurrentColor[wMainLoop]);
lplogpalPal->palPalEntry[wLoop2].peFlags = PC_RESERVED;
// Adjust the palette...
AnimatePalette (hPalette, wLoop2, 1,
&lplogpalPal->palPalEntry[wLoop2]);
}
}
// Now cycle through again...
for (wMainLoop = 0; wMainLoop < NUMBER_POLYGONS; wMainLoop++)
{
if (fOn[wMainLoop])
{
/* If we are currently displaying all of the lines, then
delete the last line... */
if (wNumDisplay[wMainLoop] == wLines[wMainLoop])
/* Erase the last line... */
DrawPolygon (hDC, hErasePen, wMainLoop,
(WORD) (wNumDisplay[wMainLoop] - 1));
/* Starting with the last entry, make it equal to the
entry before it... until we reach the first
entry... */
for (wLoop1 = (wNumDisplay[wMainLoop] - 1); wLoop1; wLoop1--)
{
/* Copy the points in the polygon over... */
for (wLoop2 = 0; wLoop2 < 4; wLoop2++)
{
ptBox[wLoop1+wMainLoop*MAXLINES][wLoop2].x =
ptBox[wLoop1-1+wMainLoop*MAXLINES][wLoop2].x;
ptBox[wLoop1+wMainLoop*MAXLINES][wLoop2].y =
ptBox[wLoop1-1+wMainLoop*MAXLINES][wLoop2].y;
ptChange[wLoop1+wMainLoop*MAXLINES][wLoop2].x =
ptChange[wLoop1-1+wMainLoop*MAXLINES]
[wLoop2].x;
ptChange[wLoop1+wMainLoop*MAXLINES][wLoop2].y =
ptChange[wLoop1-1+wMainLoop*MAXLINES]
[wLoop2].y;
}
}
/* Seeing as we now have entry 0 the same as entry 1,
generate a new entry 0... */
for (wLoop1 = 0; wLoop1 < 4; wLoop1++)
{
ptBox[wMainLoop*MAXLINES][wLoop1].x +=
ptChange[wMainLoop*MAXLINES][wLoop1].x;
ptBox[wMainLoop*MAXLINES][wLoop1].y +=
ptChange[wMainLoop*MAXLINES][wLoop1].y;
if (ptBox[wMainLoop*MAXLINES][wLoop1].x >=
(int)wScreenX)
{
ptBox[wMainLoop*MAXLINES][wLoop1].x =
ptBox[wMainLoop*MAXLINES][wLoop1].x
-2 * (ptBox[wMainLoop*MAXLINES][wLoop1].x
-wScreenX + 1);
ptChange[wMainLoop*MAXLINES][wLoop1].x =
-RAND (MAXXVEL);
}
if ((int)ptBox[wMainLoop*MAXLINES][wLoop1].x < 0)
{
ptBox[wMainLoop*MAXLINES][wLoop1].x =
-ptBox[wMainLoop*MAXLINES][wLoop1].x;
ptChange[wMainLoop*MAXLINES][wLoop1].x =
RAND (MAXXVEL);
}
if (ptBox[wMainLoop*MAXLINES][wLoop1].y >=
(int)wScreenY)
{
ptBox[wMainLoop*MAXLINES][wLoop1].y =
ptBox[wMainLoop*MAXLINES][wLoop1].y - 2 *
(ptBox[wMainLoop*MAXLINES][wLoop1].y
-wScreenY + 1);
ptChange[wMainLoop*MAXLINES][wLoop1].y =
-RAND (MAXYVEL);
}
if ((int)ptBox[wMainLoop*MAXLINES][wLoop1].y < 0)
{
ptBox[wMainLoop*MAXLINES][wLoop1].y =
-ptBox[wMainLoop*MAXLINES][wLoop1].y;
ptChange[wMainLoop*MAXLINES][wLoop1].y =
RAND (MAXYVEL);
}
}
/* Now redraw the new line... */
wLoop2 = wFreeEntry[wMainLoop] + wMainLoop * MAXLINES;
hPen = CreatePen (PS_SOLID, 1, PALETTEINDEX (wLoop2));
DrawPolygon (hDC, hPen, wMainLoop, 0);
if (hPen)
DeleteObject (hPen);
/* Now, as we are finished with the entry in the
palette, increment it such that the next time
around, it points at the next position... */
if ((++wFreeEntry[wMainLoop]) == wLines[wMainLoop])
wFreeEntry[wMainLoop] = 0;
/* Now, if we are not at the maximum number of lines,
then increment towards there... */
if (wNumDisplay[wMainLoop] < wLines[wMainLoop])
wNumDisplay[wMainLoop]++;
}
}
/* Reselect the old palette... */
if (hOldPal)
SelectPalette (hDC, hOldPal, FALSE);
/* Release the display context... */
ReleaseDC (hWnd, hDC);
}
break;
case WM_DESTROY:
if (wTimer)
KillTimer (hWnd, 1);
if (hPalette)
DeleteObject (hPalette);
if (hErasePen)
DeleteObject (hErasePen);
break;
}
return (DefScreenSaverProc (hWnd, message, wParam, lParam));
}
VOID srand (DWORD dwSeed)
{
dwRand = dwSeed;
}
WORD rand (VOID)
{
dwRand = dwRand * 214013L + 2531011L;
return (WORD)((dwRand >> 16) & 0xffff);
}
BOOL RegisterDialogClasses (HANDLE hInst)
{
/* Register the custom controls.. */
InitCommonControls();
return TRUE;
}
//***************************************************************************
BOOL ScreenSaverConfigureDialog (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
WORD nPal;
DWORD dwTemp = 0;
HPALETTE hPal;
WORD wLoop, wTemp;
BOOL fError;
BYTE byR, byG, byB;
RECT rDlgBox;
TCHAR szTemp[80];
static HWND hIDOK;
static WORD wPolygon;
switch (message)
{
case WM_INITDIALOG:
GetFields (); // Read fields from CONTROL.INI
GetWindowRect (hDlg, (LPRECT) & rDlgBox);
hIDOK = GetDlgItem (hDlg, IDOK);
// Set the global clear state...
CheckDlgButton (hDlg, ID_CLEARSCREEN, fClearScreen);
// Fill the boxes...
for (wLoop = 0; wLoop < NUMBER_POLYGONS; wLoop++)
{
TCHAR szBuffer[20];
WORD wTemp;
LoadString (hMainInstance, idsPolygon, szTemp, CharSizeOf(szTemp));
wsprintf (szBuffer, szTemp, wLoop + 1);
wTemp = (WORD)SendDlgItemMessage (hDlg, ID_SHAPE, CB_ADDSTRING, 0,
(LPARAM)szBuffer);
SendDlgItemMessage (hDlg, ID_SHAPE, CB_SETITEMDATA, wTemp, wLoop);
}
hPal = GetStockObject (DEFAULT_PALETTE);
GetObject (hPal, sizeof (WORD), (LPTSTR) &nPal);
for (wTemp = 0; wTemp < nPal; wTemp++)
{
SendDlgItemMessage (hDlg, ID_COLOR1, CB_ADDSTRING, 0, (LPARAM)(LPSTR)"a");
SendDlgItemMessage (hDlg, ID_COLOR2, CB_ADDSTRING, 0, (LPARAM)(LPSTR)"a");
}
// Start at the first polygon and let'r rip...
SendDlgItemMessage (hDlg, ID_LINES, EM_LIMITTEXT, 2, 0l);
SendDlgItemMessage( hDlg, ID_LINESARROW, UDM_SETRANGE, 0, MAKELONG(MAXLINES, 1));
SendDlgItemMessage (hDlg, ID_SHAPE, CB_SETCURSEL, (wPolygon = 0), 0l);
SendMessage (hDlg, WM_COMMAND, MAKELONG (ID_SHAPE, CBN_SELCHANGE), 0);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
// If we switch polygons, then update all of the info...
case ID_SHAPE:
if (HIWORD (wParam) == CBN_SELCHANGE)
{
WORD wTemp;
wTemp = (WORD)SendDlgItemMessage (hDlg, ID_SHAPE,
CB_GETCURSEL, 0, 0l);
wPolygon = (WORD)SendDlgItemMessage (hDlg, ID_SHAPE,
CB_GETITEMDATA, wTemp, 0l);
CheckDlgButton (hDlg, ID_ACTIVE, fOn[wPolygon]);
SetDlgItemInt (hDlg, ID_LINES, wLines[wPolygon], FALSE);
hPal = GetStockObject (DEFAULT_PALETTE);
GetObject (hPal, sizeof (WORD), (LPTSTR) &nPal);
if (SendDlgItemMessage (hDlg, ID_COLOR1, CB_SETCURSEL,
GetNearestPaletteIndex (hPal, dwStartColor[wPolygon]),
0l) == CB_ERR)
SendDlgItemMessage (hDlg, ID_COLOR1, CB_SETCURSEL, 0, 0l);
if (SendDlgItemMessage (hDlg, ID_COLOR2, CB_SETCURSEL,
GetNearestPaletteIndex (hPal, dwEndColor[wPolygon]),
0l) == CB_ERR)
SendDlgItemMessage (hDlg, ID_COLOR2, CB_SETCURSEL, 0, 0l);
// Set the walk state...
CheckRadioButton (hDlg, ID_2COLORS, ID_RANDOMCOLORS, ID_2COLORS +
fWalk[wPolygon]);
// Enable/disbale windows...
ShadeWindows (hDlg, wPolygon, wPolygon);
}
break;
// Toggle the actiavtion state...
case ID_ACTIVE:
fOn[wPolygon] ^= 1;
CheckDlgButton (hDlg, LOWORD(wParam), fOn[wPolygon]);
ShadeWindows (hDlg, wPolygon, wPolygon);
break;
case ID_CLEARSCREEN:
fClearScreen ^= 1;
CheckDlgButton (hDlg, LOWORD(wParam), fClearScreen);
break;
case ID_COLOR1:
case ID_COLOR2:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
wTemp = (WORD)SendDlgItemMessage (hDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0l);
hPal = GetStockObject (DEFAULT_PALETTE);
GetPaletteEntries (hPal, wTemp, 1, (LPPALETTEENTRY)(LPDWORD) & dwTemp);
if ( LOWORD(wParam) == ID_COLOR1 )
dwStartColor[wPolygon] = dwTemp & 0xffffffL;
else
dwEndColor[wPolygon] = dwTemp & 0xffffffL;
}
break;
// Toggle the walk state...
case ID_2COLORS:
case ID_RANDOMCOLORS:
fWalk[wPolygon] = LOWORD(wParam) - ID_2COLORS;
CheckRadioButton (hDlg, ID_2COLORS, ID_RANDOMCOLORS, LOWORD(wParam));
EnableWindow (GetDlgItem (hDlg, ID_COLOR1), !fWalk[wPolygon]);
InvalidateRect (GetDlgItem (hDlg, ID_COLOR1), NULL, TRUE);
EnableWindow (GetDlgItem (hDlg, ID_COLOR2), !fWalk[wPolygon]);
InvalidateRect (GetDlgItem (hDlg, ID_COLOR2), NULL, TRUE);
break;
// Check to see if the edit texts have lost their focus. If so
// update...
case ID_LINES:
if (HIWORD(wParam) == EN_UPDATE)
{
wLoop = (WORD) GetDlgItemInt (hDlg, LOWORD(wParam), &fError, FALSE);
fError = fError && (wLoop >= 1 && wLoop <= MAXLINES);
EnableWindow (GetDlgItem (hDlg, ID_LINESARROW), fError);
EnableWindow (GetDlgItem (hDlg, IDOK), fError);
if (fError)
wLines[wPolygon] = wLoop;
}
break;
// Save the current parameters...
case IDOK:
wLines[wPolygon] = (WORD) GetDlgItemInt (hDlg, ID_LINES, &fError, FALSE);
// Write the activation state of clearing the screen...
wsprintf (szBuffer, TEXT("%d"), fClearScreen);
WritePrivateProfileString (szAppName, szClearName, szBuffer, szIniFile);
/* Write the updated versions of everything here... */
for (wLoop = 0; wLoop < NUMBER_POLYGONS; wLoop++)
{
/* Set the activation state... */
wsprintf (szBuffer, TEXT("Active%d"), wLoop + 1);
wsprintf (szBuffer2, TEXT("%d"), fOn[wLoop]);
WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
/* Set the walk state... */
wsprintf (szBuffer, TEXT("WalkRandom%d"), wLoop + 1);
wsprintf (szBuffer2, TEXT("%d"), fWalk[wLoop]);
WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
/* Get the number of lines for the current polygon... */
wsprintf (szBuffer, TEXT("Lines%d"), wLoop + 1);
wsprintf (szBuffer2, TEXT("%d"), wLines[wLoop]);
WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
/* Set the start color... */
wsprintf (szBuffer, TEXT("StartColor%d"), wLoop + 1);
byR = GetRValue (dwStartColor[wLoop]);
byG = GetGValue (dwStartColor[wLoop]);
byB = GetBValue (dwStartColor[wLoop]);
wsprintf (szBuffer2, TEXT("%d %d %d"), byR, byG, byB);
WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
/* Set the end color... */
wsprintf (szBuffer, TEXT("EndColor%d"), wLoop + 1);
byR = GetRValue (dwEndColor[wLoop]);
byG = GetGValue (dwEndColor[wLoop]);
byB = GetBValue (dwEndColor[wLoop]);
wsprintf (szBuffer2, TEXT("%d %d %d"), byR, byG, byB);
WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
}
/* Bail out... */
case IDCANCEL:
EndDialog (hDlg, LOWORD(wParam) == IDOK);
return TRUE;
}
break;
case WM_DRAWITEM:
return (BOOL)AppOwnerDraw (hDlg, message, wParam, lParam);
case WM_MEASUREITEM:
return (BOOL)AppOwnerDraw (hDlg, message, wParam, lParam);
case WM_DELETEITEM:
return (BOOL)AppOwnerDraw (hDlg, message, wParam, lParam);
case WM_HELP: // F1
WinHelp(
(HWND) ((LPHELPINFO) lParam)->hItemHandle,
szHelpFile,
HELP_WM_HELP,
(ULONG_PTR) (LPSTR) aMystDlgHelpIds
);
break;
case WM_CONTEXTMENU: // right mouse click
WinHelp(
(HWND) wParam,
szHelpFile,
HELP_CONTEXTMENU,
(ULONG_PTR) (LPSTR) aMystDlgHelpIds
);
break;
default:
break;
}
return FALSE;
}
VOID GetFields (VOID)
{
WORD wLoop;
//Load Global Strings from stringtable
LoadString (hMainInstance, idsName, szName, CharSizeOf(szName));
LoadString (hMainInstance, idsAppName, szAppName, CharSizeOf(szAppName));
//Load Common Strings from stringtable...
LoadString (hMainInstance, idsIniFile, szIniFile, CharSizeOf(szIniFile));
LoadString (hMainInstance, idsScreenSaver, szScreenSaver, CharSizeOf(szScreenSaver));
LoadString (hMainInstance, idsHelpFile, szHelpFile, CharSizeOf(szHelpFile));
LoadString (hMainInstance, idsNoHelpMemory, szNoHelpMemory, CharSizeOf(szNoHelpMemory));
/* Do we clear the screen when we start... */
if ((fClearScreen = GetPrivateProfileInt (szAppName, szClearName, 1, szIniFile)) != 0)
fClearScreen = 1;
/* Loop through and get all of the field information... */
for (wLoop = 0; wLoop < NUMBER_POLYGONS; wLoop++)
{
/* Get the activation state... */
wsprintf (szBuffer, TEXT("Active%d"), wLoop + 1);
if ((fOn[wLoop] = GetPrivateProfileInt (szAppName, szBuffer, 1, szIniFile)) != 0)
fOn[wLoop] = 1;
/* Get the walk state... */
wsprintf (szBuffer, TEXT("WalkRandom%d"), wLoop + 1);
if ((fWalk[wLoop] = GetPrivateProfileInt (szAppName, szBuffer, 1, szIniFile)) != 0)
fWalk[wLoop] = 1;
/* Get the number of lines for the current polygon... */
wsprintf (szBuffer, TEXT("Lines%d"), wLoop + 1);
wLines[wLoop] = (WORD) GetPrivateProfileInt (szAppName, szBuffer, 5, szIniFile);
if ((int)wLines[wLoop] < 1)
wLines[wLoop] = 1;
if (wLines[wLoop] > MAXLINES)
wLines[wLoop] = MAXLINES;
/* Get the starting and ending colors (stored in DWORD format)... */
wsprintf (szBuffer, TEXT("StartColor%d"), wLoop + 1);
dwStartColor[wLoop] = GetProfileRgb (szAppName, szBuffer, RGB (0, 0, 0));
wsprintf (szBuffer, TEXT("EndColor%d"), wLoop + 1);
dwEndColor[wLoop] = GetProfileRgb (szAppName, szBuffer, RGB (255, 255, 255));
}
return;
}
VOID DrawPolygon (HDC hDC, HPEN hPen, WORD wPolygon, WORD wLine)
{
HANDLE hOldPen;
WORD wLoop1;
hOldPen = SelectObject (hDC, hPen);
MoveToEx (hDC, ptBox[wPolygon*MAXLINES+wLine][0].x,
ptBox[wPolygon*MAXLINES+wLine][0].y, NULL);
for (wLoop1 = 0; wLoop1 < 4; wLoop1++)
LineTo (hDC, ptBox[wPolygon*MAXLINES+wLine][(wLoop1+1)%4].x,
ptBox[wPolygon*MAXLINES+wLine][(wLoop1+1)%4].y);
if (hOldPen)
SelectObject (hDC, hOldPen);
return;
}
/* Adjust each of the rgb components according to the four input variables...*/
DWORD AdjustColor (DWORD dwSrc, DWORD dwDest, int nInc, int nCnt)
{
DWORD dwTemp;
WORD wLoop;
int nSrc, nDst, nTmp;
int n1, n2, n3, n4, n5;
/* Nullify the end value... */
dwTemp = 0;
/* Cycle through and compute the difference on each byte... */
for (wLoop = 0; wLoop < 3; wLoop++)
{
nSrc = (int)((dwSrc >> (wLoop * 8)) % 256);
nDst = (int)((dwDest >> (wLoop * 8)) % 256);
n1 = nDst - nSrc;
n2 = n1 * 10;
n3 = n2 / nInc;
n4 = n3 * nCnt;
n5 = n4 / 10;
nTmp = nSrc + n5;
dwTemp += ((DWORD)nTmp) << (wLoop * 8);
}
return dwTemp;
}
/* Compute a random color that is within the accepted norms... */
DWORD GenerateColor (VOID)
{
return (((DWORD)ZRAND (256)) + (((DWORD)ZRAND (256)) << 8) +
(((DWORD)ZRAND (256)) << 16));
}
/* Compute a random velocity that is within the accepted norms... */
WORD GenerateVelocity (VOID)
{
return 255;
return (RAND (30) + 20);
}
LONG AppOwnerDraw (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
RECT rc;
DWORD rgbBg;
static HBITMAP hbmCheck = NULL;
LPMEASUREITEMSTRUCT lpMIS = ((LPMEASUREITEMSTRUCT)lParam);
LPDRAWITEMSTRUCT lpDIS = ((LPDRAWITEMSTRUCT)lParam);
switch (msg)
{
case WM_MEASUREITEM:
lpMIS->itemHeight = 15;
return TRUE;
case WM_DRAWITEM:
rc = lpDIS->rcItem;
rgbBg = PALETTEINDEX (lpDIS->itemID);
if (lpDIS->itemState & ODS_SELECTED)
{
FrameR (lpDIS->hDC, &rc, rgbBlack, 2);
InflateRect (&rc, -1, -1);
FrameR (lpDIS->hDC, &rc, rgbWhite, 2);
InflateRect (&rc, -1, -1);
}
if (lpDIS->itemState & ODS_DISABLED)
FillR (lpDIS->hDC, &rc, rgbGrey);
else
FillR (lpDIS->hDC, &rc, rgbBg);
return TRUE;
case WM_DELETEITEM:
return TRUE;
}
return TRUE;
}
VOID PatB (HDC hdc, int x, int y, int dx, int dy, DWORD rgb)
{
RECT rc;
SetBkColor (hdc, rgb);
rc.left = x;
rc.top = y;
rc.right = x + dx;
rc.bottom = y + dy;
ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
}
VOID FillR (HDC hdc, LPRECT prc, DWORD rgb)
{
SetBkColor (hdc, rgb);
ExtTextOut (hdc, 0, 0, ETO_OPAQUE, prc, NULL, 0, NULL);
}
VOID FrameR (HDC hdc, LPRECT prc, DWORD rgb, int iFrame)
{
// RECT rc;
int dx, dy;
dx = prc->right - prc->left;
dy = prc->bottom - prc->top - 2 * iFrame;
PatB (hdc, prc->left, prc->top, dx, iFrame, rgb);
PatB (hdc, prc->left, prc->bottom - iFrame, dx, iFrame, rgb);
PatB (hdc, prc->left, prc->top + iFrame, iFrame, dy, rgb);
PatB (hdc, prc->right - iFrame, prc->top + iFrame, iFrame, dy, rgb);
}
BOOL DrawBitmap (HDC hdc, int x, int y, HBITMAP hbm, DWORD rop)
{
HDC hdcBits;
BITMAP bm;
// HPALETTE hpalT;
HBITMAP oldbm;
BOOL f;
if (!hdc || !hbm)
return FALSE;
hdcBits = CreateCompatibleDC (hdc);
GetObject (hbm, sizeof (BITMAP), (LPTSTR) & bm);
oldbm = SelectObject (hdcBits, hbm);
f = BitBlt (hdc, x, y, bm.bmWidth, bm.bmHeight, hdcBits, 0, 0, rop);
if (oldbm)
SelectObject (hdcBits, oldbm);
DeleteDC (hdcBits);
return f;
}
DWORD GetProfileRgb (LPTSTR szApp, LPTSTR szItem, DWORD rgb)
{
TCHAR buf[80];
LPTSTR pch;
WORD r, g, b;
GetPrivateProfileString (szApp, szItem, TEXT(""), buf, CharSizeOf(buf), szIniFile);
if (*buf)
{
pch = buf;
r = AtoI (pch);
while (*pch && *pch != TEXT(' '))
pch++;
while (*pch && *pch == TEXT(' '))
pch++;
g = AtoI (pch);
while (*pch && *pch != TEXT(' '))
pch++;
while (*pch && *pch == TEXT(' '))
pch++;
b = AtoI (pch);
return RGB (r, g, b);
}
else
return rgb;
}
WORD AtoI (LPTSTR lpszConvert)
{
WORD wReturn = 0;
while (*lpszConvert >= TEXT('0') && *lpszConvert <= TEXT('9'))
{
wReturn = wReturn * 10 + (WORD)(*lpszConvert - TEXT('0'));
lpszConvert++;
}
return wReturn;
}
VOID ShadeWindows (HWND hDlg, WORD wPoly, WORD wPolygon)
{
EnableWindow (GetDlgItem (hDlg, ID_COLORGROUP), fOn[wPolygon]);
EnableWindow (GetDlgItem (hDlg, ID_2COLORS), fOn[wPolygon]);
EnableWindow (GetDlgItem (hDlg, ID_RANDOMCOLORS), fOn[wPolygon]);
EnableWindow (GetDlgItem (hDlg, ID_LINES), fOn[wPolygon]);
EnableWindow (GetDlgItem (hDlg, ID_LINESARROW), fOn[wPolygon]);
EnableWindow (GetDlgItem (hDlg, ID_COLOR1), !fWalk[wPolygon] && fOn[wPolygon]);
InvalidateRect (GetDlgItem (hDlg, ID_COLOR1), NULL, TRUE);
EnableWindow (GetDlgItem (hDlg, ID_COLOR2), !fWalk[wPolygon] && fOn[wPolygon]);
InvalidateRect (GetDlgItem (hDlg, ID_COLOR2), NULL, TRUE);
}