home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / f / fbmp.zip / FBMP.C next >
C/C++ Source or Header  |  1992-12-15  |  8KB  |  259 lines

  1. /* FBMP.C -- Freeware BMP viewer for PM */
  2.  
  3. /* Version 0.97 */
  4.  
  5. /* This program is Copyright (c) 1992 by Raja Thiagarajan. However, it may
  6.    be used for any NON-commercial purpose.
  7.    If you have any comments or questions, you can contact me at
  8.    sthiagar@bronze.ucs.indiana.edu (Internet) or 72175,12 (CompuServe).
  9.    Note that I read my Internet mail almost daily, but only check my
  10.    CompuServe mail about once a week. I would appreciate hearing
  11.    about bugfixes or improvements!
  12.    Thanks to Peter Nielsen (pnielsen@aton.abo.fi) for some clever ideas
  13.    and good improvements!
  14. */
  15.  
  16. #include <stdio.h> /* include fclose(), fopen(), fread(), fseek(), ftell(),
  17.                       sprintf()*/
  18. #include <stdlib.h> /* include EXIT_FAILURE, exit(), free(), malloc() */
  19. #include <string.h> /* include strcat(), strrchr() */
  20.  
  21. #define INCL_DOS /* include DosBeep() */
  22. #define INCL_GPI
  23. #define INCL_WIN
  24. #include <os2.h>
  25.  
  26. /* Prototypes */
  27. VOID ReadFile (CHAR * fName);
  28. VOID PlaceTheWindow (HWND hwnd);
  29. MRESULT EXPENTRY ClientWinProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  30.  
  31. static VOID  * bPtr;
  32. static HAB     hab;  /* the handle to the program's anchor block */
  33. static ULONG   bWid, bHi; /* Bitmap width and height */
  34. static USHORT  bBits; /* Bits per plane */
  35.  
  36. static LONG    hasPalMan;
  37.  
  38. static CHAR    title [384]; /* Window title */
  39.  
  40. INT main (INT argc, CHAR * argv[])
  41. {
  42.    HMQ   hmq;        /* handle for message queue */
  43.    QMSG  qmsg;       /* message queue element */
  44.    HWND  hwnd,       /* handle to frame window */
  45.          hwndClient; /* handle for client window */
  46.  
  47.    ULONG createFlags =  FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER
  48.                               | FCF_MINMAX | FCF_SHELLPOSITION
  49.                               | FCF_TASKLIST;
  50.  
  51.    static   CHAR  clientClass [] = "Client Window";
  52.  
  53.    if (argc != 2) {
  54.       DosBeep (440, 100);
  55.       exit (EXIT_FAILURE);
  56.    } else {
  57.       ReadFile (argv[1]);
  58.    }
  59.  
  60.    {  /* Display the filename (no path!) and bitmap dimensions */
  61.       CHAR * cp = strrchr (argv[1], '\\');
  62.       if (!cp) {
  63.          cp = strrchr (argv[1], ':');
  64.       }
  65.       if (!cp) {
  66.          cp = argv[1];
  67.       } else {
  68.          cp++; /* skip past the backslash (or colon) */
  69.       }
  70.       sprintf (title, "fBMP -- %s (%ux%u)", cp, bWid, bHi);
  71.    }
  72.  
  73.    hab = WinInitialize (0);   /* initialize PM usage */
  74.    hmq = WinCreateMsgQueue (hab, 0);   /* create message queue */
  75.  
  76.    WinRegisterClass (hab, clientClass, (PFNWP) ClientWinProc, CS_SIZEREDRAW, 0);
  77.  
  78.       /* create standard window and client */
  79.    hwnd = WinCreateStdWindow (HWND_DESKTOP, 0UL, &createFlags,
  80.                      clientClass, title, 0L, 0UL, 0, &hwndClient);
  81.  
  82.    PlaceTheWindow (hwnd);
  83.  
  84.    while (WinGetMsg (hab, &qmsg, NULLHANDLE, 0, 0)) { /* msg dispatch loop */
  85.       WinDispatchMsg (hab, &qmsg);
  86.    }
  87.  
  88.    WinDestroyWindow (hwnd);   /* destroy frame window */
  89.    WinDestroyMsgQueue (hmq);  /* destroy message queue */
  90.    WinTerminate (hab);        /* terminate PM usage */
  91.  
  92.    return 0;
  93. }
  94.  
  95. VOID ReadFile (CHAR * fname)
  96. {
  97.    FILE * bmpFile;
  98.    LONG   fSize;
  99.  
  100.    bmpFile = fopen (fname, "rb");
  101.  
  102.    /* If file not found, append ".BMP" and try again */
  103.    if ((bmpFile == NULL) && (!strrchr (fname, '.'))) {
  104.       CHAR fbName [300];
  105.       strcpy (fbName, fname);
  106.       strcat (fbName, ".BMP");
  107.       bmpFile = fopen (fbName, "rb");
  108.    }
  109.  
  110.    if (bmpFile == NULL) {
  111.       DosBeep (440, 100);
  112.       exit (EXIT_FAILURE);
  113.    }
  114.  
  115.    /* Check to see if it has the right format */
  116.    {
  117.       CHAR ut [2];
  118.       fread (ut, sizeof (CHAR), 2, bmpFile);
  119.       if ((ut[0] != 'B') || (ut[1] != 'M')) {
  120.          DosBeep (440, 100); DosBeep (220, 100);
  121.          exit (EXIT_FAILURE);
  122.       }
  123.    }
  124.  
  125.    /* Determine the size of the file */
  126.    fseek (bmpFile, 0L, SEEK_END);
  127.    fSize = ftell (bmpFile);
  128.  
  129.    /* Allocate that much free memory. [Boy, do I love virtual, flat-model
  130.       memory!] */
  131.    bPtr = malloc (fSize);
  132.    if (bPtr == NULL) {
  133.       fclose (bmpFile);
  134.       DosBeep (440, 100); DosBeep (220, 100); DosBeep (110, 100);
  135.       exit (EXIT_FAILURE);
  136.    }
  137.  
  138.    /* Move back to the start of the file ...*/
  139.    fseek (bmpFile, 0L, SEEK_SET);
  140.    /* ... and load the whole thing in one gulp! */
  141.    fread (bPtr, sizeof (BYTE), fSize, bmpFile);
  142.  
  143.    /* Now close the file [since we can read from RAM instead!] */
  144.    fclose (bmpFile);
  145.  
  146.    /* As long as we're here, set the width, height, and bits per plane */
  147.    {
  148.       PBITMAPFILEHEADER2 pbfh2 = bPtr;
  149.       bWid = pbfh2->bmp2.cx;
  150.       bHi = pbfh2->bmp2.cy;
  151.       bBits = pbfh2->bmp2.cBitCount;
  152.    }
  153.  
  154. }
  155.  
  156. VOID PlaceTheWindow (HWND hwnd)
  157. {
  158.    HDC   hdcScr;
  159.    RECTL rcl;
  160.    LONG  scrWid, scrHi;
  161.    hdcScr = GpiQueryDevice (WinGetPS (HWND_DESKTOP));
  162.    DevQueryCaps (hdcScr, CAPS_WIDTH, 1L, &scrWid);   DevQueryCaps (hdcScr, CAPS_WIDTH, 1L, &scrWid);
  163.    DevQueryCaps (hdcScr, CAPS_HEIGHT, 1L, &scrHi);
  164.    DevQueryCaps (hdcScr, CAPS_ADDITIONAL_GRAPHICS, 1L, &hasPalMan);
  165.    hasPalMan &= CAPS_PALETTE_MANAGER;
  166.    rcl.xLeft = rcl.yBottom = 0;
  167.    rcl.xRight = bWid;
  168.    rcl.yTop = bHi;
  169.    WinCalcFrameRect (hwnd, &rcl, FALSE);
  170.  
  171.    WinSetWindowPos (hwnd,
  172.                      NULLHANDLE,
  173.                      (scrWid - rcl.xRight + rcl.xLeft) / 2,
  174.                      (scrHi - rcl.yTop + rcl.yBottom) / 2,
  175.                      (rcl.xRight - rcl.xLeft),
  176.                      (rcl.yTop - rcl.yBottom),
  177.                      SWP_SHOW | SWP_MOVE | SWP_SIZE);
  178. }
  179.  
  180. MRESULT EXPENTRY ClientWinProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  181. {
  182.    static HPS     hps;
  183.    static HDC     hdc;
  184.    static HPAL    hpal;
  185.    static HBITMAP hbm;
  186.    static BOOL    firstPaint = TRUE;
  187.  
  188.    switch (msg) {
  189.       case WM_CREATE:
  190.          {
  191.             SIZEL sizl = {0L, 0L};
  192.             hdc = WinOpenWindowDC (hwnd);
  193.             hps = GpiCreatePS (hab, hdc, &sizl, PU_PELS | GPIF_DEFAULT
  194.                       | GPIT_MICRO | GPIA_ASSOC);
  195.  
  196.             /* Create and use palette */
  197.             {
  198.                BYTE * foo = bPtr;
  199.                if ((bBits >= 1) && (bBits <= 8)) {
  200.                   hpal = GpiCreatePalette (hab, 0L, LCOLF_CONSECRGB,
  201.                                            1 << bBits,
  202.                                            (PULONG) (foo + 54));
  203.                   GpiSelectPalette (hps, hpal);
  204.                }
  205.             }
  206.  
  207.             /* Load bitmap */
  208.             {
  209.                PBITMAPFILEHEADER2 pbfh2 = bPtr;
  210.                BYTE * foo = bPtr;
  211.                hbm = GpiCreateBitmap (hps,
  212.                                        &(pbfh2->bmp2),
  213.                                        CBM_INIT,
  214.                                        (foo + pbfh2->offBits),
  215.                                        (PBITMAPINFO2) &(pbfh2->bmp2));
  216.             }
  217.  
  218.             /* We don't need the file image any more, so ... */
  219.             free (bPtr);
  220.          }
  221.          return (MRESULT) FALSE;
  222.       case WM_DESTROY:
  223.          GpiSetBitmap (hps, NULLHANDLE);
  224.          GpiDeleteBitmap (hbm);
  225.          GpiSelectPalette (hps, NULLHANDLE);
  226.          GpiDeletePalette (hpal);
  227.          GpiDestroyPS (hps);
  228.          return (MRESULT) FALSE;
  229.       case WM_REALIZEPALETTE:
  230.          {
  231.             ULONG palSize = 1 << bBits;
  232.             if (WinRealizePalette (hwnd, hps, &palSize)) {
  233.                WinInvalidateRect (hwnd, NULL, FALSE);
  234.             }
  235.          }
  236.          return (MRESULT) FALSE;
  237.       case WM_PAINT:
  238.          {
  239.             POINTL ptl = {0, 0};
  240. /*RECTL rcl;*/
  241.             WinBeginPaint (hwnd, hps, NULL);
  242.             if (firstPaint) {
  243.                ULONG palSize = 256;
  244.                WinRealizePalette (hwnd, hps, &palSize);
  245.                firstPaint = FALSE;
  246.             }
  247. /*WinQueryWindowRect (hwnd, &rcl);*/
  248.             WinDrawBitmap (hps, hbm, NULL, &ptl, 0, 0, DBM_NORMAL);
  249. /*WinDrawBitmap (hps, hbm, NULL, (PPOINTL) &rcl, 0, 0, DBM_STRETCH);*/
  250.             WinEndPaint (hps);
  251.          }
  252.          return (MRESULT) FALSE;
  253.       case WM_ERASEBACKGROUND:
  254.          return (MRESULT) TRUE;
  255.       default:
  256.          return (WinDefWindowProc (hwnd, msg, mp1, mp2));
  257.    }  /*end switch*/
  258. }
  259.