Rainbow: C/C++ Version
Here is the C/C++ version of Rainbow. Note how the WM_DESTROY handler calls the Windows API function KillTimer() to stop the timer (and hence the WM_TIMER messages) just before the program exits.
/****************************************************************************\
* *
* Rainbow.c *
* *
* This program demonstrates color palette cycling. *
* *
\****************************************************************************/
#include <fgwin.h>
#include
LRESULT CALLBACK WindowProc(HWND,UINT,WPARAM,LPARAM);
void FillColorPalette(void);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdParam, int iCmdShow)
{
static char szAppName[] = "FGrainbow";
HWND hWnd;
MSG msg;
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
RegisterClassEx(&wndclass);
hWnd = CreateWindow(szAppName, // window class name
"Color Cycling", // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow(hWnd,iCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/****************************************************************************\
* *
* WindowProc() *
* *
\****************************************************************************/
HDC hDC;
HPALETTE hPal;
int hVB;
UINT cxClient, cyClient;
int Start;
BYTE RGBvalues[2*24*3]; // two sets of 24 RGB triplets
LRESULT CALLBACK WindowProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
int Color, xLen, yLen;
switch (iMsg)
{
case WM_CREATE:
// create the logical palette
hDC = GetDC(hWnd);
fg_setdc(hDC);
FillColorPalette();
hPal = fg_logpal(10,24,RGBvalues);
fg_realize(hPal);
// create a 640x480 virtual buffer
fg_vbinit();
hVB = fg_vballoc(640,480);
fg_vbopen(hVB);
fg_vbcolors();
// construct a crude image of a rainbow
fg_setcolor(255);
fg_fillpage();
fg_setclip(0,639,0,300);
fg_move(320,300);
xLen = 240;
yLen = 120;
for (Color = 10; Color < 34; Color++)
{
fg_setcolor(Color);
fg_ellipsef(xLen,yLen);
xLen -= 4;
yLen -= 3;
}
fg_setcolor(255);
fg_ellipsef(xLen,yLen);
fg_setclip(0,639,0,479);
// starting index into the array of color values
Start = 0;
// start the 50ms timer
SetTimer(hWnd,1,50,NULL);
return 0;
case WM_PAINT:
BeginPaint(hWnd,&ps);
fg_vbscale(0,fg_getmaxx(),0,fg_getmaxy(),0,cxClient-1,0,cyClient-1);
EndPaint(hWnd,&ps);
return 0;
case WM_SETFOCUS:
fg_realize(hPal);
InvalidateRect(hWnd,NULL,TRUE);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_TIMER:
if (GetActiveWindow() == hWnd)
{
Start = (Start + 3) % 72;
fg_setdacs(10,24,&RGBvalues[Start]);
if (fg_colors() > 8)
fg_vbscale(0,fg_getmaxx(),0,fg_getmaxy(),0,cxClient-1,0,cyClient-1);
}
return 0;
case WM_DESTROY:
KillTimer(hWnd,1);
fg_vbclose();
fg_vbfree(hVB);
fg_vbfin();
DeleteObject(hPal);
ReleaseDC(hWnd,hDC);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,iMsg,wParam,lParam);
}
/****************************************************************************\
* *
* FillColorPalette() *
* *
* Set up the colors for the application's logical palette in the RGBvalues *
* array. The logical palette will contain 24 non-system colors (indices 10 *
* to 33) defining the initial RGB values for the colors being cycled. *
* *
* Note that we store two identical sets of 24 RGB triplets in RGBvalues. We *
* can then perform color cycling without having to worry about wrapping to *
* the start of the array because the index pointing to the starting RGB *
* triplet never extends beyond the first set of 24 RGB triplets. *
* *
\****************************************************************************/
void FillColorPalette()
{
static BYTE Colors[] = {
182,182,255, 198,182,255, 218,182,255, 234,182,255, 255,182,255,
255,182,234, 255,182,218, 255,182,198, 255,182,182, 255,198,182,
255,218,182, 255,234,182, 255,255,182, 234,255,182, 218,255,182,
198,255,182, 182,255,182, 182,255,198, 182,255,218, 182,255,234,
182,255,255, 182,234,255, 182,218,255, 182,198,255};
// set up two identical sets of the 24 colors in the RGBvalues array
memcpy(RGBvalues,Colors,24*3);
memcpy(&RGBvalues[24*3],Colors,24*3);
}
|