Annotation of mstools/samples/showdib/showdib.c, revision 1.1.1.2

1.1       root        1: /*******************************************************************************
                      2:  *                                                                            *
                      3:  *  PROGRAM    : ShowDIB.c                                                    *
                      4:  *                                                                            *
                      5:  *  PURPOSE    : Application to illustrate the use of the GDI                 *
                      6:  *               DIB (Device Independent Bitmap) and Palette manager          *
                      7:  *               functions.                                                   *
                      8:  *                                                                            *
                      9:  *  FUNCTIONS  : WinMain ()             -  Creates the app. window and enters *
                     10:  *                                         the message loop.                  *
                     11:  *                                                                            *
                     12:  *               WndProc()              -  Processes app. window messages.    *
                     13:  *                                                                            *
                     14:  *               MenuCommand()          -  Processes menu commands.           *
                     15:  *                                                                            *
                     16:  *               FreeDIB()              -  Frees currently active objects.    *
                     17:  *                                                                            *
                     18:  *               InitDIB()              -  Reads DIB from a file and loads it.*
                     19:  *                                                                            *
                     20:  *******************************************************************************/
                     21: 
                     22: #include <windows.h>
                     23: #include <io.h>
                     24: #include <stdio.h>
                     25: #include "showdib.h"
                     26: #include <commdlg.h>
                     27: 
                     28: DIBPARAMS      DIBParams;                 /* params for the SETSCALING escape */
                     29: CHAR          achFileName[128] = "";
                     30: DWORD          dwOffset;
                     31: NPLOGPALETTE   pLogPal;
                     32: HPALETTE       hpalSave = NULL;
                     33: HANDLE        hInst ;
                     34: RECT          rcClip;
                     35: static        HCURSOR hcurSave;
                     36: 
                     37: BOOL   fPalColors  = FALSE;          /* TRUE if the current DIB's color table   */
                     38:                                      /* contains palette indexes not rgb values */
                     39: UINT   nAnimating  = 0;              /* Palette animation count                 */
                     40: WORD   UpdateCount = 0;
                     41: 
                     42: BOOL   bUpdateColors = TRUE;  /* Directly update screen colors                */
                     43: BOOL   bDIBToDevice  = FALSE; /* Use SetDIBitsToDevice() to BLT data.         */
                     44: BOOL   bNoUgly       = FALSE; /* Make window black on a WM_PALETTEISCHANGING  */
                     45: BOOL   bLegitDraw    = FALSE; /* We have a valid bitmap to draw               */
                     46: 
                     47: CHAR   szBitmapExt[] = "*.BMP; *.DIB; *.RLE";     /* possible file extensions */
                     48: WORD   wTransparent  = TRANSPARENT;               /* Mode of DC               */
                     49: CHAR   szAppName[]   = "ShowDIB" ;                /* App. name                */
                     50: 
                     51: HPALETTE hpalCurrent   = NULL;        /* Handle to current palette            */
                     52: HANDLE  hdibCurrent   = NULL;         /* Handle to current memory DIB         */
                     53: HBITMAP  hbmCurrent    = NULL;        /* Handle to current memory BITMAP      */
                     54: HANDLE  hbiCurrent    = NULL;         /* Handle to current bitmap info struct */
                     55: HWND    hWndApp;                      /* Handle to app. window                */
                     56: 
                     57: /* Styles of app. window */
                     58: DWORD         dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
                     59:                         WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME;
                     60: 
                     61: VOID PrintDIB (HWND hWnd, HDC hDC, INT x, INT y, INT dx, INT dy);
                     62: /****************************************************************************
                     63:  *                                                                         *
                     64:  *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)                       *
                     65:  *                                                                         *
                     66:  *  PURPOSE    : Creates the app. window and enters the message loop.      *
                     67:  *                                                                         *
                     68:  ****************************************************************************/
                     69: int APIENTRY WinMain(
                     70:     HANDLE hInstance,
                     71:     HANDLE hPrevInstance,
                     72:     LPSTR lpCmdLine,
                     73:     int nCmdShow
                     74:     )
                     75: {
                     76:      HWND       hWnd ;
                     77:      WNDCLASS   wndclass ;
                     78:      MSG        msg ;
                     79:      int        xScreen, yScreen ;
                     80:      CHAR       ach[40];
                     81: 
                     82:      hInst = hInstance ;
                     83: 
                     84:      /* Initialize clip rectangle */
                     85:      SetRectEmpty(&rcClip);
                     86: 
                     87:      if (!hPrevInstance) {
                     88:         wndclass.style         = CS_DBLCLKS;
                     89:         wndclass.lpfnWndProc   = (WNDPROC) WndProc ;
                     90:         wndclass.cbClsExtra    = 0 ;
                     91:         wndclass.cbWndExtra    = 0 ;
                     92:         wndclass.hInstance     = hInstance ;
                     93:         wndclass.hIcon         = LoadIcon(hInst, "SHOWICON");
                     94:         wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
                     95:         wndclass.hbrBackground = GetStockObject (BLACK_BRUSH) ;
                     96:         wndclass.lpszMenuName  = szAppName ;
                     97:         wndclass.lpszClassName = szAppName ;
                     98: 
                     99:         if (!RegisterClass (&wndclass))
                    100:                 return FALSE ;
                    101:      }
                    102: 
                    103:      if (!GetProfileString("extensions", "bmp", "", ach, sizeof(ach)))
                    104:             WriteProfileString("extensions", "bmp", "showdib.exe ^.bmp");
                    105:      if (!GetProfileString("extensions", "dib", "", ach, sizeof(ach)))
                    106:             WriteProfileString("extensions", "dib", "showdib.exe ^.dib");
                    107: 
                    108:      /* Save the pointer to the command line */
                    109:      lstrcpy(achFileName, lpCmdLine);
                    110: 
                    111:      xScreen = GetSystemMetrics (SM_CXSCREEN) ;
                    112:      yScreen = GetSystemMetrics (SM_CYSCREEN) ;
                    113: 
                    114:      /* Create the app. window */
                    115:      hWnd = CreateWindow( szAppName,
                    116:                          szAppName,
                    117:                          dwStyle,
                    118:                          CW_USEDEFAULT,
                    119:                          0,
                    120:                          xScreen / 2,
                    121:                          yScreen / 2,
                    122:                          NULL,
                    123:                          NULL,
                    124:                          hInstance,
                    125:                          NULL) ;
                    126: 
                    127:      ShowWindow (hWndApp = hWnd, nCmdShow) ;
                    128: 
                    129:      /* Enter message loop */
                    130:      while (GetMessage (&msg, NULL, 0, 0)) {
                    131:         TranslateMessage (&msg) ;
                    132:         DispatchMessage (&msg) ;
                    133:      }
                    134: 
                    135:      return msg.wParam ;
                    136: }
                    137: 
                    138: /****************************************************************************
                    139:  *                                                                         *
                    140:  *  FUNCTION   : WndProc (hWnd, iMessage, wParam, lParam)                  *
                    141:  *                                                                         *
                    142:  *  PURPOSE    : Processes window messages.                                *
                    143:  *                                                                         *
                    144:  ****************************************************************************/
                    145: LONG   APIENTRY WndProc (
                    146:     HWND     hWnd ,
                    147:     UINT     iMessage ,
                    148:     UINT     wParam ,
                    149:     LONG     lParam )
                    150: 
                    151: {
                    152:     PAINTSTRUCT      ps;
                    153:     HDC             hDC;
                    154:     HANDLE          h;
                    155:     INT             i;
                    156:     INT             iMax;
                    157:     INT             iMin;
                    158:     INT             iPos;
                    159:     INT             dn;
                    160:     RECT            rc,Rect;
                    161:     HPALETTE        hOldPal;
                    162:     HMENU           hMenu;
                    163: 
                    164:     switch (iMessage) {
                    165:        case WM_DESTROY:
                    166:                /* Clean up and quit */
                    167:                FreeDib();
                    168:                PostQuitMessage(0);
                    169:                break ;
                    170: 
                    171:        case WM_CREATE:
                    172:                /* Allocate space for our logical palette */
                    173:                pLogPal = (NPLOGPALETTE) LocalAlloc( LMEM_FIXED,
                    174:                                                     (sizeof(LOGPALETTE) +
                    175:                                                     (sizeof(PALETTEENTRY)*(MAXPALETTE))));
                    176:         if(!pLogPal){
                    177:             MessageBox(hWnd, "<WM_CREATE> Not enough memory for palette.", NULL, MB_OK | MB_ICONHAND);
                    178:                PostQuitMessage (0) ;
                    179:             break;
                    180:         }
                    181: 
                    182: // Temporary workaround.  lpCmdLine points to exe name, not first parameter
                    183:                /* If DIB initialization fails, quit */
                    184: //             if (achFileName[0] && !InitDIB(hWnd))
                    185: //                     PostQuitMessage (3) ;
                    186: 
                    187:                /* fall through */
                    188: 
                    189:        case WM_WININICHANGE:
                    190: 
                    191:                hMenu = GetMenu(hWnd);
                    192: 
                    193:                /* If printer initialization succeeds, enable appropriate
                    194:                 * menu item and clean up.
                    195:                 */
                    196:                if ( hDC = GetPrinterDC() ) {
                    197:                    EnableMenuItem( hMenu,
                    198:                                    IDM_PRINT,
                    199:                                    (RC_DIBTODEV &
                    200:                                     GetDeviceCaps(hDC, RASTERCAPS)) ?
                    201:                                     MF_ENABLED :
                    202:                                     MF_GRAYED | MF_DISABLED);
                    203:                    DeleteDC(hDC);
                    204:                }
                    205:                break;
                    206: 
                    207:        case WM_PALETTEISCHANGING:
                    208:                /* if SHOWDIB was not responsible for palette change and if
                    209:                 * ok to hide changes, paint app. window black.
                    210:                 */
                    211:                if (wParam != (UINT)(hWnd && bNoUgly)) {
                    212:                    GetClientRect(hWnd, &Rect);
                    213: 
                    214:                    hDC = GetDC(hWnd);
                    215:                    FillRect( hDC, (LPRECT) &Rect, GetStockObject(BLACK_BRUSH));
                    216:                    ReleaseDC(hWnd, hDC);
                    217:                }
                    218:                break;
                    219: 
                    220:        case WM_ACTIVATE:
                    221:                if (!GET_WM_ACTIVATE_STATE(wParam, lParam))  /* app. is being de-activated */
                    222:                   break;
                    223:                /* If the app. is moving to the foreground, fall through and
                    224:                 * redraw full client area with the newly realized palette,
                    225:                 * if the palette has changed.
                    226:                 */
                    227: 
                    228:        case WM_QUERYNEWPALETTE:
                    229:                /* If palette realization causes a palette change,
                    230:                 * we need to do a full redraw.
                    231:                 */
                    232:                if (bLegitDraw) {
                    233:                    hDC = GetDC (hWnd);
                    234:                    hOldPal = SelectPalette (hDC, hpalCurrent, 0);
                    235: 
                    236:                    i = RealizePalette(hDC);
                    237: 
                    238:                    SelectPalette (hDC, hOldPal, 0);
                    239:                    ReleaseDC (hWnd, hDC);
                    240: 
                    241:                    if (i) {
                    242:                        InvalidateRect (hWnd, (LPRECT) (NULL), 1);
                    243:                        UpdateCount = 0;
                    244:                        return 1;
                    245:                    } else
                    246:                        return FALSE;
                    247:                }
                    248:                else
                    249:                    return FALSE;
                    250:                break;
                    251: 
                    252:        case WM_PALETTECHANGED:
                    253:                /* if SHOWDIB was not responsible for palette change and if
                    254:                 * palette realization causes a palette change, do a redraw.
                    255:                 */
                    256:                 if ((HWND)wParam != hWnd){
                    257:                    if (bLegitDraw){
                    258:                        hDC = GetDC (hWnd);
                    259:                        hOldPal = SelectPalette (hDC, hpalCurrent, 0);
                    260: 
                    261:                        i = RealizePalette (hDC);
                    262: 
                    263:                        if (i){
                    264:                            if (bUpdateColors){
                    265:                                UpdateColors (hDC);
                    266:                                UpdateCount++;
                    267:                            }
                    268:                            else
                    269:                                InvalidateRect (hWnd, (LPRECT) (NULL), 1);
                    270:                        }
                    271: 
                    272:                        SelectPalette (hDC, hOldPal, 0);
                    273:                        ReleaseDC (hWnd, hDC);
                    274:                    }
                    275:                }
                    276:                break;
                    277: 
                    278:        case WM_RENDERALLFORMATS:
                    279:                /* Ensure that clipboard data can be rendered even tho'
                    280:                 * app. is being destroyed.
                    281:                 */
                    282:                SendMessage(hWnd,WM_RENDERFORMAT,CF_DIB,0L);
                    283:                SendMessage(hWnd,WM_RENDERFORMAT,CF_BITMAP,0L);
                    284:                SendMessage(hWnd,WM_RENDERFORMAT,CF_PALETTE,0L);
                    285:                break;
                    286: 
                    287:        case WM_RENDERFORMAT:
                    288:                /* Format data in manner specified and pass the data
                    289:                 * handle to clipboard.
                    290:                 */
                    291:                if (h = RenderFormat(wParam))
                    292:                    SetClipboardData((WORD)wParam,h);
                    293:                break;
                    294: 
                    295:         case WM_COMMAND:
                    296:                /* Process menu commands */
                    297:                return MenuCommand(hWnd, LOWORD(wParam));
                    298:                break;
                    299: 
                    300:        case WM_TIMER:
                    301:                /* Signal for palette animation */
                    302:                hDC = GetDC(hWnd);
                    303:                hOldPal = SelectPalette(hDC, hpalCurrent, 0);
                    304:                {
                    305:                    PALETTEENTRY peTemp;
                    306: 
                    307:                    /* Shift all palette entries left by one position and wrap
                    308:                     * around the first entry
                    309:                     */
                    310:                    peTemp = pLogPal->palPalEntry[0];
                    311:                    for (i = 0; i < (pLogPal->palNumEntries - 1); i++)
                    312:                         pLogPal->palPalEntry[i] = pLogPal->palPalEntry[i+1];
                    313:                    pLogPal->palPalEntry[i] = peTemp;
                    314:                }
                    315:                /* Replace entries in logical palette with new entries*/
                    316:                AnimatePalette(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPalEntry);
                    317: 
                    318:                SelectPalette(hDC, hOldPal, 0);
                    319:                ReleaseDC(hWnd, hDC);
                    320: 
                    321:                /* Decrement animation count and terminate animation
                    322:                 * if it reaches zero
                    323:                 */
                    324:                if (!(--nAnimating))
                    325:                    PostMessage(hWnd,WM_COMMAND,IDM_ANIMATE0,0L);
                    326:                break;
                    327: 
                    328:        case WM_PAINT:
                    329:                /* If we have updated more than once, the rest of our
                    330:                 * window is not in some level of degradation worse than
                    331:                 * our redraw...  we need to redraw the whole area
                    332:                 */
                    333:                if (UpdateCount > 1) {
                    334:                    BeginPaint(hWnd, &ps);
                    335:                    EndPaint(hWnd, &ps);
                    336:                    UpdateCount = 0;
                    337:                    InvalidateRect(hWnd, (LPRECT) (NULL), 1);
                    338:                    break;
                    339:                }
                    340: 
                    341:                hDC = BeginPaint(hWnd, &ps);
                    342:                AppPaint(hWnd,
                    343:                         hDC,
                    344:                         GetScrollPos(hWnd,SB_HORZ),
                    345:                         GetScrollPos(hWnd,SB_VERT) );
                    346:                EndPaint(hWnd, &ps);
                    347:                break ;
                    348: 
                    349:        case WM_SIZE:
                    350:            SetScrollRanges(hWnd);
                    351:            break;
                    352: 
                    353:        case WM_KEYDOWN:
                    354:            /* Translate keyboard messages to scroll commands */
                    355:            switch (wParam) {
                    356:                case VK_UP:
                    357:                    PostMessage (hWnd, WM_VSCROLL, SB_LINEUP,   0L);
                    358:                    break;
                    359: 
                    360:                case VK_DOWN:
                    361:                    PostMessage (hWnd, WM_VSCROLL, SB_LINEDOWN, 0L);
                    362:                    break;
                    363: 
                    364:                case VK_PRIOR:
                    365:                    PostMessage (hWnd, WM_VSCROLL, SB_PAGEUP,   0L);
                    366:                    break;
                    367: 
                    368:                case VK_NEXT:
                    369:                    PostMessage (hWnd, WM_VSCROLL, SB_PAGEDOWN, 0L);
                    370:                    break;
                    371: 
                    372:                case VK_HOME:
                    373:                    PostMessage (hWnd, WM_HSCROLL, SB_PAGEUP,   0L);
                    374:                    break;
                    375: 
                    376:                case VK_END:
                    377:                    PostMessage (hWnd, WM_HSCROLL, SB_PAGEDOWN, 0L);
                    378:                    break;
                    379: 
                    380:                case VK_LEFT:
                    381:                    PostMessage (hWnd, WM_HSCROLL, SB_LINEUP,   0L);
                    382:                    break;
                    383: 
                    384:                case VK_RIGHT:
                    385:                    PostMessage (hWnd, WM_HSCROLL, SB_LINEDOWN, 0L);
                    386:                    break;
                    387:            }
                    388:            break;
                    389: 
                    390:        case WM_KEYUP:
                    391:            switch (wParam) {
                    392:               case VK_UP:
                    393:               case VK_DOWN:
                    394:               case VK_PRIOR:
                    395:               case VK_NEXT:
                    396:                  PostMessage (hWnd, WM_VSCROLL, SB_ENDSCROLL, 0L);
                    397:                  break;
                    398: 
                    399:               case VK_HOME:
                    400:               case VK_END:
                    401:               case VK_LEFT:
                    402:               case VK_RIGHT:
                    403:                  PostMessage (hWnd, WM_HSCROLL, SB_ENDSCROLL, 0L);
                    404:                  break;
                    405:            }
                    406:            break;
                    407: 
                    408:        case WM_VSCROLL:
                    409:            /* Calculate new vertical scroll position */
                    410:            GetScrollRange (hWnd, SB_VERT, &iMin, &iMax);
                    411:            iPos = GetScrollPos (hWnd, SB_VERT);
                    412:            GetClientRect (hWnd, &rc);
                    413: 
                    414:            switch (GET_WM_VSCROLL_CODE(wParam, lParam)) {
                    415:                case SB_LINEDOWN:
                    416:                    dn =  rc.bottom / 16 + 1;
                    417:                    break;
                    418: 
                    419:                case SB_LINEUP:
                    420:                    dn = -rc.bottom / 16 + 1;
                    421:                    break;
                    422: 
                    423:                case SB_PAGEDOWN:
                    424:                    dn =  rc.bottom / 2  + 1;
                    425:                    break;
                    426: 
                    427:                case SB_PAGEUP:
                    428:                    dn = -rc.bottom / 2  + 1;
                    429:                    break;
                    430: 
                    431:                case SB_THUMBTRACK:
                    432:                case SB_THUMBPOSITION:
                    433:                    dn = GET_WM_VSCROLL_POS(wParam, lParam)-iPos;
                    434:                    break;
                    435: 
                    436:                default:
                    437:                    dn = 0;
                    438:                    break;
                    439:            }
                    440:            /* Limit scrolling to current scroll range */
                    441:            if (dn = BOUND (iPos + dn, iMin, iMax) - iPos) {
                    442:                ScrollWindow (hWnd, 0, -dn, NULL, NULL);
                    443:                SetScrollPos (hWnd, SB_VERT, iPos + dn, TRUE);
                    444:            }
                    445:            break;
                    446: 
                    447:        case WM_HSCROLL:
                    448:            /* Calculate new horizontal scroll position */
                    449:            GetScrollRange (hWnd, SB_HORZ, &iMin, &iMax);
                    450:            iPos = GetScrollPos (hWnd, SB_HORZ);
                    451:            GetClientRect (hWnd, &rc);
                    452: 
                    453:            switch (GET_WM_HSCROLL_CODE(wParam, lParam)) {
                    454:                case SB_LINEDOWN:
                    455:                    dn =  rc.right / 16 + 1;
                    456:                    break;
                    457: 
                    458:                case SB_LINEUP:
                    459:                    dn = -rc.right / 16 + 1;
                    460:                    break;
                    461: 
                    462:                case SB_PAGEDOWN:
                    463:                    dn =  rc.right / 2  + 1;
                    464:                    break;
                    465: 
                    466:                case SB_PAGEUP:
                    467:                    dn = -rc.right / 2  + 1;
                    468:                    break;
                    469: 
                    470:                case SB_THUMBTRACK:
                    471:                case SB_THUMBPOSITION:
                    472:                    dn = GET_WM_HSCROLL_POS(wParam, lParam)-iPos;
                    473:                    break;
                    474: 
                    475:                default:
                    476:                    dn = 0;
                    477:                    break;
                    478:            }
                    479:            /* Limit scrolling to current scroll range */
                    480:            if (dn = BOUND (iPos + dn, iMin, iMax) - iPos) {
                    481:                ScrollWindow (hWnd, -dn, 0, NULL, NULL);
                    482:                SetScrollPos (hWnd, SB_HORZ, iPos + dn, TRUE);
                    483:            }
                    484:            break;
                    485: 
                    486:        case WM_LBUTTONDOWN:
                    487:            /* Start rubberbanding a rect. and track it's dimensions.
                    488:             * set the clip rectangle to it's dimensions.
                    489:             */
                    490:            TrackMouse (hWnd, MAKEMPOINT(lParam));
                    491:            break;
                    492: 
                    493:        case WM_LBUTTONDBLCLK:
                    494:            break;
                    495: 
                    496:        case WM_INITMENU:
                    497:            /* check/uncheck menu items depending on state  of related
                    498:             * flags
                    499:             */
                    500:            CheckMenuItem((HMENU)wParam, IDM_UPDATECOL,
                    501:                (bUpdateColors ? MF_CHECKED : MF_UNCHECKED));
                    502:            CheckMenuItem((HMENU)wParam, IDM_TRANSPARENT,
                    503:                (wTransparent == TRANSPARENT ? MF_CHECKED : MF_UNCHECKED));
                    504:            CheckMenuItem((HMENU)wParam, IDM_DIBSCREEN,
                    505:                (bDIBToDevice ? MF_CHECKED : MF_UNCHECKED));
                    506:            CheckMenuItem((HMENU)wParam, IDM_NOUGLY,
                    507:                (bNoUgly ? MF_CHECKED : MF_UNCHECKED));
                    508:            CheckMenuItem((HMENU)wParam, IDM_MEMORYDIB, MF_CHECKED);
                    509:            EnableMenuItem((HMENU)wParam, IDM_PASTEDIB,
                    510:                IsClipboardFormatAvailable(CF_DIB)?MF_ENABLED:MF_GRAYED);
                    511:            EnableMenuItem((HMENU)wParam, IDM_PASTEDDB,
                    512:                IsClipboardFormatAvailable(CF_BITMAP)?MF_ENABLED:MF_GRAYED);
                    513:            EnableMenuItem((HMENU)wParam, IDM_PASTEPAL,
                    514:                IsClipboardFormatAvailable(CF_PALETTE)?MF_ENABLED:MF_GRAYED);
                    515:            EnableMenuItem((HMENU)wParam, IDM_PRINT,
                    516:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    517:            EnableMenuItem((HMENU)wParam, IDM_SAVE,
                    518:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    519:            EnableMenuItem((HMENU)wParam, IDM_COPY,
                    520:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    521: 
                    522:            EnableMenuItem((HMENU)wParam, IDM_ANIMATE0,
                    523:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    524:            EnableMenuItem((HMENU)wParam, IDM_ANIMATE5,
                    525:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    526:            EnableMenuItem((HMENU)wParam, IDM_ANIMATE50,
                    527:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    528:            EnableMenuItem((HMENU)wParam, IDM_ANIMATE100,
                    529:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    530:            EnableMenuItem((HMENU)wParam, IDM_ANIMATE200,
                    531:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    532:            EnableMenuItem((HMENU)wParam, IDM_ANIMATE201,
                    533:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    534:            EnableMenuItem((HMENU)wParam, IDM_STEALCOL,
                    535:                bLegitDraw ? MF_ENABLED : MF_GRAYED);
                    536:            break;
                    537: 
                    538:        default:
                    539:            return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
                    540: 
                    541:     }
                    542:     return 0L ;
                    543: 
                    544: }
                    545: /****************************************************************************
                    546:  *                                                                         *
                    547:  *  FUNCTION   : MenuCommand ( HWND hWnd, WPARAM wParam)                           *
                    548:  *                                                                         *
                    549:  *  PURPOSE    : Processes menu commands.                                  *
                    550:  *                                                                         *
                    551:  *  RETURNS    : TRUE  - if command could be processed.                    *
                    552:  *              FALSE - otherwise                                          *
                    553:  *                                                                         *
                    554:  ****************************************************************************/
                    555: BOOL MenuCommand (
                    556:     HWND hWnd,
                    557:     UINT id)
                    558: 
                    559: {
                    560:     BITMAPINFOHEADER bi;
                    561:     HDC             hDC;
                    562:     HANDLE          h;
                    563:     HBITMAP         hbm;
                    564:     HPALETTE        hpal;
                    565:     WORD            i;
                    566:     CHAR            Name[40];
                    567:     BOOL            bSave;
                    568:     INT             xSize, ySize, xRes, yRes, dx, dy;
                    569:     RECT            Rect;
                    570:     HFILE           fh;
                    571:     WORD            fFileOptions;
                    572: 
                    573:     switch (id) {
                    574:        case IDM_ABOUT:
                    575:                /* Show About .. box */
                    576:                fDialog ((INT)ABOUTBOX, hWnd,(FARPROC)AppAbout);
                    577:                break;
                    578: 
                    579:        case IDM_COPY:
                    580:                if (!bLegitDraw)
                    581:                    return 0L;
                    582: 
                    583:                /* Clean clipboard of contents */
                    584:                if (OpenClipboard(hWnd)) {
                    585:                    EmptyClipboard ();
                    586:                    SetClipboardData (CF_DIB     ,NULL);
                    587:                    SetClipboardData (CF_BITMAP  ,NULL);
                    588:                    SetClipboardData (CF_PALETTE ,NULL);
                    589:                    CloseClipboard ();
                    590:                }
                    591:                break;
                    592: 
                    593:        case IDM_PASTEPAL:
                    594:                if (OpenClipboard (hWnd)) {
                    595:                    if (h = GetClipboardData (CF_PALETTE)) {
                    596:                        /* Delete current palette and get the CF_PALETTE data
                    597:                         * from the clipboard
                    598:                         */
                    599:                        if (hpalCurrent)
                    600:                            DeleteObject (hpalCurrent);
                    601: 
                    602:                        hpalCurrent = CopyPalette (h);
                    603: 
                    604:                        /*
                    605:                         * If we have a bitmap realized against the old palette
                    606:                         * delete the bitmap and rebuild it using the new palette.
                    607:                         */
                    608:                        if (hbmCurrent){
                    609:                            DeleteObject (hbmCurrent);
                    610:                            hbmCurrent = NULL;
                    611: 
                    612:                            if (hdibCurrent)
                    613:                                hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent);
                    614:                        }
                    615:                    }
                    616:                    CloseClipboard();
                    617:                }
                    618:                break;
                    619: 
                    620:        case IDM_PASTEDIB:
                    621:                if (OpenClipboard (hWnd)) {
                    622:                    if (h = GetClipboardData (CF_DIB)) {
                    623:                        /* Delete current DIB and get CF_DIB and
                    624:                         * CF_PALETTE format data from the clipboard
                    625:                         */
                    626:                        hpal = GetClipboardData (CF_PALETTE);
                    627: 
                    628:                        FreeDib();
                    629:                        hdibCurrent = CopyHandle (h);
                    630:                        if (hdibCurrent) {
                    631:                            bLegitDraw = TRUE;
                    632:                            lstrcpy(achFileName,"<Clipboard>");
                    633:                            hbiCurrent = hdibCurrent;
                    634: 
                    635:                            /* If there is a CF_PALETTE object in the
                    636:                             * clipboard, this is the palette to assume
                    637:                             * the DIB should be realized against, otherwise
                    638:                             * create a palette for it.
                    639:                             */
                    640:                            if (hpal)
                    641:                                hpalCurrent = CopyPalette (hpal);
                    642:                            else
                    643:                                hpalCurrent = CreateDibPalette (hdibCurrent);
                    644: 
                    645:                            SizeWindow(hWnd);
                    646:                        }
                    647:                        else {
                    648:                            bLegitDraw = FALSE;
                    649:                            ErrMsg("No Memory Available!");
                    650:                        }
                    651:                    }
                    652:                    CloseClipboard();
                    653:                }
                    654:                break;
                    655: 
                    656:        case IDM_PASTEDDB:
                    657:                if (OpenClipboard (hWnd)) {
                    658:                    if (hbm = GetClipboardData(CF_BITMAP)) {
                    659:                        hpal = GetClipboardData(CF_PALETTE);
                    660:                        FreeDib();
                    661: 
                    662:                        /*
                    663:                         * If there is a CF_PALETTE object in the
                    664:                         * clipboard, this is the palette to assume
                    665:                         * the bitmap is realized against.
                    666:                         */
                    667:                        if (hpal)
                    668:                            hpalCurrent = CopyPalette(hpal);
                    669:                        else
                    670:                            hpalCurrent = GetStockObject(DEFAULT_PALETTE);
                    671: 
                    672:                        hdibCurrent = DibFromBitmap(hbm,BI_RGB,0,hpalCurrent);
                    673: 
                    674:                        if (hdibCurrent) {
                    675:                            bLegitDraw = TRUE;
                    676:                            lstrcpy(achFileName,"<Clipboard>");
                    677:                            hbiCurrent = hdibCurrent;
                    678: 
                    679:                            hbmCurrent = BitmapFromDib(hdibCurrent,hpalCurrent);
                    680: 
                    681:                            SizeWindow(hWnd);
                    682:                        }
                    683:                        else {
                    684:                            bLegitDraw = FALSE;
                    685:                            ErrMsg("No Memory Available!");
                    686:                        }
                    687:                    }
                    688:                    CloseClipboard ();
                    689:                }
                    690:                break;
                    691: 
                    692:        case IDM_PRINT:
                    693:                GetWindowText(hWnd, Name, sizeof(Name));
                    694: 
                    695:                DibInfo(hbiCurrent, &bi);
                    696: 
                    697:                if (!IsRectEmpty(&rcClip))
                    698:                {
                    699:                    bi.biWidth  = rcClip.right  - rcClip.left;
                    700:                    bi.biHeight = rcClip.bottom - rcClip.top;
                    701:                }
                    702: 
                    703:                /* Initialise printer stuff */
                    704:                if (!(hDC = GetPrinterDC()))
                    705:                        break;
                    706: 
                    707:                xSize = GetDeviceCaps(hDC, HORZRES);
                    708:                ySize = GetDeviceCaps(hDC, VERTRES);
                    709:                xRes  = GetDeviceCaps(hDC, LOGPIXELSX);
                    710:                yRes  = GetDeviceCaps(hDC, LOGPIXELSY);
                    711: 
                    712:                /* Use half inch margins on left and right
                    713:                 * and one inch on top. Maintain the same aspect ratio.
                    714:                 */
                    715: 
                    716:                dx = xSize - xRes;
                    717:                dy = (INT)((LONG)dx * bi.biHeight/bi.biWidth);
                    718: 
                    719:                /* Fix bounding rectangle for the picture .. */
                    720:                Rect.top    = yRes;
                    721:                Rect.left   = xRes / 2;
                    722:                Rect.bottom = yRes + dy;
                    723:                Rect.right  = xRes / 2 + dx;
                    724: 
                    725:                /* ... and inform the driver */
                    726:                Escape(hDC, SET_BOUNDS, sizeof(RECT), (LPSTR)&Rect, NULL);
                    727: 
                    728:                bSave = TRUE;
                    729: 
                    730:                if (InitPrinting(hDC, hWnd, hInst, Name)) {
                    731: 
                    732:                        PrintDIB(hWnd, hDC, xRes/2, yRes, dx, dy);
                    733: 
                    734:                        /* Signal to the driver to begin translating the drawing
                    735:                         * commands to printer output...
                    736:                         */
                    737:                        Escape (hDC, NEWFRAME, NULL, NULL, NULL);
                    738: 
                    739:                        TermPrinting(hDC);
                    740:                }
                    741: 
                    742:                DeleteDC(hDC);
                    743:                break;
                    744: 
                    745:        case IDM_OPEN:
                    746:                {
                    747: 
                    748:                /* Bring up File/Open ... dialog */
                    749:                fh = DlgOpenFile (hWnd,
                    750:                                  "Select a DIB to display",
                    751:                                  (LONG)OF_EXIST | OF_MUSTEXIST | OF_NOOPTIONS,
                    752:                                  szBitmapExt,
                    753:                                  achFileName,
                    754:                                  NULL
                    755:                                  );
                    756:                /*  Load up the DIB if the user did not press cancel */
                    757:                if (fh > 0) {
                    758:                   StartWait();
                    759:                   if (InitDIB (hWnd))
                    760:                       InvalidateRect (hWnd, NULL, FALSE);
                    761:                   else
                    762:                       bLegitDraw = FALSE;
                    763:                   EndWait();
                    764:                }
                    765:                break;
                    766:                }
                    767:        case IDM_SAVE:
                    768:                DibInfo(hbiCurrent,&bi);
                    769:                fFileOptions = 0;
                    770: 
                    771:                /* Depending on compression type for current DIB,
                    772:                 * set the appropriate bit in the fFileOptions flag
                    773:                 */
                    774:                if (bi.biCompression == BI_RGB)
                    775:                    fFileOptions |= F_RGB;
                    776:                else if (bi.biCompression == BI_RLE4)
                    777:                    fFileOptions |= F_RLE4;
                    778:                else if (bi.biCompression == BI_RLE8)
                    779:                    fFileOptions |= F_RLE8;
                    780: 
                    781:                /* Depending on bits/pixel type for current DIB,
                    782:                 * set the appropriate bit in the fFileOptions flag
                    783:                 */
                    784:                switch (bi.biBitCount){
                    785:                    case  1:
                    786:                        fFileOptions |= F_1BPP;
                    787:                        break;
                    788: 
                    789:                    case  4:
                    790:                        fFileOptions |= F_4BPP;
                    791:                        break;
                    792: 
                    793:                    case  8:
                    794:                        fFileOptions |= F_8BPP;
                    795:                        break;
                    796: 
                    797:                    case 24:
                    798:                        fFileOptions |= F_24BPP;
                    799:                }
                    800: 
                    801:                /* Bring up File/Save... dialog and get info. about filename,
                    802:                 * compression, and bits/pix. of DIB to be written.
                    803:                 */
                    804:                fh = DlgOpenFile (hWnd,
                    805:                                  "Select File to save DIB to",
                    806:                                  (LONG)OF_EXIST | OF_SAVE | OF_NOSHOWSPEC,
                    807:                                  szBitmapExt,
                    808:                                  achFileName,
                    809:                                  &fFileOptions);
                    810: 
                    811:                /* Extract DIB specs. if the user did not press cancel */
                    812:                if (fh != 0){
                    813:                    if (fFileOptions & F_RGB)
                    814:                        bi.biCompression = BI_RGB;
                    815: 
                    816:                    if (fFileOptions & F_RLE4)
                    817:                        bi.biCompression = BI_RLE4;
                    818: 
                    819:                    if (fFileOptions & F_RLE8)
                    820:                        bi.biCompression = BI_RLE8;
                    821: 
                    822:                    if (fFileOptions & F_1BPP)
                    823:                        bi.biBitCount = 1;
                    824: 
                    825:                    if (fFileOptions & F_4BPP)
                    826:                        bi.biBitCount = 4;
                    827: 
                    828:                    if (fFileOptions & F_8BPP)
                    829:                        bi.biBitCount = 8;
                    830: 
                    831:                    if (fFileOptions & F_24BPP)
                    832:                        bi.biBitCount = 24;
                    833: 
                    834:                    /* Realize a DIB in the specified format and obtain a
                    835:                     * handle to it.
                    836:                     */
                    837:                    hdibCurrent = RealizeDibFormat(bi.biCompression,bi.biBitCount);
                    838:                    if (!hdibCurrent){
                    839:                        ErrMsg("Unable to save the specified file");
                    840:                        return 0L;
                    841:                    }
                    842: 
                    843:                    /* Write the DIB */
                    844:                    StartWait();
                    845:                    if (!WriteDIB(achFileName,hdibCurrent))
                    846:                        ErrMsg("Unable to save the specified file");
                    847:                    EndWait();
                    848:                }
                    849:                break;
                    850: 
                    851:        case IDM_EXIT:
                    852:                PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
                    853:                break;
                    854: 
                    855:        case IDM_UPDATECOL:
                    856:                /* Toggle state of "update screen colors" flag. If it is
                    857:                 * off, clear the "hide changes" flag
                    858:                 */
                    859:                bUpdateColors = !bUpdateColors;
                    860:                if (bUpdateColors)
                    861:                    bNoUgly = 0;
                    862:                break;
                    863: 
                    864:        case IDM_DIBSCREEN:
                    865:                bDIBToDevice = !bDIBToDevice;
                    866:                InvalidateRect(hWnd, (LPRECT) (NULL), 1);
                    867:                break;
                    868: 
                    869:        case IDM_MEMORYDIB:
                    870:                break;
                    871: 
                    872:        case IDM_NOUGLY:
                    873:                /* Toggle state of "hide changes" flag. If it is off, clear
                    874:                 * the "update screen colors" flag. This will tell SHOWDIB
                    875:                 * to paint itself black while the palette is changing.
                    876:                 */
                    877:                bNoUgly = !bNoUgly;
                    878:                if (bNoUgly)
                    879:                    bUpdateColors = 0;
                    880:                break;
                    881: 
                    882:        case IDM_TRANSPARENT:
                    883:                /* Toggle DC mode */
                    884:                wTransparent = (WORD) (wTransparent == TRANSPARENT ?
                    885:                    OPAQUE : TRANSPARENT);
                    886:                break;
                    887: 
                    888:        case IDM_ANIMATE0:
                    889:                if (!hpalSave)
                    890:                    break;
                    891: 
                    892:                /* Reset animation count and stop timer */
                    893:                KillTimer(hWnd, 1);
                    894:                nAnimating = 0;
                    895: 
                    896:                /* Restore palette which existed before animation started */
                    897:                DeleteObject(hpalCurrent);
                    898:                hpalCurrent = hpalSave;
                    899: 
                    900:                /* Rebuild bitmap based on newly realized information */
                    901:                hDC = GetDC (hWnd);
                    902:                SelectPalette (hDC, hpalCurrent, 0);
                    903:                RealizePalette (hDC);
                    904:                ReleaseDC (hWnd, hDC);
                    905: 
                    906:                if (hbmCurrent){
                    907:                    DeleteObject (hbmCurrent);
                    908:                    hbmCurrent = NULL;
                    909: 
                    910:                    if (hdibCurrent)
                    911:                       hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent);
                    912:                }
                    913:                hpalSave = NULL;
                    914: 
                    915:                /* Force redraw with new palette for everyone */
                    916:                InvalidateRect(hWnd, NULL, TRUE);
                    917:                break;
                    918: 
                    919:        case IDM_STEALCOL:
                    920:        case IDM_ANIMATE5:
                    921:        case IDM_ANIMATE20:
                    922:        case IDM_ANIMATE50:
                    923:        case IDM_ANIMATE100:
                    924:        case IDM_ANIMATE200:
                    925:        case IDM_ANIMATE201:
                    926:                /* Set animation count i.e number of times animation is to
                    927:                 * take place.
                    928:                 */
                    929:                nAnimating = id;
                    930:                if (id == IDM_STEALCOL)
                    931:                        nAnimating = 0;
                    932: 
                    933:                /* Save current palette */
                    934:                hpalSave = CopyPalette(hpalCurrent);
                    935: 
                    936:                GetObject(hpalCurrent, sizeof(INT), (LPSTR)&pLogPal->palNumEntries);
                    937:                GetPaletteEntries(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPalEntry);
                    938: 
                    939:                /* Reserve all entries in the palette otherwise AnimatePalette()
                    940:                 * will not modify them
                    941:                 */
                    942:                for (i = 0; i < pLogPal->palNumEntries; i++) {
                    943:                     pLogPal->palPalEntry[i].peFlags = (BYTE)PC_RESERVED;
                    944:                }
                    945: 
                    946:                SetPaletteEntries(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPalEntry);
                    947: 
                    948:                /* Rebuild bitmap based on newly realized information */
                    949:                if (hbmCurrent){
                    950:                    DeleteObject (hbmCurrent);
                    951:                    hbmCurrent = NULL;
                    952: 
                    953:                    if (hdibCurrent)
                    954:                       hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent);
                    955:                }
                    956: 
                    957:                /* Force redraw with new palette for everyone */
                    958:                InvalidateRect(hWnd, NULL, TRUE);
                    959: 
                    960:                /* Initiate the timer so that palette can be animated in
                    961:                 * response to a WM_TIMER message
                    962:                 */
1.1.1.2 ! root      963:                if (nAnimating && !SetTimer(hWnd, 1, 250, (TIMERPROC)(LPSTR) NULL))
1.1       root      964:                        nAnimating = 0;
                    965: 
                    966:        default:
                    967:                break;
                    968:     }
                    969: 
                    970:     return TRUE;
                    971: }
                    972: 
                    973: /****************************************************************************
                    974:  *                                                                         *
                    975:  *  FUNCTION   : InitDIB(hWnd)                                             *
                    976:  *                                                                         *
                    977:  *  PURPOSE    : Reads a DIB from a file, obtains a handle to it's          *
                    978:  *              BITMAPINFO struct., sets up the palette and loads the DIB. *
                    979:  *                                                                         *
                    980:  *  RETURNS    : TRUE  - DIB loads ok                                      *
                    981:  *              FALSE - otherwise                                          *
                    982:  *                                                                         *
                    983:  ****************************************************************************/
                    984: INT InitDIB(HWND hWnd)
                    985: {
                    986:     HFILE             fh;
                    987:     LPBITMAPINFOHEADER lpbi;
                    988:     WORD FAR *        pw;
                    989:     INT               i;
                    990:     BITMAPINFOHEADER   bi;
                    991:     OFSTRUCT          of;
                    992: 
                    993:     FreeDib();
                    994: 
                    995:     /* Open the file and get a handle to it's BITMAPINFO */
                    996: 
                    997:     fh = OpenFile(achFileName, (LPOFSTRUCT)&of, (UINT)OF_READ);
                    998:     if (fh == -1) {
                    999:        ErrMsg("Can't open file '%ls'", (LPSTR)achFileName);
                   1000:        return FALSE;
                   1001:     }
                   1002:     hbiCurrent = ReadDibBitmapInfo(fh);
                   1003: 
                   1004:     dwOffset = _llseek(fh, 0L, (UINT)SEEK_CUR);
                   1005:     _lclose(fh);
                   1006: 
                   1007:     if (hbiCurrent == NULL) {
                   1008:        ErrMsg("%ls is not a Legitimate DIB File!", (LPSTR)achFileName);
                   1009:        return FALSE;
                   1010:     }
                   1011:     DibInfo(hbiCurrent,&bi);
                   1012: 
                   1013:     /* Set up the palette */
                   1014:     hpalCurrent = CreateDibPalette(hbiCurrent);
                   1015:     if (hpalCurrent == NULL) {
                   1016:        ErrMsg("CreatePalette() Failed");
                   1017:        return FALSE;
                   1018:     }
                   1019: 
                   1020:     /* Convert the DIB color table to palette relative indexes, so
                   1021:      * SetDIBits() and SetDIBitsToDevice() can avoid color matching.
                   1022:      * We can do this because the palette we realize is identical
                   1023:      * to the color table of the bitmap, ie the indexes match 1 to 1
                   1024:      *
                   1025:      * Now that the DIB color table is palette indexes not RGB values
                   1026:      * we must use DIB_PAL_COLORS as the wUsage parameter to SetDIBits()
                   1027:      */
                   1028:     lpbi = (VOID FAR *)GlobalLock(hbiCurrent);
                   1029:     if (lpbi->biBitCount != 24) {
                   1030:        fPalColors = TRUE;
                   1031: 
                   1032:        pw = (WORD FAR *)((LPSTR)lpbi + lpbi->biSize);
                   1033: 
                   1034:        for (i=0; i<(INT)lpbi->biClrUsed; i++)
                   1035:            *pw++ = (WORD)i;
                   1036:     }
                   1037:     GlobalUnlock(hbiCurrent);
                   1038:     bLegitDraw = TRUE;
                   1039: 
                   1040:     /* If the input bitmap is not in RGB FORMAT the banding code will
                   1041:      * not work!  we need to load the DIB bits into memory.
                   1042:      * if memory DIB, load it all NOW!  This will avoid calling the
                   1043:      * banding code.
                   1044:      */
                   1045:     hdibCurrent = OpenDIB(achFileName);
                   1046: 
                   1047:     /* If the RLE could not be loaded all at once, exit gracefully NOW,
                   1048:      * to avoid calling the banding code
                   1049:      */
                   1050:     if ((bi.biCompression != BI_RGB) && !hdibCurrent){
                   1051:        ErrMsg ("Could not load RLE!");
                   1052:        FreeDib();
                   1053:        return FALSE;
                   1054:     }
                   1055: 
                   1056:     if (hdibCurrent && !bDIBToDevice){
                   1057:                hbmCurrent = BitmapFromDib(hdibCurrent,hpalCurrent);
                   1058:                if (!hbmCurrent){
                   1059:                ErrMsg ("Could not create bitmap!");
                   1060:                FreeDib();
                   1061:                return FALSE;
                   1062:                }
                   1063:     }
                   1064: 
                   1065:     SizeWindow(hWnd);
                   1066: 
                   1067:     return TRUE;
                   1068: }
                   1069: /****************************************************************************
                   1070:  *                                                                         *
                   1071:  *  FUNCTION   : FreeDib(void)                                             *
                   1072:  *                                                                         *
                   1073:  *  PURPOSE    : Frees all currently active bitmap, DIB and palette objects *
                   1074:  *              and initializes their handles.                             *
                   1075:  *                                                                         *
                   1076:  ****************************************************************************/
                   1077: VOID FreeDib()
                   1078: {
                   1079:     if (hpalCurrent)
                   1080:        DeleteObject(hpalCurrent);
                   1081: 
                   1082:     if (hbmCurrent)
                   1083:        DeleteObject(hbmCurrent);
                   1084: 
                   1085:     if (hdibCurrent)
                   1086:        GlobalFree(hdibCurrent);
                   1087: 
                   1088:     if (hbiCurrent && hbiCurrent != hdibCurrent)
                   1089:        GlobalFree(hbiCurrent);
                   1090: 
                   1091:     fPalColors = FALSE;
                   1092:     bLegitDraw = FALSE;
                   1093:     hpalCurrent = NULL;
                   1094:     hdibCurrent = NULL;
                   1095:     hbmCurrent = NULL;
                   1096:     hbiCurrent = NULL;
                   1097:     SetRectEmpty (&rcClip);
                   1098: }

unix.superglobalmegacorp.com

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