Annotation of mstools/samples/mypal/mypal.c, revision 1.1.1.1

1.1       root        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 INT     nSizeX;        /* Width of the application window             */
                     25: static INT     nSizeY;        /* Height of the application window            */
                     26: NPLOGPALETTE   pLogPal;       /* Pointer to program's logical palette        */
                     27: INT            nXBorder;      /* Width of window border                      */
                     28: INT            nXTitle;       /* Width of title bar                          */
                     29: INT            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: RECT           rClientRect;   /* Client rectangle coordinates                */
                     37: DWORD   dwPal[PALETTESIZE];   /* Stores palette entries for later lookup     */
                     38: INT            iGlobalXOffset;
                     39: INT            iGlobalYOffset;
                     40: INT            iYMiddle;
                     41: 
                     42: LONG APIENTRY WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam);
                     43: 
                     44: /****************************************************************************
                     45:  *                                                                         *
                     46:  *  FUNCTION   : void ShowColor(HWND hWnd, HDC hDC)                        *
                     47:  *                                                                         *
                     48:  *  PURPOSE    : Displays a little box on each side of the caption bar     *
                     49:  *              displaying the pixel color at the mouse position.          *
                     50:  *                                                                         *
                     51:  ****************************************************************************/
                     52: VOID ShowColor (
                     53:        HWND  hWnd,
                     54:        HDC   hDC)
                     55: {
                     56:      HBRUSH  hBrush, hOldBrush;
                     57: 
                     58:      hBrush    = CreateSolidBrush ( PALETTEINDEX(iIndex) );
                     59:      hOldBrush = SelectObject (hDC,hBrush) ;
                     60: 
                     61:      GetWindowRect (hWnd, (LPRECT)&rClientRect);
                     62: 
                     63:      PatBlt ( hDC,
                     64:              rClientRect.left + nXTitle + nXBorder + 1,
                     65:              rClientRect.top + nXBorder,
                     66:              nXTitle,
                     67:              nYTitle,
                     68:              PATCOPY);
                     69: 
                     70:      PatBlt(hDC,
                     71:            rClientRect.right - ( 3 * nXTitle + nXBorder + 2),
                     72:            rClientRect.top + nXBorder,
                     73:            nXTitle,
                     74:            nYTitle,
                     75:            PATCOPY);
                     76:      SelectObject (hDC, hOldBrush);
                     77:      DeleteObject (hBrush) ;
                     78: }
                     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:     HANDLE hInstance,
                     89:     HANDLE 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: 
                    101:      UNREFERENCED_PARAMETER( lpCmdLine );
                    102: 
                    103:      if (!hPrevInstance){
                    104:         wndclass.style         = CS_HREDRAW | CS_VREDRAW;
                    105:         wndclass.lpfnWndProc   = (WNDPROC) 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   = (INT)GetSystemMetrics (SM_CXFRAME);
                    123:      nXTitle    = (INT)GetSystemMetrics (SM_CXSIZE);
                    124:      nYTitle    = (INT)GetSystemMetrics (SM_CYSIZE);
                    125:      iIndex     = 0;
                    126:      bCaptureOn  = FALSE;
                    127: 
                    128:      hDCGlobal  = GetDC (NULL);
                    129:      iRasterCaps = GetDeviceCaps(hDCGlobal, RASTERCAPS);
                    130:      iRasterCaps = (iRasterCaps & RC_PALETTE) ? TRUE : FALSE;
                    131: 
                    132:      if (iRasterCaps)
                    133:         iNumColors = GetDeviceCaps(hDCGlobal, SIZEPALETTE);
                    134:      else
                    135:         iNumColors = GetDeviceCaps( hDCGlobal, NUMCOLORS);
                    136:      ReleaseDC (NULL,hDCGlobal);
                    137: 
                    138:      nSizeX = ((xScreen - 2*nXBorder) / PALETTESIZE) * PALETTESIZE;
                    139: 
                    140:      /* create the app. window */
                    141:      hWnd = CreateWindow (szAppName,
                    142:                          "My Physical Palette ",
                    143:                          WS_OVERLAPPEDWINDOW,
                    144:                          (xScreen-nSizeX) / 2 - nXBorder,
                    145:                          yScreen - ( 4 * GetSystemMetrics (SM_CYCAPTION)),
                    146:                          nSizeX + 2 * nXBorder,
                    147:                          4 * GetSystemMetrics (SM_CYCAPTION),
                    148:                          NULL,
                    149:                          NULL,
                    150:                          hInstance,
                    151:                          NULL);
                    152:      ShowWindow (hWnd, nCmdShow);
                    153:      UpdateWindow (hWnd);
                    154: 
                    155:      while (GetMessage (&msg, NULL, 0, 0)){
                    156:           TranslateMessage (&msg) ;
                    157:           DispatchMessage (&msg) ;
                    158:      }
                    159: 
                    160:      return msg.wParam ;
                    161: }
                    162: 
                    163: /******************************************************************************
                    164:  *                                                                           *
                    165:  *  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)                            *
                    166:  *                                                                           *
                    167:  *  PURPOSE:  Processes window messages and sets up a 256 bar representation  *
                    168:  *           of the current physical palette. Specifically, in response to:  *
                    169:  *                                                                           *
                    170:  *              WM_CREATE  -Allocates for and sets up a LOGPALETTE           *
                    171:  *                          structure, creates a logical palette the same    *
                    172:  *                          size as the physical palette and obtains a       *
                    173:  *                          handle to the logical palette.                   *
                    174:  *                                                                           *
                    175:  *              WM_DESTROY -Destroys the logical palette and shuts down app. *
                    176:  *                                                                           *
                    177:  *              WM_PAINT   -Resizes client area to hold as many vertical     *
                    178:  *                          color bars as there are physical palette entries.*
                    179:  *                          Also realises the current logical palette and    *
                    180:  *                          draws one color bar corresponding to each        *
                    181:  *                          palette entry                                    *
                    182:  *                                                                           *
                    183:  *          WM_RBUTTONDOWN -Captures the mouse and initiates the below       *
                    184:  *                          process:                                         *
                    185:  *                                                                           *
                    186:  *          WM_MOUSEMOVE   -Following a WM_RBUTTONDOWN, if the right mouse   *
                    187:  *                          key is depressed, displays info about the        *
                    188:  *                          pixel RGB value and palette index of the mouse   *
                    189:  *                          coordinates.                                     *
                    190:  *                                                                           *
                    191:  *          WM_RBUTTONUP   -Release mouse capture and terminates the above   *
                    192:  *                          process                                          *
                    193:  *                                                                           *
                    194:  *          WM_LBUTTONDOWN -Determines and displays the palette index and    *
                    195:  *                          RGB value of the bar under the mouse.            *
                    196:  *                                                                           *
                    197:  *          WM_KEYDOWN     -Allows use of the arrow keys in stepping thro'   *
                    198:  *                          palette entries.                                 *
                    199:  *                                                                           *
                    200:  *****************************************************************************/
                    201: LONG APIENTRY WndProc (
                    202:     HWND        hWnd,
                    203:     UINT     iMessage,
                    204:     UINT        wParam,
                    205:     LONG        lParam)
                    206: {
                    207:     HDC          hDC;
                    208:     PAINTSTRUCT   ps;
                    209:     INT                  iLoop;
                    210:     INT          nStart;
                    211:     HBRUSH       hBrush;
                    212:     HBRUSH       hOldBrush;
                    213: 
                    214:     MPOINT       pt;
                    215:     static INT    nIncr;
                    216:     static DWORD  dwColor;
                    217:     static DWORD  dwLastColor;
                    218:     static INT   i, x;
                    219: 
                    220:     switch (iMessage) {
                    221:         case WM_DESTROY:
                    222:              /* delete the handle to the logical palette if it has any
                    223:               * color entries and quit.
                    224:               */
                    225:              if (pLogPal->palNumEntries)
                    226:                  DeleteObject (hPal);
                    227:              PostQuitMessage (0) ;
                    228:              break ;
                    229: 
                    230:         case WM_CREATE:
                    231:              /* Allocate enough memory for a logical palette with
                    232:               * PALETTESIZE entries and set the size and version fields
                    233:               * of the logical palette structure.
                    234:               */
                    235:              pLogPal = (NPLOGPALETTE) LocalAlloc (LMEM_FIXED,
                    236:                                                  (sizeof (LOGPALETTE) +
                    237:                                                  (sizeof (PALETTEENTRY) * (PALETTESIZE))));
                    238: 
                    239:           if(!pLogPal){
                    240:             MessageBox(hWnd, "<WM_CREATE> Not enough memory for palette.", NULL, MB_OK | MB_ICONHAND);
                    241:                PostQuitMessage (0) ;
                    242:             break;
                    243:           }
                    244: 
                    245:              pLogPal->palVersion    = 0x300;
                    246:              pLogPal->palNumEntries = PALETTESIZE;
                    247: 
                    248:              /* fill in intensities for all palette entry colors */
                    249:              for (iLoop = 0; iLoop < PALETTESIZE; iLoop++) {
                    250:                  *((WORD *) (&pLogPal->palPalEntry[iLoop].peRed)) = (WORD)iLoop;
                    251:                  pLogPal->palPalEntry[iLoop].peBlue  = 0;
                    252:                  pLogPal->palPalEntry[iLoop].peFlags = PC_EXPLICIT;
                    253:              }
                    254: 
                    255:              /*  create a logical color palette according the information
                    256:               *  in the LOGPALETTE structure.
                    257:               */
                    258:              hPal = CreatePalette ((LPLOGPALETTE) pLogPal) ;
                    259:              break;
                    260: 
                    261:         case WM_GETMINMAXINFO:
                    262: 
                    263:              ((LPRGPT)lParam)->iInfo[6] = nXBorder * 2 + PALETTESIZE;
                    264:              ((LPRGPT)lParam)->iInfo[7] = nXBorder * 2 + nYTitle*3;
                    265: 
                    266:              return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
                    267:              break;
                    268: 
                    269:         case WM_PAINT:
                    270: 
                    271:              /* Divide client width into equal-sized parts, one per palette
                    272:               * entry, and re-calculate client width so that it will display
                    273:               * exactly as many vertical bars as there are palette entries.
                    274:               */
                    275:               GetClientRect(hWnd,(LPRECT) &rClientRect);
                    276:               nSizeX = (rClientRect.right - rClientRect.left);
                    277:               nSizeX = (nSizeX/iNumColors) * iNumColors;
                    278: 
                    279:               nSizeY = rClientRect.bottom - rClientRect.top;
                    280:               GetWindowRect(hWnd,(LPRECT) &rClientRect);
                    281: 
                    282:              /* Adjust window width so that it can display exactly
                    283:               * as many vertical bars( of equal width) as there are palette
                    284:               * colors.
                    285:               */
                    286: 
                    287:              SetWindowPos( hWnd,
                    288:                            (HWND)NULL,
                    289:                            0,
                    290:                            0,
                    291:                            nSizeX + 2*nXBorder,
                    292:                            rClientRect.bottom - rClientRect.top,
                    293:                            SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
                    294: 
                    295:              hDC = BeginPaint(hWnd, &ps);
                    296: 
                    297:              /* Select the palette into the window device context and
                    298:               * make the Palette Manager map the logical palette to the
                    299:               * system palette (realize it).
                    300:               */
                    301:              SelectPalette (hDC, hPal, 1);
                    302:              RealizePalette (hDC);
                    303: 
                    304:              /* Calculate width of each color bar to be displayed */
                    305:              nIncr = nSizeX / iNumColors;
                    306: 
                    307:              /* Paint the individual bars separately on the app. window */
                    308:              for (nStart = iLoop = 0; iLoop < iNumColors; iLoop++){
                    309: 
                    310:                  /* Since this app. uses a logical palette, use the
                    311:                   * PALETTEINDEX macro to specify the palette entry
                    312:                   * index instead of using an explicit RGB value.
                    313:                   */
                    314:                  hBrush       = CreateSolidBrush (PALETTEINDEX (iLoop));
                    315:                  dwPal[iLoop] = GetNearestColor (hDC, PALETTEINDEX (iLoop) );
                    316:                  hOldBrush    = SelectObject (hDC,hBrush) ;
                    317:                  PatBlt (hDC, nStart, 0, nIncr, nSizeY, PATCOPY);
                    318:                  nStart       += nIncr;
                    319:                  SelectObject (hDC, hOldBrush);
                    320:                  DeleteObject (hBrush) ;
                    321:              }
                    322:              wsprintf (szTitlebuf, "MyPal Colors= %d", iNumColors);
                    323:              SetWindowText (hWnd, (LPSTR)szTitlebuf);
                    324: 
                    325:              EndPaint(hWnd,&ps);
                    326: 
                    327:              break ;
                    328: 
                    329:         case WM_MOUSEMOVE:
                    330: 
                    331:              if (wParam & MK_RBUTTON) {
                    332: 
                    333:           POINT pt;
                    334:                   
                    335: #ifdef WIN16
                    336:                  /* Convert mouse position to screen coordinates */
                    337:                  pt.x = LOWORD(lParam);
                    338:                  pt.y = HIWORD(lParam);
                    339: #else
                    340:                  LONG2POINT(lParam, pt);       
                    341: #endif
                    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: 
                    376:              /* Determine number of color bar under mouse, thus the index
                    377:               * of color in palette.
                    378:               */
                    379:              x = LOWORD(lParam);
                    380:              iIndex = (x / nIncr );
                    381: 
                    382:              wsprintf ( szTitlebuf,
                    383:                         "MyPal Colors=%d  Index=%d  PalSize=%d RasterCaps:%d",
                    384:                         iNumColors,
                    385:                         iIndex,
                    386:                         iNumColors,
                    387:                         iRasterCaps );
                    388: 
                    389:              SetWindowText (hWnd, (LPSTR)szTitlebuf);
                    390: 
                    391:              /* Set mouse capture so that subsequent WM_MOUSEMOVEs
                    392:               * (with right mouse button depressed) will allow MyPal
                    393:               * to display RGB info anywhere on the screen without losing
                    394:               * the focus.
                    395:               */
                    396:              SetCapture (hWnd);
                    397:              bCaptureOn = TRUE;
                    398:              hDCGlobal = GetDC(NULL);
                    399:              if (hPal) {
                    400:                  SelectPalette (hDCGlobal, hPal, FALSE);
                    401:                  RealizePalette (hDCGlobal);
                    402:              }
                    403:              break;
                    404: 
                    405:         case WM_RBUTTONUP:
                    406:              /* Stops displaying RGB and palette info and releases mouse
                    407:               * capture
                    408:               */
                    409:              ReleaseDC (NULL, hDCGlobal);
                    410:              bCaptureOn = FALSE;
                    411:              ReleaseCapture ();
                    412:              break;
                    413: 
                    414:         case WM_MOVE:
                    415:              /* If you have a wide column, this adds 1/2 so X is centered */
                    416:              iGlobalXOffset  = LOWORD (lParam);
                    417:              iGlobalYOffset  = HIWORD (lParam) + nXBorder;
                    418:              break;
                    419: 
                    420:         case WM_SIZE:
                    421:              iYMiddle = (HIWORD (lParam)/2);
                    422:              break;
                    423: 
                    424:         case WM_LBUTTONDOWN:
                    425:         case WM_KEYDOWN:
                    426: 
                    427:             if (iMessage == WM_LBUTTONDOWN){
                    428:                 /* determine which column was hit by the mouse */
                    429:                 x = LOWORD(lParam);
                    430:                 iIndex = (x / nIncr );
                    431:             }
                    432:             else{
                    433:                 /* Use arrow keys to step thro' the palette entries */
                    434:                 switch (wParam) {
                    435:                     case VK_RIGHT:
                    436:                     case VK_UP:
                    437:                                  /* go to next (higher) palette entry */
                    438:                                  iIndex++;
                    439:                                  break;
                    440:                     case VK_LEFT:
                    441:                     case VK_DOWN:
                    442:                                  /* go to previous (lower) palette entry */
                    443:                                  iIndex--;
                    444:                                  break;
                    445:                     case VK_NEXT:
                    446:                                  iIndex += 10;
                    447:                                  break;
                    448:                     case VK_PRIOR:
                    449:                                  iIndex -= 10;
                    450:                                  break;
                    451:                     case VK_HOME:
                    452:                                  /* go to first palette entry */
                    453:                                  iIndex = 0;
                    454:                                  break;
                    455:                     case VK_END:
                    456:                                  /* go to last palette entry */
                    457:                                  iIndex = iNumColors-1;
                    458:                                  break;
                    459:                     default:
                    460:                                  return 0L;
                    461:                                  break;
                    462:                 }
                    463:                 /* Make sure the palette index is within range else
                    464:                  * set it to the limiting values and give a warning beep.
                    465:                  */
                    466:                 if (iIndex < 0) {
                    467:                     iIndex = 0;
                    468:                     MessageBeep(1);
                    469:                 }
                    470:                 else{
                    471:                     if (iIndex > iNumColors-1) {
                    472:                         iIndex = iNumColors-1;
                    473:                         MessageBeep(1);
                    474:                      }
                    475:                 }
                    476: 
                    477:                 pt.x = (SHORT)((iIndex * nIncr) +
                    478:                        iGlobalXOffset   +
                    479:                        ((nIncr > 1) ? (nIncr / 2) : 1));
                    480:                 pt.y = (SHORT)(iYMiddle + iGlobalYOffset);
                    481: 
                    482:                 SetCursorPos (pt.x, pt.y);
                    483:             }
                    484: 
                    485:             if (TRUE == bCaptureOn) {
                    486:                 MessageBeep(1);
                    487:                 break;
                    488:             }
                    489: 
                    490:             /* Select & realize the palette or the colors > 0x7
                    491:              * will not match up.
                    492:              */
                    493:             hDC = GetDC(NULL);
                    494:             SelectPalette  (hDC, hPal, 1);
                    495:             RealizePalette (hDC) ;
                    496: 
                    497:             dwColor = GetNearestColor (hDC, PALETTEINDEX (iIndex));
                    498: 
                    499:             wsprintf ( szTitlebuf,
                    500:                        "MyPal Colors=%d  Index=%d  R=%3u G=%3u B=%3u",
                    501:                        iNumColors,
                    502:                        iIndex,
                    503:                        (WORD)(BYTE)GetRValue (dwColor),
                    504:                        (WORD)(BYTE)GetGValue (dwColor),
                    505:                        (WORD)(BYTE)GetBValue (dwColor)
                    506:                     );
                    507: 
                    508:             SetWindowText (hWnd, (LPSTR)szTitlebuf);
                    509:             ShowColor (hWnd,hDC);
                    510:             ReleaseDC(NULL, hDC);
                    511:             break;
                    512: 
                    513:         default:
                    514:              return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
                    515: 
                    516:     }
                    517:     return 0L ;
                    518: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.