home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 7.ddi / MWHC.007 / MA < prev    next >
Encoding:
Text File  |  1991-08-28  |  15.7 KB  |  508 lines

  1. /***************************************************************************
  2.  *                                       *
  3.  *  PROGRAM    : MyPal.c                           *
  4.  *                                       *
  5.  *  PURPOSE    : Sets up a bar representation of the current physical       *
  6.  *          palette and displays useful information regarding       *
  7.  *          pixel colors and palette indices.               *
  8.  *                                       *
  9.  *  FUNCTIONS    : WinMain() - calls initialization function,           *
  10.  *                  processes message loop               *
  11.  *                                       *
  12.  *          WndProc() - Window function for app. Processes       *
  13.  *                  window messages.                   *
  14.  *                                       *
  15.  *        ShowColor() - Displays a little box on each side of the    *
  16.  *                  caption bar displaying the pixel color at the*
  17.  *                  mouse position.                   *
  18.  ***************************************************************************/
  19.  
  20. #include <windows.h>
  21. #include <stdlib.h>
  22. #include "mypal.h"
  23.  
  24. HANDLE        hPal;           /* Handle to the application's logical palette */
  25. static WORD    nSizeX;        /* Width of the application window          */
  26. static WORD    nSizeY;        /* Height of the application window          */
  27. NPLOGPALETTE    pLogPal;       /* Pointer to program's logical palette        */
  28. WORD        nXBorder;      /* Width of window border              */
  29. WORD        nXTitle;       /* Width of title bar                  */
  30. WORD        nYTitle;       /* Height of title bar                  */
  31. BOOL        bCaptureOn;    /* Indicates if mouse capture is on          */
  32. int        iIndex;        /* Last index selected in palette          */
  33. char        szTitlebuf[90];/* Buffer for pixel and palette info. text     */
  34. HDC        hDCGlobal;     /* The Screen DC                   */
  35. int        iNumColors;    /* Number of colors supported by device          */
  36. int        iRasterCaps;   /* Raster capabilities                  */
  37. int        iPalSize;      /* Size of Physical palette              */
  38. RECT        rClientRect;   /* Client rectangle coordinates              */
  39. DWORD     dwPal[PALETTESIZE];   /* Stores palette entries for later lookup     */
  40. int        iGlobalXOffset;
  41. int        iGlobalYOffset;
  42. int        iYMiddle;
  43.  
  44. long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
  45.  
  46. /****************************************************************************
  47.  *                                        *
  48.  *  FUNCTION   : void ShowColor(HWND hWnd, HDC hDC)                *
  49.  *                                        *
  50.  *  PURPOSE    : Displays a little box on each side of the caption bar        *
  51.  *         displaying the pixel color at the mouse position.        *
  52.  *                                        *
  53.  ****************************************************************************/
  54. void ShowColor (hWnd, hDC)
  55. HWND  hWnd;
  56. HDC   hDC;
  57. {
  58.      HBRUSH  hBrush, hOldBrush;
  59.  
  60.      hBrush    = CreateSolidBrush ( PALETTEINDEX(iIndex) );
  61.      hOldBrush = SelectObject (hDC,hBrush) ;
  62.  
  63.      GetWindowRect (hWnd, (LPRECT)&rClientRect);
  64.  
  65.      PatBlt ( hDC,
  66.           rClientRect.left + nXTitle + nXBorder + 1,
  67.           rClientRect.top + nXBorder,
  68.           nXTitle,
  69.           nYTitle,
  70.           PATCOPY);
  71.  
  72.      PatBlt(hDC,
  73.         rClientRect.right - ( 3 * nXTitle + nXBorder + 2),
  74.         rClientRect.top + nXBorder,
  75.         nXTitle,
  76.         nYTitle,
  77.         PATCOPY);
  78.      SelectObject (hDC, hOldBrush);
  79.      DeleteObject (hBrush) ;
  80. }
  81.  
  82. /****************************************************************************
  83.  *                                        *
  84.  *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)                *
  85.  *                                        *
  86.  *  PURPOSE    : Creates the app. window and processes the message loop.    *
  87.  *                                        *
  88.  ****************************************************************************/
  89. int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  90.  
  91. HANDLE hInstance;
  92. HANDLE hPrevInstance;
  93. LPSTR  lpszCmdLine;
  94. int    nCmdShow;
  95.  
  96. {
  97.      static char szAppName [] = "MyPal";
  98.      HWND     hWnd;
  99.      WNDCLASS     wndclass;
  100.      MSG     msg ;
  101.      short int     xScreen;
  102.      short int     yScreen;
  103.  
  104.      if (!hPrevInstance){
  105.      wndclass.style     = CS_HREDRAW | CS_VREDRAW;
  106.      wndclass.lpfnWndProc    = WndProc;
  107.      wndclass.cbClsExtra    = 0;
  108.      wndclass.cbWndExtra    = 0;
  109.      wndclass.hInstance    = hInstance;
  110.      wndclass.hIcon     = LoadIcon(hInstance, szAppName);
  111.      wndclass.hCursor    = LoadCursor (NULL, IDC_ARROW);
  112.      wndclass.hbrBackground = GetStockObject (BLACK_BRUSH);
  113.      wndclass.lpszMenuName    = szAppName;
  114.      wndclass.lpszClassName = szAppName;
  115.  
  116.      if (!RegisterClass (&wndclass))
  117.          return FALSE ;
  118.      }
  119.  
  120.      /* Do some global initializations */
  121.      xScreen     = GetSystemMetrics (SM_CXSCREEN);
  122.      yScreen     = GetSystemMetrics (SM_CYSCREEN);
  123.      nXBorder     = GetSystemMetrics (SM_CXFRAME);
  124.      nXTitle     = GetSystemMetrics (SM_CXSIZE);
  125.      nYTitle     = GetSystemMetrics (SM_CYSIZE);
  126.      iIndex     = 0;
  127.      bCaptureOn  = FALSE;
  128.  
  129.      hDCGlobal     = GetDC (NULL);
  130.      iPalSize     = GetDeviceCaps (hDCGlobal, SIZEPALETTE);
  131.      iRasterCaps = GetDeviceCaps (hDCGlobal, RASTERCAPS);
  132.      iRasterCaps = (iRasterCaps & RC_PALETTE) ? TRUE : FALSE;
  133.      ReleaseDC (NULL,hDCGlobal);
  134.  
  135.      if (iRasterCaps)
  136.      iNumColors = GetDeviceCaps(hDCGlobal, SIZEPALETTE);
  137.      else
  138.      iNumColors = GetDeviceCaps( hDCGlobal, NUMCOLORS);
  139.  
  140.      nSizeX = ((xScreen - 2*nXBorder) / PALETTESIZE) * PALETTESIZE;
  141.  
  142.      /* create the app. window */
  143.      hWnd = CreateWindow (szAppName,
  144.               "My Physical Palette ",
  145.               WS_OVERLAPPEDWINDOW,
  146.               (xScreen-nSizeX) / 2 - nXBorder,
  147.               yScreen - ( 4 * GetSystemMetrics (SM_CYCAPTION)),
  148.               nSizeX + 2 * nXBorder,
  149.               4 * GetSystemMetrics (SM_CYCAPTION),
  150.               NULL,
  151.               NULL,
  152.               hInstance,
  153.               NULL);
  154.      ShowWindow (hWnd, nCmdShow);
  155.      UpdateWindow (hWnd);
  156.  
  157.      while (GetMessage (&msg, NULL, 0, 0)){
  158.        TranslateMessage (&msg) ;
  159.        DispatchMessage (&msg) ;
  160.      }
  161.  
  162.      return msg.wParam ;
  163. }
  164.  
  165. /******************************************************************************
  166.  *                                          *
  167.  *  FUNCTION: WndProc(HWND, WORD, WORD, LONG)                  *
  168.  *                                          *
  169.  *  PURPOSE:  Processes window messages and sets up a 256 bar representation  *
  170.  *          of the current physical palette. Specifically, in response to:  *
  171.  *                                          *
  172.  *         WM_CREATE  -Allocates for and sets up a LOGPALETTE          *
  173.  *                 structure, creates a logical palette the same    *
  174.  *                 size as the physical palette and obtains a       *
  175.  *                 handle to the logical palette.              *
  176.  *                                          *
  177.  *         WM_DESTROY -Destroys the logical palette and shuts down app. *
  178.  *                                          *
  179.  *         WM_PAINT   -Resizes client area to hold as many vertical     *
  180.  *                 color bars as there are physical palette entries.*
  181.  *                 Also realises the current logical palette and    *
  182.  *                 draws one color bar corresponding to each          *
  183.  *                 palette entry                      *
  184.  *                                          *
  185.  *         WM_RBUTTONDOWN -Captures the mouse and initiates the below       *
  186.  *                 process:                          *
  187.  *                                          *
  188.  *         WM_MOUSEMOVE   -Following a WM_RBUTTONDOWN, if the right mouse   *
  189.  *                 key is depressed, displays info about the          *
  190.  *                 pixel RGB value and palette index of the mouse   *
  191.  *                 coordinates.                      *
  192.  *                                          *
  193.  *         WM_RBUTTONUP   -Release mouse capture and terminates the above   *
  194.  *                 process                          *
  195.  *                                          *
  196.  *         WM_LBUTTONDOWN -Determines and displays the palette index and    *
  197.  *                 RGB value of the bar under the mouse.          *
  198.  *                                          *
  199.  *         WM_KEYDOWN     -Allows use of the arrow keys in stepping thro'   *
  200.  *                 palette entries.                      *
  201.  *                                          *
  202.  *****************************************************************************/
  203. long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
  204.  
  205. HWND     hWnd;
  206. WORD     iMessage;
  207. WORD     wParam;
  208. LONG     lParam;
  209.  
  210. {
  211.     HDC       hDC;
  212.     PAINTSTRUCT   ps;
  213.     WORD      iLoop;
  214.     WORD      nStart;
  215.     HBRUSH      hBrush;
  216.     HBRUSH      hOldBrush;
  217.  
  218.     POINT      pt;
  219.     static WORD   nIncr;
  220.     static DWORD  dwColor;
  221.     static DWORD  dwLastColor;
  222.     static int      i, x;
  223.  
  224.     switch (iMessage){
  225.      case WM_DESTROY:
  226.           /* delete the handle to the logical palette if it has any
  227.            * color entries and quit.
  228.            */
  229.           if (pLogPal->palNumEntries)
  230.           DeleteObject (hPal);
  231.           PostQuitMessage (0) ;
  232.           break ;
  233.  
  234.      case WM_CREATE:
  235.           /* Allocate enough memory for a logical palette with
  236.            * PALETTESIZE entries and set the size and version fields
  237.            * of the logical palette structure.
  238.            */
  239.           pLogPal = calloc(1, (sizeof (LOGPALETTE) +
  240.                     (sizeof (PALETTEENTRY) * (PALETTESIZE))));
  241.  
  242.           pLogPal->palVersion    = 0x300;
  243.           pLogPal->palNumEntries = PALETTESIZE;
  244.  
  245.           /* fill in intensities for all palette entry colors */
  246.           for (iLoop = 0; iLoop < PALETTESIZE; iLoop++) {
  247.           *((WORD *) (&pLogPal->palPalEntry[iLoop].peRed)) = iLoop;
  248.           pLogPal->palPalEntry[iLoop].peBlue  = 0;
  249.           pLogPal->palPalEntry[iLoop].peFlags = PC_EXPLICIT;
  250.           }
  251.  
  252.           /*  create a logical color palette according the information
  253.            *  in the LOGPALETTE structure.
  254.            */
  255.           hPal = CreatePalette ((LPLOGPALETTE) pLogPal) ;
  256.           break;
  257.  
  258.      case WM_GETMINMAXINFO:
  259.  
  260.           ((LPRGPT)BRK_FP(lParam))->iInfo[6] = nXBorder * 2 + PALETTESIZE;
  261.           ((LPRGPT)BRK_FP(lParam))->iInfo[7] = nXBorder * 2 + nYTitle*3;
  262.  
  263.           return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  264.  
  265.      case WM_PAINT:
  266.  
  267.           /* Divide client width into equal-sized parts, one per palette
  268.            * entry, and re-calculate client width so that it will display
  269.            * exactly as many vertical bars as there are palette entries.
  270.            */
  271.            GetClientRect(hWnd,(LPRECT) &rClientRect);
  272.            nSizeX = (rClientRect.right - rClientRect.left);
  273.            nSizeX = (nSizeX/iNumColors) * iNumColors;
  274.  
  275.            nSizeY = rClientRect.bottom - rClientRect.top;
  276.            GetWindowRect(hWnd,(LPRECT) &rClientRect);
  277.  
  278.           /* Adjust window width so that it can display exactly
  279.            * as many vertical bars( of equal width) as there are palette
  280.            * colors.
  281.            */
  282.  
  283.           SetWindowPos( hWnd,
  284.                 (HWND)NULL,
  285.                 0,
  286.                 0,
  287.                 nSizeX + 2*nXBorder,
  288.                 rClientRect.bottom - rClientRect.top,
  289.                 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  290.  
  291.           hDC = BeginPaint(hWnd, &ps);
  292.  
  293.           /* Select the palette into the window device context and
  294.            * make the Palette Manager map the logical palette to the
  295.            * system palette (realize it).
  296.            */
  297.           SelectPalette (hDC, hPal, 1);
  298.           RealizePalette (hDC);
  299.  
  300.           /* Calculate width of each color bar to be displayed */
  301.           nIncr = nSizeX / iNumColors;
  302.  
  303.           /* Paint the individual bars separately on the app. window */
  304.           for (nStart = iLoop = 0; iLoop < iNumColors; iLoop++){
  305.  
  306.           /* Since this app. uses a logical palette, use the
  307.            * PALETTEINDEX macro to specify the palette entry
  308.            * index instead of using an explicit RGB value.
  309.            */
  310.           hBrush       = CreateSolidBrush (PALETTEINDEX (iLoop));
  311.           dwPal[iLoop] = GetNearestColor (hDC, PALETTEINDEX (iLoop) );
  312.           hOldBrush    = SelectObject (hDC,hBrush) ;
  313.           PatBlt (hDC, nStart, 0, nIncr, nSizeY, PATCOPY);
  314.           nStart       += nIncr;
  315.           SelectObject (hDC, hOldBrush);
  316.           DeleteObject (hBrush) ;
  317.           }
  318.           wsprintf (szTitlebuf, "MyPal Colors= %d", iNumColors);
  319.           SetWindowText (hWnd, (LPSTR)szTitlebuf);
  320.  
  321.           EndPaint(hWnd,&ps);
  322.  
  323.           break ;
  324.  
  325.      case WM_MOUSEMOVE:
  326.  
  327.           if (wParam & MK_RBUTTON) {
  328.  
  329.           /* Convert mouse position to screen coordinates */
  330.           pt.x = LOWORD(lParam);
  331.           pt.y = HIWORD(lParam);
  332.           ClientToScreen(hWnd,&pt);
  333.  
  334.           /* Get RGB value (color) of pixel under mouse coordinate */
  335.           dwColor = GetPixel(hDCGlobal, pt.x, pt.y);
  336.  
  337.           /* If color value already exists in palette lookup table,
  338.            * obtain it's index.
  339.            */
  340.           for (i=0 ; i < iNumColors ; i++)
  341.               if ( dwColor == dwPal[i] )
  342.               break;
  343.           iIndex = i;
  344.  
  345.           /* If previous color value was not identical to current one,
  346.            * display color boxes on either side of title bar,
  347.            * the R, G, B values and palette index of current color.
  348.            */
  349.           if (dwColor != dwLastColor) {
  350.               wsprintf ( szTitlebuf,
  351.                  "MyPal Colors=%d  Index=%d  R=%3u G=%3u B=%3u",
  352.                  iNumColors,
  353.                  iIndex,
  354.                  (WORD)(BYTE) GetRValue (dwColor),
  355.                  (WORD)(BYTE) GetGValue (dwColor),
  356.                  (WORD)(BYTE) GetBValue (dwColor));
  357.               SetWindowText (hWnd, (LPSTR)szTitlebuf);
  358.               ShowColor (hWnd, hDCGlobal);
  359.               dwLastColor = dwColor;
  360.           }
  361.           }
  362.           break;
  363.  
  364.      case WM_RBUTTONDOWN:
  365.  
  366.           /* Determine number of color bar under mouse, thus the index
  367.            * of color in palette.
  368.            */
  369.           x = LOWORD(lParam);
  370.           iIndex = (x / nIncr );
  371.  
  372.           wsprintf ( szTitlebuf,
  373.              "MyPal Colors=%d  Index=%d  PalSize=%d RasterCaps:%d",
  374.              iNumColors,
  375.              iIndex,
  376.              iPalSize,
  377.              iRasterCaps );
  378.  
  379.           SetWindowText (hWnd, (LPSTR)szTitlebuf);
  380.  
  381.           /* Set mouse capture so that subsequent WM_MOUSEMOVEs
  382.            * (with right mouse button depressed) will allow MyPal
  383.            * to display RGB info anywhere on the screen without losing
  384.            * the focus.
  385.            */
  386.           SetCapture (hWnd);
  387.           bCaptureOn = TRUE;
  388.           hDCGlobal = GetDC(NULL);
  389.           if (hPal) {
  390.           SelectPalette (hDCGlobal, hPal, FALSE);
  391.           RealizePalette (hDCGlobal);
  392.           }
  393.           break;
  394.  
  395.      case WM_RBUTTONUP:
  396.           /* Stops displaying RGB and palette info and releases mouse
  397.            * capture
  398.            */
  399.           ReleaseDC (NULL, hDCGlobal);
  400.           bCaptureOn = FALSE;
  401.           ReleaseCapture ();
  402.           break;
  403.  
  404.      case WM_MOVE:
  405.           /* If you have a wide column, this adds 1/2 so X is centered */
  406.           iGlobalXOffset  = LOWORD (lParam);
  407.           iGlobalYOffset  = HIWORD (lParam) + nXBorder;
  408.           break;
  409.  
  410.      case WM_SIZE:
  411.           iYMiddle = (HIWORD (lParam)/2);
  412.           break;
  413.  
  414.      case WM_LBUTTONDOWN:
  415.      case WM_KEYDOWN:
  416.  
  417.          if (iMessage == WM_LBUTTONDOWN){
  418.          /* determine which column was hit by the mouse */
  419.          x = LOWORD(lParam);
  420.          iIndex = (x / nIncr );
  421.          }
  422.          else{
  423.          /* Use arrow keys to step thro' the palette entries */
  424.          switch (wParam) {
  425.              case VK_RIGHT:
  426.              case VK_UP:
  427.                   /* go to next (higher) palette entry */
  428.                   iIndex++;
  429.                   break;
  430.              case VK_LEFT:
  431.              case VK_DOWN:
  432.                   /* go to previous (lower) palette entry */
  433.                   iIndex--;
  434.                   break;
  435.              case VK_NEXT:
  436.                   iIndex += 10;
  437.                   break;
  438.              case VK_PRIOR:
  439.                   iIndex -= 10;
  440.                   break;
  441.              case VK_HOME:
  442.                   /* go to first palette entry */
  443.                   iIndex = 0;
  444.                   break;
  445.              case VK_END:
  446.                   /* go to last palette entry */
  447.                   iIndex = iNumColors-1;
  448.                   break;
  449.              default:
  450.                   return 0L;
  451.          }
  452.          /* Make sure the palette index is within range else
  453.           * set it to the limiting values and give a warning beep.
  454.           */
  455.          if (iIndex < 0) {
  456.              iIndex = 0;
  457.              MessageBeep(1);
  458.          }
  459.          else{
  460.              if (iIndex > iNumColors-1) {
  461.              iIndex = iNumColors-1;
  462.              MessageBeep(1);
  463.               }
  464.          }
  465.  
  466.          pt.x = (iIndex * nIncr) +
  467.             iGlobalXOffset     +
  468.             ((nIncr > 1) ? (nIncr / 2) : 1);
  469.          pt.y = iYMiddle + iGlobalYOffset;
  470.  
  471.          SetCursorPos (pt.x, pt.y);
  472.          }
  473.  
  474.          if (TRUE == bCaptureOn) {
  475.          MessageBeep(1);
  476.          break;
  477.          }
  478.  
  479.          /* Select & realize the palette or the colors > 0x7
  480.           * will not match up.
  481.           */
  482.          hDC = GetDC(NULL);
  483.          SelectPalette  (hDC, hPal, 1);
  484.          RealizePalette (hDC) ;
  485.  
  486.          dwColor = GetNearestColor (hDC, PALETTEINDEX (iIndex));
  487.  
  488.          wsprintf ( szTitlebuf,
  489.             "MyPal Colors=%d  Index=%d  R=%3u G=%3u B=%3u",
  490.             iNumColors,
  491.             iIndex,
  492.             (WORD)(BYTE)GetRValue (dwColor),
  493.             (WORD)(BYTE)GetGValue (dwColor),
  494.             (WORD)(BYTE)GetBValue (dwColor)
  495.              );
  496.  
  497.          SetWindowText (hWnd, (LPSTR)szTitlebuf);
  498.          ShowColor (hWnd,hDC);
  499.          ReleaseDC(NULL, hDC);
  500.          break;
  501.  
  502.      default:
  503.           return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  504.  
  505.     }
  506.     return 0L ;
  507. }
  508.