Annotation of mstools/samples/mypal/mypal.c, revision 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.