home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / MYPAL / MYPAL.C_ / MYPAL.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  17.2 KB  |  550 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 __export WndProc (HWND, UINT, WPARAM, LPARAM);
  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.      char szCantLoad [256];
  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 = COLOR_WINDOW+1;
  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.      /* Don't take on displaying more than 256 colors */
  141.      if (iNumColors > PALETTESIZE) {
  142.      if ( LoadString (hInstance, IDSCANTLOAD,
  143.               szCantLoad, sizeof (szCantLoad)))
  144.          MessageBox (NULL, szCantLoad, szAppName, MB_OK|MB_ICONEXCLAMATION);
  145.      return FALSE;
  146.      }
  147.  
  148.      nSizeX = ((xScreen - 2*nXBorder) / PALETTESIZE) * PALETTESIZE;
  149.  
  150.      /* create the app. window */
  151.      hWnd = CreateWindow (szAppName,
  152.               "My Physical Palette ",
  153.               WS_OVERLAPPEDWINDOW,
  154.               (xScreen-nSizeX) / 2 - nXBorder,
  155.               yScreen - ( 4 * GetSystemMetrics (SM_CYCAPTION)),
  156.               nSizeX + 2 * nXBorder,
  157.               4 * GetSystemMetrics (SM_CYCAPTION),
  158.               NULL,
  159.               NULL,
  160.               hInstance,
  161.               NULL);
  162.      ShowWindow (hWnd, nCmdShow);
  163.      UpdateWindow (hWnd);
  164.  
  165.      while (GetMessage (&msg, NULL, 0, 0)){
  166.        TranslateMessage (&msg) ;
  167.        DispatchMessage (&msg) ;
  168.      }
  169.  
  170.      return msg.wParam ;
  171. }
  172.  
  173. /******************************************************************************
  174.  *                                          *
  175.  *  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)                  *
  176.  *                                          *
  177.  *  PURPOSE:  Processes window messages and sets up a 256 bar representation  *
  178.  *          of the current physical palette. Specifically, in response to:  *
  179.  *                                          *
  180.  *         WM_CREATE  -Allocates for and sets up a LOGPALETTE          *
  181.  *                 structure, creates a logical palette the same    *
  182.  *                 size as the physical palette and obtains a       *
  183.  *                 handle to the logical palette.              *
  184.  *                                          *
  185.  *         WM_DESTROY -Destroys the logical palette and shuts down app. *
  186.  *                                          *
  187.  *         WM_PAINT   -Resizes client area to hold as many vertical     *
  188.  *                 color bars as there are physical palette entries.*
  189.  *                 Also realises the current logical palette and    *
  190.  *                 draws one color bar corresponding to each          *
  191.  *                 palette entry                      *
  192.  *                                          *
  193.  *         WM_RBUTTONDOWN -Captures the mouse and initiates the below       *
  194.  *                 process:                          *
  195.  *                                          *
  196.  *         WM_MOUSEMOVE   -Following a WM_RBUTTONDOWN, if the right mouse   *
  197.  *                 key is depressed, displays info about the          *
  198.  *                 pixel RGB value and palette index of the mouse   *
  199.  *                 coordinates.                      *
  200.  *                                          *
  201.  *         WM_RBUTTONUP   -Release mouse capture and terminates the above   *
  202.  *                 process                          *
  203.  *                                          *
  204.  *         WM_LBUTTONDOWN -Determines and displays the palette index and    *
  205.  *                 RGB value of the bar under the mouse.          *
  206.  *                                          *
  207.  *         WM_KEYDOWN     -Allows use of the arrow keys in stepping thro'   *
  208.  *                 palette entries.                      *
  209.  *                                          *
  210.  *****************************************************************************/
  211. long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
  212.  
  213. HWND     hWnd;
  214. UINT iMessage;
  215. WPARAM     wParam;
  216. LPARAM     lParam;
  217.  
  218. {
  219.     HDC       hDC;
  220.     PAINTSTRUCT   ps;
  221.     WORD      iLoop;
  222.     WORD      nStart;
  223.     HBRUSH      hBrush;
  224.     HBRUSH      hOldBrush;
  225.  
  226.     POINT      pt;
  227.     static WORD   nIncr;
  228.     static DWORD  dwColor;
  229.     static DWORD  dwLastColor;
  230.     static int      i, x;
  231.  
  232.     switch (iMessage){
  233.      case WM_DESTROY:
  234.           /* delete the handle to the logical palette if it has any
  235.            * color entries and quit.
  236.            */
  237.           if (pLogPal->palNumEntries)
  238.           DeleteObject (hPal);
  239.           PostQuitMessage (0) ;
  240.           break ;
  241.  
  242.      case WM_CREATE:
  243.           /* Allocate enough memory for a logical palette with
  244.            * PALETTESIZE entries and set the size and version fields
  245.            * of the logical palette structure.
  246.            */
  247.           pLogPal = (NPLOGPALETTE) LocalAlloc (LMEM_FIXED,
  248.                           (sizeof (LOGPALETTE) +
  249.                           (sizeof (PALETTEENTRY) * (PALETTESIZE))));
  250.  
  251.           pLogPal->palVersion    = 0x300;
  252.           pLogPal->palNumEntries = PALETTESIZE;
  253.  
  254.           /* fill in intensities for all palette entry colors */
  255.           for (iLoop = 0; iLoop < PALETTESIZE; iLoop++) {
  256.           *((WORD *) (&pLogPal->palPalEntry[iLoop].peRed)) = iLoop;
  257.           pLogPal->palPalEntry[iLoop].peBlue  = 0;
  258.           pLogPal->palPalEntry[iLoop].peFlags = PC_EXPLICIT;
  259.           }
  260.  
  261.           /*  create a logical color palette according the information
  262.            *  in the LOGPALETTE structure.
  263.            */
  264.           hPal = CreatePalette ((LPLOGPALETTE) pLogPal) ;
  265.           break;
  266.  
  267.      case WM_GETMINMAXINFO:
  268.  
  269.           ((LPRGPT)lParam)->iInfo[6] = nXBorder * 2 + PALETTESIZE;
  270.           ((LPRGPT)lParam)->iInfo[7] = nXBorder * 2 + nYTitle*3;
  271.  
  272.           return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  273.           break;
  274.  
  275.      case WM_PAINT:
  276.  
  277.           /* Divide client width into equal-sized parts, one per palette
  278.            * entry, and re-calculate client width so that it will display
  279.            * exactly as many vertical bars as there are palette entries.
  280.            */
  281.            GetClientRect(hWnd,(LPRECT) &rClientRect);
  282.            nSizeX = (rClientRect.right - rClientRect.left);
  283.            nSizeX = (nSizeX/iNumColors) * iNumColors;
  284.  
  285.            nSizeY = rClientRect.bottom - rClientRect.top;
  286.            GetWindowRect(hWnd,(LPRECT) &rClientRect);
  287.  
  288.           /* Adjust window width so that it can display exactly
  289.            * as many vertical bars( of equal width) as there are palette
  290.            * colors.
  291.            */
  292.  
  293.           SetWindowPos( hWnd,
  294.                 (HWND)NULL,
  295.                 0,
  296.                 0,
  297.                 nSizeX + 2*nXBorder,
  298.                 rClientRect.bottom - rClientRect.top,
  299.                 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  300.  
  301.           hDC = BeginPaint(hWnd, &ps);
  302.  
  303.           /* Select the palette into the window device context and
  304.            * make the Palette Manager map the logical palette to the
  305.            * system palette (realize it).
  306.            */
  307.           SelectPalette (hDC, hPal, 1);
  308.           RealizePalette (hDC);
  309.  
  310.           /* Calculate width of each color bar to be displayed */
  311.           nIncr = nSizeX / iNumColors;
  312.  
  313.           /* Paint the individual bars separately on the app. window */
  314.           for (nStart = iLoop = 0; iLoop < (WORD)iNumColors; iLoop++){
  315.  
  316.           /* Since this app. uses a logical palette, use the
  317.            * PALETTEINDEX macro to specify the palette entry
  318.            * index instead of using an explicit RGB value.
  319.            */
  320.           hBrush       = CreateSolidBrush (PALETTEINDEX (iLoop));
  321.           dwPal[iLoop] = GetNearestColor (hDC, PALETTEINDEX (iLoop) );
  322.           hOldBrush    = SelectObject (hDC,hBrush) ;
  323.           PatBlt (hDC, nStart, 0, nIncr, nSizeY, PATCOPY);
  324.           nStart       += nIncr;
  325.           SelectObject (hDC, hOldBrush);
  326.           DeleteObject (hBrush) ;
  327.           }
  328.           wsprintf (szTitlebuf, "MyPal Colors= %d", iNumColors);
  329.           SetWindowText (hWnd, (LPSTR)szTitlebuf);
  330.  
  331.           EndPaint(hWnd,&ps);
  332.  
  333.           break ;
  334.  
  335.      case WM_MOUSEMOVE:
  336.  
  337.           if (wParam & MK_RBUTTON) {
  338.  
  339.           /* Convert mouse position to screen coordinates */
  340.           pt.x = LOWORD(lParam);
  341.           pt.y = HIWORD(lParam);
  342.           ClientToScreen(hWnd,&pt);
  343.  
  344.           /* Get RGB value (color) of pixel under mouse coordinate */
  345.           dwColor = GetPixel(hDCGlobal, pt.x, pt.y);
  346.  
  347.           /* If color value already exists in palette lookup table,
  348.            * obtain it's index.
  349.            */
  350.           for (i=0 ; i < iNumColors ; i++)
  351.               if ( dwColor == dwPal[i] )
  352.               break;
  353.           iIndex = i;
  354.  
  355.           /* If previous color value was not identical to current one,
  356.            * display color boxes on either side of title bar,
  357.            * the R, G, B values and palette index of current color.
  358.            */
  359.           if (dwColor != dwLastColor) {
  360.               wsprintf ( szTitlebuf,
  361.                  "MyPal Colors=%d  Index=%d  R=%3u G=%3u B=%3u",
  362.                  iNumColors,
  363.                  iIndex,
  364.                  (WORD)(BYTE) GetRValue (dwColor),
  365.                  (WORD)(BYTE) GetGValue (dwColor),
  366.                  (WORD)(BYTE) GetBValue (dwColor));
  367.               SetWindowText (hWnd, (LPSTR)szTitlebuf);
  368.               ShowColor (hWnd, hDCGlobal);
  369.               dwLastColor = dwColor;
  370.           }
  371.           }
  372.           break;
  373.  
  374.      case WM_RBUTTONDOWN:
  375.            hDC = BeginPaint(hWnd, &ps);
  376.  
  377.           /* Select the palette into the window device context and
  378.            * make the Palette Manager map the logical palette to the
  379.            * system palette (realize it).
  380.            */
  381.           SelectPalette (hDC, hPal, 1);
  382.           RealizePalette (hDC);
  383.  
  384.           /* Calculate width of each color bar to be displayed */
  385.           nIncr = nSizeX / iNumColors;
  386.  
  387.           /* Paint the individual bars separately on the app. window */
  388.           for (nStart = iLoop = 0; iLoop < (WORD)iNumColors; iLoop++){
  389.  
  390.           /* Since this app. uses a logical palette, use the
  391.            * PALETTEINDEX macro to specify the palette entry
  392.            * index instead of using an explicit RGB value.
  393.            */
  394.           hBrush       = CreateSolidBrush (PALETTEINDEX (iLoop));
  395.           dwPal[iLoop] = GetNearestColor (hDC, PALETTEINDEX (iLoop) );
  396.           hOldBrush    = SelectObject (hDC,hBrush) ;
  397.           PatBlt (hDC, nStart, 0, nIncr, nSizeY, PATCOPY);
  398.           nStart       += nIncr;
  399.           SelectObject (hDC, hOldBrush);
  400.           DeleteObject (hBrush) ;
  401.           }
  402.           wsprintf (szTitlebuf, "MyPal Colors= %d", iNumColors);
  403.           SetWindowText (hWnd, (LPSTR)szTitlebuf);
  404.  
  405.           EndPaint(hWnd,&ps);
  406.  
  407.           /* Determine number of color bar under mouse, thus the index
  408.            * of color in palette.
  409.            */
  410.           x = LOWORD(lParam);
  411.           iIndex = (x / nIncr );
  412.  
  413.           wsprintf ( szTitlebuf,
  414.              "MyPal Colors=%d  Index=%d  PalSize=%d RasterCaps:%d",
  415.              iNumColors,
  416.              iIndex,
  417.              iPalSize,
  418.              iRasterCaps );
  419.  
  420.           SetWindowText (hWnd, (LPSTR)szTitlebuf);
  421.  
  422.           /* Set mouse capture so that subsequent WM_MOUSEMOVEs
  423.            * (with right mouse button depressed) will allow MyPal
  424.            * to display RGB info anywhere on the screen without losing
  425.            * the focus.
  426.            */
  427.           SetCapture (hWnd);
  428.           bCaptureOn = TRUE;
  429.           hDCGlobal = GetDC(NULL);
  430.           if (hPal) {
  431.           SelectPalette (hDCGlobal, hPal, FALSE);
  432.           RealizePalette (hDCGlobal);
  433.           }
  434.           break;
  435.  
  436.      case WM_RBUTTONUP:
  437.           /* Stops displaying RGB and palette info and releases mouse
  438.            * capture
  439.            */
  440.           ReleaseDC (NULL, hDCGlobal);
  441.           bCaptureOn = FALSE;
  442.           ReleaseCapture ();
  443.           break;
  444.  
  445.      case WM_MOVE:
  446.           /* If you have a wide column, this adds 1/2 so X is centered */
  447.           iGlobalXOffset  = LOWORD (lParam);
  448.           iGlobalYOffset  = HIWORD (lParam) + nXBorder;
  449.           break;
  450.  
  451.      case WM_SIZE:
  452.           iYMiddle = (HIWORD (lParam)/2);
  453.           break;
  454.  
  455.      case WM_LBUTTONDOWN:
  456.      case WM_KEYDOWN:
  457.  
  458.          if (iMessage == WM_LBUTTONDOWN){
  459.          /* determine which column was hit by the mouse */
  460.          x = LOWORD(lParam);
  461.          iIndex = (x / nIncr );
  462.          }
  463.          else{
  464.          /* Use arrow keys to step thro' the palette entries */
  465.          switch (wParam) {
  466.              case VK_RIGHT:
  467.              case VK_UP:
  468.                   /* go to next (higher) palette entry */
  469.                   iIndex++;
  470.                   break;
  471.              case VK_LEFT:
  472.              case VK_DOWN:
  473.                   /* go to previous (lower) palette entry */
  474.                   iIndex--;
  475.                   break;
  476.              case VK_NEXT:
  477.                   iIndex += 10;
  478.                   break;
  479.              case VK_PRIOR:
  480.                   iIndex -= 10;
  481.                   break;
  482.              case VK_HOME:
  483.                   /* go to first palette entry */
  484.                   iIndex = 0;
  485.                   break;
  486.              case VK_END:
  487.                   /* go to last palette entry */
  488.                   iIndex = iNumColors-1;
  489.                   break;
  490.              default:
  491.                   return 0L;
  492.                   break;
  493.          }
  494.          /* Make sure the palette index is within range else
  495.           * set it to the limiting values and give a warning beep.
  496.           */
  497.          if (iIndex < 0) {
  498.              iIndex = 0;
  499.              MessageBeep(1);
  500.          }
  501.          else{
  502.              if (iIndex > iNumColors-1) {
  503.              iIndex = iNumColors-1;
  504.              MessageBeep(1);
  505.               }
  506.          }
  507.  
  508.          pt.x = (iIndex * nIncr) +
  509.             iGlobalXOffset     +
  510.             ((nIncr > 1) ? (nIncr / 2) : 1);
  511.          pt.y = iYMiddle + iGlobalYOffset;
  512.  
  513.          SetCursorPos (pt.x, pt.y);
  514.          }
  515.  
  516.          if (TRUE == bCaptureOn) {
  517.          MessageBeep(1);
  518.          break;
  519.          }
  520.  
  521.          /* Select & realize the palette or the colors > 0x7
  522.           * will not match up.
  523.           */
  524.          hDC = GetDC(NULL);
  525.          SelectPalette  (hDC, hPal, 1);
  526.          RealizePalette (hDC) ;
  527.  
  528.          dwColor = GetNearestColor (hDC, PALETTEINDEX (iIndex));
  529.  
  530.          wsprintf ( szTitlebuf,
  531.             "MyPal Colors=%d  Index=%d  R=%3u G=%3u B=%3u",
  532.             iNumColors,
  533.             iIndex,
  534.             (WORD)(BYTE)GetRValue (dwColor),
  535.             (WORD)(BYTE)GetGValue (dwColor),
  536.             (WORD)(BYTE)GetBValue (dwColor)
  537.              );
  538.  
  539.          SetWindowText (hWnd, (LPSTR)szTitlebuf);
  540.          ShowColor (hWnd,hDC);
  541.          ReleaseDC(NULL, hDC);
  542.          break;
  543.  
  544.      default:
  545.           return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  546.  
  547.     }
  548.     return 0L ;
  549. }
  550.