MYPAL.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:22k
源码类别:

Windows编程

开发平台:

Visual C++

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