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);
}

<< Prev

Next >>

Contents
Fastgraph Home Page

 

copyright 2001 Ted Gruber Software, Inc.