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