home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Hits 1995 June / Image.iso / demos / woodruff / wing / palanim.c_ / palanim.c
Encoding:
C/C++ Source or Header  |  1994-06-26  |  23.2 KB  |  744 lines

  1. /*
  2.  *    PALANIM.C
  3.  *
  4.  *    (C) Copyright Microsoft Corp. 1994.  All rights reserved.
  5.  *
  6.  *    You have a royalty-free right to use, modify, reproduce and 
  7.  *    distribute the Sample Files (and/or any modified version) in 
  8.  *    any way you find useful, provided that you agree that 
  9.  *    Microsoft has no warranty obligations or liability for any 
  10.  *    Sample Application Files which are modified. 
  11.  */
  12.  
  13. #include <windows.h>
  14. #include <commdlg.h>
  15. #include <wing.h>
  16.  
  17. #include "dib.h"
  18. #include "palanim.h"
  19.  
  20. /*----------------------------------------------------------------------------*\
  21. |                                                                              |
  22. |   g l o b a l   v a r i a b l e s                                            |
  23. |                                                                              |
  24. \*----------------------------------------------------------------------------*/
  25. static  char    szAppName[]="WinG Palette Animation App";
  26.  
  27. static  HINSTANCE hInstApp;
  28. static  HWND      hwndApp;
  29. static    HPALETTE  hpalApp;
  30. static    BOOL      fAppActive;
  31.  
  32. static HDC hdcOffscreen;
  33. void far *gpBits;
  34. struct {
  35.     BITMAPINFOHEADER InfoHeader;
  36.     RGBQUAD ColorTable[256];
  37. } gInfo;
  38.  
  39. int fAnimatePalette = 0;        // Don't animate
  40. int fIncludeStatic = 0;            // Use the static color entries
  41. enum {Red, Green, Blue} gWashColor = Red;
  42.  
  43. PALETTEENTRY aPalette[256];
  44.  
  45. extern HBITMAP ghBitmapMonochrome;
  46.  
  47. #ifdef WIN32
  48.     #define _export
  49. #endif
  50.  
  51. /*----------------------------------------------------------------------------*\
  52. |                                                                              |
  53. |   f u n c t i o n   d e f i n i t i o n s                                    |
  54. |                                                                              |
  55. \*----------------------------------------------------------------------------*/
  56.  
  57. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  58. int  ErrMsg (LPSTR sz,...);
  59. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  60.  
  61. void AppExit(void);
  62. BOOL AppIdle(void);
  63.  
  64. /***************************************************************************
  65.     Internal functions for the animation
  66. */
  67.  
  68. void CreateWashPalette(void);
  69. void DibCreateWash(BITMAPINFOHEADER far *Info, void far *pBits);
  70. void DibHorizontalLine(BITMAPINFOHEADER far *Info, void far *pBits,
  71.     int y, char unsigned color);
  72.  
  73. /***************************************************************************
  74.     Sample functions from wing.hlp
  75. */
  76.  
  77. HDC Create100x100WinGDC(void);
  78. void Destroy100x100WinGDC(HDC hWinGDC);
  79.  
  80. void AppActivate(BOOL fActive);
  81.  
  82. void ClearSystemPalette(void);
  83. HPALETTE CreateIdentityPalette(RGBQUAD aRGB[], int nColors);
  84.  
  85. /*----------------------------------------------------------------------------*\
  86. |   AppAbout( hDlg, uiMessage, wParam, lParam )                                |
  87. |                                                                              |
  88. |   Description:                                                               |
  89. |       This function handles messages belonging to the "About" dialog box.    |
  90. |       The only message that it looks for is WM_COMMAND, indicating the use   |
  91. |       has pressed the "OK" button.  When this happens, it takes down         |
  92. |       the dialog box.                                                        |
  93. |                                                                              |
  94. |   Arguments:                                                                 |
  95. |       hDlg            window handle of about dialog window                   |
  96. |       uiMessage       message number                                         |
  97. |       wParam          message-dependent                                      |
  98. |       lParam          message-dependent                                      |
  99. |                                                                              |
  100. |   Returns:                                                                   |
  101. |       TRUE if message has been processed, else FALSE                         |
  102. |                                                                              |
  103. \*----------------------------------------------------------------------------*/
  104. BOOL FAR PASCAL _export AppAbout(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  105. {
  106.     switch (msg)
  107.     {
  108.         case WM_COMMAND:
  109.         if (LOWORD(wParam) == IDOK)
  110.             {
  111.                 EndDialog(hwnd,TRUE);
  112.             }
  113.             break;
  114.  
  115.         case WM_INITDIALOG:
  116.             return TRUE;
  117.     }
  118.     return FALSE;
  119. }
  120.  
  121. /*----------------------------------------------------------------------------*\
  122. |   AppInit( hInst, hPrev)                                                     |
  123. |                                                                              |
  124. |   Description:                                                               |
  125. |       This is called when the application is first loaded into               |
  126. |       memory.  It performs all initialization that doesn't need to be done   |
  127. |       once per instance.                                                     |
  128. |                                                                              |
  129. |   Arguments:                                                                 |
  130. |       hInstance       instance handle of current instance                    |
  131. |       hPrev           instance handle of previous instance                   |
  132. |                                                                              |
  133. |   Returns:                                                                   |
  134. |       TRUE if successful, FALSE if not                                       |
  135. |                                                                              |
  136. \*----------------------------------------------------------------------------*/
  137. BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine)
  138. {
  139.     WNDCLASS cls;
  140.     int      dx,dy;
  141.     HBITMAP hbmOffscreen;
  142.     HMENU hMenu;
  143.     HDC Screen;
  144.  
  145.     /* Save instance handle for DialogBoxs */
  146.     hInstApp = hInst;
  147.  
  148.     /* Refuse to run if this is a non-palettized device */
  149.     Screen = GetDC(0);
  150.     if (Screen)
  151.     {
  152.         int PaletteDevice = GetDeviceCaps(Screen, RASTERCAPS) & RC_PALETTE;
  153.         ReleaseDC(0, Screen);
  154.         if (!PaletteDevice)
  155.         {
  156.             MessageBox(0,
  157.                 "Palette animation requires a palettized display device!",
  158.                 "Non-palettized Display",
  159.                 MB_OK);
  160.             return FALSE;
  161.         }
  162.     }
  163.  
  164.     if (!hPrev)
  165.     {
  166.         /*
  167.          *  Register a class for the main application window
  168.          */
  169.         cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  170.         cls.hIcon          = LoadIcon(hInst,"AppIcon");
  171.         cls.lpszMenuName   = "AppMenu";
  172.         cls.lpszClassName  = szAppName;
  173.         cls.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  174.         cls.hInstance      = hInst;
  175.         cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  176.         cls.lpfnWndProc    = (WNDPROC)AppWndProc;
  177.         cls.cbWndExtra     = 0;
  178.         cls.cbClsExtra     = 0;
  179.  
  180.         if (!RegisterClass(&cls))
  181.             return FALSE;
  182.     }
  183.  
  184.     dx = GetSystemMetrics (SM_CXSCREEN) / 2;
  185.     dy = GetSystemMetrics (SM_CYSCREEN) / 2;
  186.  
  187.     hwndApp = CreateWindow (szAppName,    // Class name
  188.                             szAppName,              // Caption
  189.                             WS_OVERLAPPEDWINDOW,    // Style bits
  190.                             CW_USEDEFAULT, 0,       // Position
  191.                 dx,dy,            // Size
  192.                             (HWND)NULL,             // Parent window (no parent)
  193.                             (HMENU)NULL,            // use class menu
  194.                             hInst,                  // handle to window instance
  195.                             (LPSTR)NULL             // no params to pass on
  196.                            );
  197.     ShowWindow(hwndApp,sw);
  198.  
  199.     //*** Create the WinGDC  (actually 256x256)
  200.     hdcOffscreen = Create100x100WinGDC();
  201.  
  202.     //*** Check the menu to reflect initial palette (red)
  203.     hMenu = GetMenu(hwndApp);
  204.     CheckMenuItem(hMenu, MENU_STATIC, fIncludeStatic ? MF_CHECKED : MF_UNCHECKED);
  205.     CheckMenuItem(hMenu, MENU_RED, MF_CHECKED);
  206.     CheckMenuItem(hMenu, MENU_GREEN, MF_UNCHECKED);
  207.     CheckMenuItem(hMenu, MENU_BLUE, MF_UNCHECKED);
  208.  
  209.     //*** Hack to get the offscreen HBITMAP
  210.     hbmOffscreen = (HBITMAP)SelectObject(hdcOffscreen, ghBitmapMonochrome);
  211.     SelectObject(hdcOffscreen, hbmOffscreen);
  212.  
  213.     //*** Initialize the DIB to a wash from top to bottom
  214.     gpBits = WinGGetDIBPointer(hbmOffscreen, (BITMAPINFO far *)&gInfo);
  215.     DibCreateWash(&gInfo.InfoHeader, gpBits);
  216.  
  217.     //*** Reset the color palette
  218.     ClearSystemPalette();
  219.     CreateWashPalette();
  220.  
  221.     return TRUE;
  222. }
  223.  
  224.  
  225. /*----------------------------------------------------------------------------*\
  226. |   AppExit()                                       |
  227. |                                                                              |
  228. |   Description:                                                               |
  229. |    app is just about to exit, cleanup                       |
  230. |                                                                              |
  231. \*----------------------------------------------------------------------------*/
  232. void AppExit()
  233. {
  234.     if (hdcOffscreen)
  235.         Destroy100x100WinGDC(hdcOffscreen);
  236.  
  237.     if (hpalApp)
  238.         DeleteObject(hpalApp);
  239.  
  240.     //*** Be sure to restore the state on exit!
  241.     if (fIncludeStatic)
  242.         AppActivate(FALSE);
  243. }
  244.  
  245. /*----------------------------------------------------------------------------*\
  246. |   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                              |
  247. |                                                                              |
  248. |   Description:                                                               |
  249. |       The main procedure for the App.  After initializing, it just goes      |
  250. |       into a message-processing loop until it gets a WM_QUIT message         |
  251. |       (meaning the app was closed).                                          |
  252. |                                                                              |
  253. |   Arguments:                                                                 |
  254. |       hInst           instance handle of this instance of the app            |
  255. |       hPrev           instance handle of previous instance, NULL if first    |
  256. |       szCmdLine       ->null-terminated command line                         |
  257. |       cmdShow         specifies how the window is initially displayed        |
  258. |                                                                              |
  259. |   Returns:                                                                   |
  260. |       The exit code as specified in the WM_QUIT message.                     |
  261. |                                                                              |
  262. \*----------------------------------------------------------------------------*/
  263. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
  264. {
  265.     MSG     msg;
  266.  
  267.     /* Call initialization procedure */
  268.     if (!AppInit(hInst,hPrev,sw,szCmdLine))
  269.     return FALSE;
  270.  
  271.     /*
  272.      * Polling messages from event queue
  273.      */
  274.     for (;;)
  275.     {
  276.         if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
  277.         {
  278.             if (msg.message == WM_QUIT)
  279.                 break;
  280.  
  281.             TranslateMessage(&msg);
  282.             DispatchMessage(&msg);
  283.         }
  284.         else
  285.     {
  286.         if (AppIdle())
  287.                 WaitMessage();
  288.         }
  289.     }
  290.  
  291.     AppExit();
  292.     return msg.wParam;
  293. }
  294.  
  295. /*----------------------------------------------------------------------------*\
  296. |   AppIdle()                                       |
  297. |                                                                              |
  298. |   Description:                                                               |
  299. |    place to do idle time stuff.                           |
  300. |                                                                              |
  301. |   Returns:                                       |
  302. |    RETURN TRUE IF YOU HAVE NOTHING TO DO OTHERWISE YOUR APP WILL BE A     |
  303. |    CPU PIG!                                   |
  304. \*----------------------------------------------------------------------------*/
  305. BOOL AppIdle()
  306. {
  307.     if (fAppActive)
  308.     {
  309.         return TRUE;
  310.     }
  311.     else
  312.     {
  313.     //
  314.     // we are a background app.
  315.     //
  316.     return TRUE;        // nothing to do.
  317.     }
  318. }
  319.  
  320. /*----------------------------------------------------------------------------*\
  321. |   AppPaint(hwnd, hdc)                                                        |
  322. |                                                                              |
  323. |   Description:                                                               |
  324. |       The paint function.  Right now this does nothing.                      |
  325. |                                                                              |
  326. |   Arguments:                                                                 |
  327. |       hwnd             window painting into                                  |
  328. |       hdc              display context to paint to                           |
  329. |                                                                              |
  330. |   Returns:                                                                   |
  331. |       nothing                                                                |
  332. |                                                                              |
  333. \*----------------------------------------------------------------------------*/
  334. AppPaint (HWND hwnd, HDC hdc)
  335. {
  336.     RECT    rc;
  337.  
  338.     GetClientRect(hwnd,&rc);
  339.  
  340.     SetTextColor(hdc,GetSysColor(COLOR_WINDOWTEXT));
  341.     SetBkColor(hdc,GetSysColor(COLOR_WINDOW));
  342.  
  343.     if (hdcOffscreen)
  344.     {
  345.         int i;
  346.         PALETTEENTRY aPalette[256];
  347.         RGBQUAD aPaletteRGB[256];
  348.  
  349.         //*** BEFORE BLTTING, match the DIB color table to the
  350.         //*** current palette to match the animated palette
  351.         GetPaletteEntries(hpalApp, 0, 256, aPalette);
  352.         //*** Alas, palette entries are r-g-b, rgbquads are b-g-r
  353.         for (i=0; i<256; ++i)
  354.         {
  355.             aPaletteRGB[i].rgbRed = aPalette[i].peRed;
  356.             aPaletteRGB[i].rgbGreen = aPalette[i].peGreen;
  357.             aPaletteRGB[i].rgbBlue = aPalette[i].peBlue;
  358.             aPaletteRGB[i].rgbReserved = 0;
  359.         }
  360.         WinGSetDIBColorTable(hdcOffscreen, 0, 256, aPaletteRGB);
  361.  
  362.         WinGBitBlt(hdc,0,0,256,256,hdcOffscreen,0,0);
  363.     }
  364.  
  365.     return TRUE;
  366. }
  367.  
  368. /*----------------------------------------------------------------------------*\
  369. |   AppWndProc( hwnd, uiMessage, wParam, lParam )                              |
  370. |                                                                              |
  371. |   Description:                                                               |
  372. |       The window proc for the app's main (tiled) window.  This processes all |
  373. |       of the parent window's messages.                                       |
  374. |                                                                              |
  375. \*----------------------------------------------------------------------------*/
  376.  
  377. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  378. {
  379.     PAINTSTRUCT ps;
  380.     HDC hdc;
  381.     BOOL f;
  382.     static int CurtainY = 0;
  383.  
  384.     switch (msg)
  385.     {
  386.         case WM_CREATE:
  387.         break;
  388.  
  389.         case WM_ACTIVATEAPP:
  390.             fAppActive = (BOOL)wParam;
  391.  
  392.             //*** Remap the system colors and deal with the palette
  393.             if (fIncludeStatic == 0)
  394.             {
  395.                 AppActivate(fAppActive);
  396.  
  397.                 if (hpalApp)
  398.                 {
  399.                     HDC hdc = GetDC(hwnd);
  400.  
  401.                     UnrealizeObject(hpalApp);
  402.                     SelectPalette(hdc, hpalApp, FALSE);
  403.                     RealizePalette(hdc);
  404.  
  405.                     ReleaseDC(hwnd, hdc);
  406.                 }
  407.             }
  408.             break;
  409.  
  410.         case WM_TIMER:
  411.             switch (wParam)
  412.             {
  413.                 case 1:
  414.                     //*** Animate or terminate the "falling black curtain"
  415.                     {
  416.                         if (CurtainY < 256)
  417.                         {
  418.                             DibHorizontalLine(&gInfo.InfoHeader, gpBits, CurtainY, 0);
  419.                             CurtainY++;
  420.                         }
  421.                         else
  422.                         {
  423.                             CurtainY = 0;
  424.                             DibCreateWash(&gInfo.InfoHeader, gpBits);
  425.                             KillTimer(hwnd, wParam);
  426.                         }
  427.                     }
  428.  
  429.                     //*** The DIB has changed - redisplay it
  430.                     InvalidateRect(hwnd, NULL, FALSE);
  431.                     UpdateWindow(hwnd);
  432.  
  433.                     break;
  434.  
  435.                 case 2:
  436.                     //*** Get the current palette
  437.                     GetPaletteEntries(hpalApp, 0, 256, aPalette);
  438.  
  439.                     if (fIncludeStatic)
  440.                     {
  441.                         //*** We'll rotate the middle 236 entries, leaving
  442.                         //*** black and white at the top
  443.                         aPalette[245] = aPalette[10];
  444.                         AnimatePalette(hpalApp, 10, 236, &aPalette[11]);
  445.                     }
  446.                     else
  447.                     {
  448.                         //*** We'll rotate the middle 254 entries, leaving
  449.                         //*** black and white at the top
  450.                         aPalette[255] = aPalette[1];
  451.                         AnimatePalette(hpalApp, 1, 254, &aPalette[2]);
  452.                     }
  453.                     InvalidateRect(hwnd, NULL, FALSE);
  454.                     UpdateWindow(hwnd);
  455.                     break;
  456.             }
  457.             break;
  458.  
  459.         case WM_ERASEBKGND:
  460.             break;
  461.  
  462.         case WM_INITMENU:
  463.             break;
  464.  
  465.         case WM_COMMAND:
  466.             return AppCommand(hwnd,msg,wParam,lParam);
  467.  
  468.     case WM_DESTROY:
  469.             PostQuitMessage(0);
  470.             break;
  471.  
  472.         case WM_CLOSE:
  473.         break;
  474.  
  475.         case WM_PALETTECHANGED:
  476.         if ((HWND)wParam == hwnd)
  477.         break;
  478.  
  479.         // fall through to WM_QUERYNEWPALETTE
  480.  
  481.     case WM_QUERYNEWPALETTE:
  482.         hdc = GetDC(hwnd);
  483.  
  484.         if (hpalApp)
  485.         SelectPalette(hdc, hpalApp, FALSE);
  486.  
  487.         f = RealizePalette(hdc);
  488.         ReleaseDC(hwnd,hdc);
  489.  
  490.         if (f)
  491.         InvalidateRect(hwnd,NULL,TRUE);
  492.  
  493.         return f;
  494.  
  495.         case WM_PAINT:
  496.             hdc = BeginPaint(hwnd,&ps);
  497.             if (hpalApp)
  498.             {
  499.                 SelectPalette(hdc, hpalApp, FALSE);
  500.                 RealizePalette(hdc);
  501.             }
  502.             AppPaint (hwnd,hdc);
  503.             EndPaint(hwnd,&ps);
  504.             return 0L;
  505.     }
  506.     return DefWindowProc(hwnd,msg,wParam,lParam);
  507. }
  508.  
  509. /*----------------------------------------------------------------------------*\
  510. |   AppCommand(hwnd, msg, wParam, lParam )                       |
  511. |                                                                              |
  512. |   Description:                                                               |
  513. |    handles WM_COMMAND messages for the main window (hwndApp)           |
  514. |       of the parent window's messages.                                       |
  515. |                                                                              |
  516. \*----------------------------------------------------------------------------*/
  517. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  518. {
  519.     HMENU hMenu;
  520.     HPALETTE hPal = GetStockObject(DEFAULT_PALETTE);
  521.     HDC hdc = GetDC(hwnd);
  522.  
  523.     switch(wParam)
  524.     {
  525.         case MENU_ABOUT:
  526.         DialogBox(hInstApp,"AppAbout",hwnd,AppAbout);
  527.             break;
  528.  
  529.         case MENU_EXIT:
  530.             PostMessage(hwnd,WM_CLOSE,0,0L);
  531.             break;
  532.  
  533.         case MENU_RED:
  534.         case MENU_GREEN:
  535.         case MENU_BLUE:
  536.             hMenu = GetMenu(hwndApp);
  537.  
  538.             CheckMenuItem(hMenu, MENU_RED, MF_UNCHECKED);
  539.             CheckMenuItem(hMenu, MENU_GREEN, MF_UNCHECKED);
  540.             CheckMenuItem(hMenu, MENU_BLUE, MF_UNCHECKED);
  541.             CheckMenuItem(hMenu, wParam, MF_CHECKED);
  542.             
  543.             if (wParam == MENU_RED) gWashColor = Red;
  544.             else if (wParam == MENU_GREEN) gWashColor = Green;
  545.             else gWashColor = Blue;
  546.  
  547.             //*** Delete the old palette and create a new one
  548.             hPal = SelectPalette(hdc, hPal, FALSE);
  549.             DeleteObject(hPal);
  550.  
  551.             CreateWashPalette();
  552.  
  553.             InvalidateRect(hwnd, NULL, FALSE);
  554.             UpdateWindow(hwnd);
  555.             break;
  556.  
  557.         case MENU_PALETTE:
  558.             hMenu = GetMenu(hwndApp);
  559.             if (fAnimatePalette)
  560.             {
  561.                 fAnimatePalette = 0;
  562.                 CheckMenuItem(hMenu, MENU_PALETTE, MF_UNCHECKED);
  563.                 KillTimer(hwnd, 2);
  564.             }
  565.             else
  566.             {
  567.                 fAnimatePalette = 1;
  568.                 CheckMenuItem(hMenu, MENU_PALETTE, MF_CHECKED);
  569.                 SetTimer(hwnd, 2, 1, 0);
  570.             }
  571.             break;
  572.  
  573.         case MENU_CURTAIN:
  574.             //*** Just start off the falling curtain
  575.             SetTimer(hwnd, 1, 10, 0);
  576.             break;
  577.  
  578.         case MENU_STATIC:
  579.             hMenu = GetMenu(hwndApp);
  580.  
  581.             if (fIncludeStatic)
  582.             {
  583.                 //*** Flag no static color use
  584.                 fIncludeStatic = 0;
  585.                 CheckMenuItem(hMenu, MENU_STATIC, MF_UNCHECKED);
  586.  
  587.                 //*** Remap the system colors
  588.                 AppActivate(TRUE);
  589.             }
  590.             else
  591.             {
  592.                 //*** Flag static color use
  593.                 fIncludeStatic = 1;
  594.                 CheckMenuItem(hMenu, MENU_STATIC, MF_CHECKED);
  595.  
  596.                 //*** Remap the system colors to normal
  597.                 AppActivate(FALSE);
  598.             }
  599.  
  600.             //*** Delete the old palette and create a new one
  601.             hPal = SelectPalette(hdc, hPal, FALSE);
  602.             DeleteObject(hPal);
  603.  
  604.             CreateWashPalette();
  605.  
  606.             InvalidateRect(hwnd, NULL, FALSE);
  607.             UpdateWindow(hwnd);
  608.             break;
  609.     }
  610.  
  611.      ReleaseDC(hwnd, hdc);
  612.  
  613.     return 0L;
  614. }
  615.  
  616. /*----------------------------------------------------------------------------*\
  617. |   ErrMsg - Opens a Message box with a error message in it.  The user can     |
  618. |            select the OK button to continue                                  |
  619. \*----------------------------------------------------------------------------*/
  620. int ErrMsg (LPSTR sz,...)
  621. {
  622.     char ach[128];
  623.  
  624.     wvsprintf (ach,sz,(LPSTR)(&sz+1));   /* Format the string */
  625.     MessageBox(hwndApp,ach,szAppName,MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL);
  626.     return FALSE;
  627. }
  628.  
  629.  
  630. /***************************************************************************
  631.     Palette Creation
  632.     Create three palettes of solid color washes, with or without statics
  633. */
  634.  
  635. void CreateWashPalette(void)
  636. {
  637.     RGBQUAD aWash[256];
  638.     int i;
  639.  
  640.     //*** Fill in the palette with a 256-color ramp
  641.     for (i=0; i<256; ++i)
  642.     {
  643.         aWash[i].rgbRed = aWash[i].rgbBlue = aWash[i].rgbGreen = 0;
  644.  
  645.         switch (gWashColor)
  646.         {
  647.             case Red:
  648.                 aWash[i].rgbRed = i;
  649.                 break;
  650.  
  651.             case Green:
  652.                 aWash[i].rgbGreen = i;
  653.                 break;
  654.  
  655.             case Blue:
  656.                 aWash[i].rgbBlue = i;
  657.                 break;
  658.         }
  659.  
  660.         aWash[i].rgbReserved = 0;
  661.     }
  662.  
  663.     //*** Turn the wash into a palette
  664.     if (hpalApp)
  665.         DeleteObject(hpalApp);
  666.     hpalApp = CreateIdentityPalette(aWash, 256);
  667. }
  668.  
  669. /***************************************************************************
  670.     Dib drawing routines
  671.  
  672.     One creates a wash of color from left to right,
  673.     the other draws a horizontal line at a given Y in the DIB
  674. */
  675.  
  676. void DibCreateWash(BITMAPINFOHEADER far *Info, void far *pBits)
  677. {
  678.     unsigned int dxBytes = DibWidthBytes(Info);
  679.     int dxWidth = DibWidth(Info);
  680.     int dyLines = (int)Info->biHeight;
  681.     int i, j;
  682.     char unsigned huge *pScanline = (char unsigned huge *)pBits;
  683.     char unsigned huge *pPixel;
  684.  
  685.     if (dyLines < 0)
  686.     {
  687.         dyLines = -dyLines;
  688.     }
  689.  
  690.     for (i=0; i<dyLines; ++i)
  691.     {
  692.         //*** Point to the beginning of this scan line in the DIB
  693.         pPixel = pScanline;
  694.  
  695.         //*** Step through this scan line and fill it
  696.         //*** Wash up on the evens, then down on the odds
  697.         for (j=0; j<256; j+=2)
  698.         {
  699.             *pPixel = (char unsigned)(j % 256);
  700.             pPixel++;
  701.         }
  702.         for (j=253; j>0; j-=2)
  703.         {
  704.             *pPixel = (char unsigned)(j % 256);
  705.             pPixel++;
  706.         }
  707.         //*** Make the last column white
  708.         *pPixel = 255;
  709.  
  710.         //*** Move pointer to the next scan line
  711.         pScanline += dxBytes;
  712.     }
  713. }
  714.  
  715. void DibHorizontalLine(BITMAPINFOHEADER far *Info, void far *pBits,
  716.     int y, char unsigned color)
  717. {
  718.     unsigned int dxBytes = DibWidthBytes(Info);
  719.     char unsigned huge *pPixel;
  720.     int dxWidth = DibWidth(Info);
  721.     int dyLines = (int)Info->biHeight;
  722.     int i;
  723.  
  724.     //*** Account for top-down and bottom-up DIBs
  725.     if (dyLines > 0)
  726.     {
  727.         pPixel = (char unsigned huge *)pBits +
  728.             (long)(dyLines - 1 - y) * (long)dxBytes;
  729.     }
  730.     else
  731.     {
  732.         pPixel = (char unsigned huge *)pBits +
  733.             (long)y * (long)dxBytes;
  734.     }
  735.  
  736.     for (i=0; i<dxWidth; ++i)
  737.     {
  738.         *pPixel = color;
  739.         pPixel++;
  740.     }
  741. }
  742.  
  743.  
  744.