home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 17.ddi / SAMPLES / DIBVIEW / FILE.C_ / FILE.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  35.3 KB  |  1,311 lines

  1. /*************************************************************************
  2.  
  3.       File:  FILE.C
  4.  
  5.    Purpose:  Contains the file I/O routines and the Dib Information
  6.              dialog box.
  7.  
  8.  Functions:  HANDLE   OpenDIBFile       (szFilename);
  9.              BOOL     GetFileName       (LPSTR, WORD);
  10.              HANDLE   ReadDIBFile       (int);
  11.              BOOL     MyRead            (int, LPSTR, DWORD);
  12.              int      CheckIfFileExists (char *);
  13.              int      GetDibInfo        (char *, INFOSTRUCT *);
  14.              BOOL     SaveDIBFile       (void);
  15.              HANDLE   WinDibFromBitmap  (HBITMAP, DWORD, WORD, HPALETTE);
  16.              HANDLE   PMDibFromBitmap   (HBITMAP, DWORD, WORD, HPALETTE);
  17.              BOOL     WriteDIB          (LPSTR, HANDLE);
  18.              VOID     ParseCommandLine  (LPSTR);
  19.              HANDLE   GetDIB            (void);
  20.              DWORD PASCAL lwrite        (int, VOID FAR *, DWORD);
  21.  
  22.   Comments:
  23.  
  24.    History:   Date     Reason
  25.  
  26.              6/1/91    Created
  27.              6/27/91   Added Dib Information support
  28.              7/22/91   Added File Save support
  29.              8/8/91    Added Command Line Support
  30.             11/15/91   Added szFilename parm to OpenDIBFile.
  31.  
  32. *************************************************************************/
  33.  
  34. #include "master.h"
  35.  
  36. char szFileName[256];         // Filename of DIB
  37. char szDirName[256];          // last Directory this Instance saw
  38. /*************************************************************************
  39.  
  40.   Function:  OpenDIBFile (void)
  41.  
  42.    Purpose:  Prompts user for a filename, opens it, and returns a handle
  43.              to the DIB memory block.
  44.  
  45.    Returns:  NULL if no file is opened, or an error occurs reading the file
  46.              A valid DIB handle if successful.
  47.  
  48.   Comments:
  49.  
  50.    History:   Date     Reason
  51.  
  52.              6/1/91    Created
  53.             11/15/91   Added szFilename parm.
  54.  
  55. *************************************************************************/
  56.  
  57. HANDLE OpenDIBFile (LPSTR szFilename)
  58. {
  59.   HANDLE   hDIB;
  60.  
  61.   szFilename[0] = '\0';
  62.  
  63.   if (GetFileName (szFileName, IDS_OPENDLG))
  64.   {
  65.     lstrcpy (szFilename, szFileName);
  66.     hDIB = GetDIB ();
  67.     if (hDIB)
  68.     {
  69.       return hDIB;
  70.     }
  71.   }
  72.   return NULL;
  73. }
  74.  
  75.  
  76. /*************************************************************************
  77.  
  78.   Function:  GetFileName (LPSTR. WORD)
  79.  
  80.    Purpose:  Prompts user for a filename through the use of a Windows 3.1
  81.              FileOpen common dialog box.
  82.  
  83.    Returns:  TRUE if a filename is selected.
  84.              FALSE if no filename is selected.
  85.  
  86.   Comments:  Filename is put into the string passed to the routine.
  87.              If a filename is not selected, NULL is returned.
  88.  
  89.    History:   Date      Author      Reason
  90.  
  91.              6/1/91    Created
  92.              6/27/91   Changed OPENFILENAME structure to
  93.                        support customized common dialog box
  94.  
  95. *************************************************************************/
  96.  
  97. BOOL GetFileName (LPSTR szFileName, WORD wIDString)
  98. {
  99.    OPENFILENAME   of;
  100.    FARPROC      fpDlgFunc;           // far proc to dlg function
  101.    DWORD          flags;
  102.    static char    szTitle[30];         // Dialog Box title
  103.    static char    szTemplate[20];      // Dialog Box template
  104.    static char    szFile[256];         // File name
  105.    static char    szFileTitle[256];    // Title
  106.    static char    szDrive[5];          // Drive
  107.    static char    szDir[256];          // Directory
  108.    static char    szFname[10];         // Filename
  109.    static char    szExt[4];            // Extension
  110.    HANDLE         hDibInfo;            // Handle to extra words
  111.    LPDIBINFO      ptr;                 // pointer to extra words
  112.    char *szFilter[] =                  // Filter
  113.       {
  114.       "Bitmaps",
  115.       "*.bmp;*.dib;*.rle",
  116.       ""
  117.       };
  118.  
  119.  
  120.    // Initialize the OPENFILENAME members
  121.  
  122.    szFile[0] = '\0';
  123.  
  124.    if (wIDString == IDS_OPENDLG)
  125.      {
  126.      LoadString (hInst, wIDString, szTitle, sizeof (szTitle));
  127.      LoadString (hInst, IDS_FILEOPEN, szTemplate, sizeof (szTemplate));
  128.      fpDlgFunc = (FARPROC) MakeProcInstance(FileOpenHookProc, hInst);
  129.      flags = OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_HIDEREADONLY;
  130.  
  131.      }
  132.    else if (wIDString == IDS_SAVEDLG)
  133.      {
  134.      hDibInfo = (HANDLE) GetWindowWord (GetCurrentMDIWnd(), WW_DIB_HINFO);
  135.      ptr = (LPDIBINFO) GlobalLock (hDibInfo);
  136.  
  137.      LoadString (hInst, wIDString, szTitle, sizeof (szTitle));
  138.      LoadString (hInst, IDS_FILESAVE, szTemplate, sizeof (szTemplate));
  139.      fpDlgFunc = (FARPROC) MakeProcInstance(FileSaveHookProc, hInst);
  140.      flags = OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_HIDEREADONLY |
  141.              OFN_OVERWRITEPROMPT;
  142.      lstrcpy ((LPSTR) szFileName, ptr->szFileName);
  143.      lstrcpy ((LPSTR) szFile, (LPSTR)ptr->szFileName);
  144.      _splitpath (szFile, szDrive, szDir, szFname, szExt);
  145.      szDirName[0]=0;
  146.      szFile[0]=0;
  147.      lstrcat ((LPSTR)szDirName, (LPSTR) szDrive);
  148.      lstrcat ((LPSTR)szDirName, (LPSTR)szDir);
  149.      lstrcpy((LPSTR)szFile, (LPSTR) szFname);
  150.      lstrcat ((LPSTR)szFile, (LPSTR) szExt);
  151.      GlobalUnlock (hDibInfo);
  152.      }
  153.  
  154.    of.lStructSize       = sizeof (OPENFILENAME);
  155.    of.hwndOwner         = GetFocus ();
  156.    of.hInstance         = hInst;
  157.    of.lpstrFilter       = szFilter[0];
  158.    of.lpstrCustomFilter = NULL;
  159.    of.nMaxCustFilter    = 0L;
  160.    of.nFilterIndex      = 1L;
  161.    of.lpstrFile         = szFile;
  162.    of.nMaxFile          = sizeof (szFile);
  163.    of.lpstrFileTitle    = szFileTitle;
  164.    of.nMaxFileTitle     = sizeof (szFileTitle);
  165.    of.lpstrInitialDir   = szDirName;
  166.    of.lpstrTitle        = szTitle;
  167.    of.Flags             = flags;
  168.    of.nFileOffset       = 0;
  169.    of.nFileExtension    = 0;
  170.    of.lpstrDefExt       = NULL;
  171.    of.lpfnHook        = (FARHOOK)fpDlgFunc;
  172.    of.lpTemplateName    = szTemplate;
  173.  
  174.  
  175.    // Call the GetOpenFilename function
  176.  
  177.    if (wIDString == IDS_OPENDLG)
  178.     {
  179.     if (GetOpenFileName (&of))
  180.       {
  181.       lstrcpy (szFileName, of.lpstrFile);
  182.       return TRUE;
  183.       }
  184.     else
  185.       return FALSE;
  186.     }
  187.    else
  188.     {
  189.     if (GetSaveFileName (&of))
  190.       {
  191.       lstrcpy (szFileName, of.lpstrFile);
  192.       return TRUE;
  193.       }
  194.     }
  195. }
  196.  
  197.  
  198. /*************************************************************************
  199.  
  200.   Function:  ReadDIBFile (int)
  201.  
  202.    Purpose:  Reads in the specified DIB file into a global chunk of
  203.              memory.
  204.  
  205.    Returns:  A handle to a dib (hDIB) if successful.
  206.              NULL if an error occurs.
  207.  
  208.   Comments:  BITMAPFILEHEADER is stripped off of the DIB.  Everything
  209.              from the end of the BITMAPFILEHEADER structure on is
  210.              returned in the global memory handle.
  211.  
  212.    History:   Date      Author      Reason
  213.  
  214.              6/1/91    Created
  215.              6/27/91   Removed PM bitmap conversion routines.
  216.              6/31/91   Removed logic which overallocated memory
  217.                        (to account for bad display drivers).
  218.             11/08/91   Again removed logic which overallocated
  219.                        memory (it had creeped back in!)
  220.  
  221. *************************************************************************/
  222.  
  223. HANDLE ReadDIBFile (int hFile)
  224. {
  225.    BITMAPFILEHEADER   bmfHeader;
  226.    DWORD              dwBitsSize;
  227.    HANDLE             hDIB;
  228.    LPSTR              pDIB;
  229.  
  230.  
  231.    // get length of DIB in bytes for use when reading
  232.  
  233.    dwBitsSize = filelength (hFile);
  234.  
  235.    // Go read the DIB file header and check if it's valid.
  236.  
  237.    if ((_lread (hFile, (LPSTR) &bmfHeader, sizeof (bmfHeader)) != sizeof (bmfHeader)) ||
  238.         (bmfHeader.bfType != DIB_HEADER_MARKER))
  239.       {
  240.       DIBError (ERR_NOT_DIB);
  241.       return NULL;
  242.       }
  243.  
  244.    // Allocate memory for DIB
  245.  
  246.    hDIB = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize - sizeof(BITMAPFILEHEADER));
  247.  
  248.    if (hDIB == 0)
  249.      {
  250.      DIBError (ERR_MEMORY);
  251.      return NULL;
  252.      }
  253.  
  254.    pDIB = GlobalLock (hDIB);
  255.  
  256.    // Go read the bits.
  257.  
  258.    if (!MyRead (hFile, pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)))
  259.       {
  260.       GlobalUnlock (hDIB);
  261.       GlobalFree   (hDIB);
  262.       DIBError (ERR_READ);
  263.       return NULL;
  264.       }
  265.  
  266.  
  267.    GlobalUnlock (hDIB);
  268.    return hDIB;
  269. }
  270.  
  271. /*************************************************************************
  272.  
  273.   Function:  MyRead (int, LPSTR, DWORD)
  274.  
  275.    Purpose:  Routine to read files greater than 64K in size.
  276.  
  277.    Returns:  TRUE if successful.
  278.              FALSE if an error occurs.
  279.  
  280.   Comments:
  281.  
  282.    History:   Date     Reason
  283.  
  284.              6/1/91    Created
  285.  
  286. *************************************************************************/
  287.  
  288. BOOL MyRead (int hFile, LPSTR lpBuffer, DWORD dwSize)
  289. {
  290.    char huge *lpInBuf = (char huge *) lpBuffer;
  291.    int       nBytes;
  292.  
  293.  
  294.    while (dwSize)
  295.       {
  296.       nBytes = (int) (dwSize > (DWORD) BYTES_PER_READ ? BYTES_PER_READ :
  297.                                                         LOWORD (dwSize));
  298.  
  299.       if (_lread (hFile, (LPSTR) lpInBuf, nBytes) != (WORD) nBytes)
  300.          return FALSE;
  301.  
  302.       dwSize  -= nBytes;
  303.       lpInBuf += nBytes;
  304.       }
  305.  
  306.    return TRUE;
  307. }
  308.  
  309. /*************************************************************************
  310.  
  311.   Function:  FileOpenHookProc (HWND, WORD, WORD, LONG)
  312.  
  313.    Purpose:  Hook procedure for FileOpen common dialog box.
  314.  
  315.    Returns:  TRUE if message was processed.
  316.              FALSE if the system needs to process the message.
  317.  
  318.   Comments:
  319.  
  320.    History:   Date     Reason
  321.  
  322.              6/27/91   Created
  323.              11/2/92    Moved to _TEXT segment to allow call into C runtime
  324.  
  325. *************************************************************************/
  326.  
  327. BOOL FAR PASCAL __export FileOpenHookProc (HWND hDlg, WORD msg, WORD wParam, LONG lParam)
  328. {
  329.   INFOSTRUCT info;
  330.   FARPROC    lpInfo;
  331.  
  332.   switch (msg)
  333.     {
  334.     case WM_COMMAND:
  335.         switch (wParam)
  336.           {
  337.           case IDOK:
  338.            getcwd (szDirName, DIRNAMESIZE);
  339.            break;
  340.  
  341.           case IDD_INFO:
  342.  
  343.             // User has selected the Dib Information button.  Query the
  344.             // text in the edit control, check if it is a valid file, get
  345.             // the file statistics, and then display the dialog box.
  346.  
  347.             GetDlgItemText (hDlg, edt1, (LPSTR) szFileName, sizeof (szFileName));
  348.  
  349.             if (!CheckIfFileExists(szFileName))
  350.                 {
  351.                 DIBError (ERR_OPEN);
  352.                 SetFocus (GetDlgItem(hDlg, edt1));
  353.                 return FALSE;
  354.                 }
  355.  
  356.             if (!GetDibInfo (szFileName, &info))
  357.                 {
  358.                 DIBError (ERR_READ);
  359.                 return FALSE;
  360.                 }
  361.  
  362.             lpInfo = MakeProcInstance(InfoDlgProc, hInst);
  363.             DialogBoxParam(hInst, "INFO", hDlg, lpInfo,
  364.                           (DWORD) (INFOSTRUCT FAR *) &info);
  365.             FreeProcInstance (lpInfo);
  366.             break;
  367.           }
  368.     break;
  369.     }
  370.   return FALSE;
  371. }
  372.  
  373. /*************************************************************************
  374.  
  375.   Function:  CheckIfFileExists (char *)
  376.  
  377.    Purpose:  Checks to see if the user selected file exists.
  378.  
  379.    Returns:  TRUE if the file is opened.
  380.              FALSE if the file does not exists.
  381.  
  382.   Comments:  After checking the file, the file is immediately closed again.
  383.  
  384.    History:   Date     Reason
  385.  
  386.              6/27/91   Created
  387.  
  388. *************************************************************************/
  389.  
  390. int CheckIfFileExists (char * szFileName)
  391. {
  392.   int      hFile;
  393.   OFSTRUCT ofstruct;
  394.  
  395.   if (szFileName[0] == '\0')
  396.     return FALSE;
  397.  
  398.   hFile = OpenFile((LPSTR) szFileName, &ofstruct, OF_EXIST);
  399.  
  400.   if (hFile > 0)
  401.     return TRUE;
  402.   else
  403.     return FALSE;
  404. }
  405.  
  406.  
  407. /*************************************************************************
  408.  
  409.   Function:  GetDibInfo (char *, INFOSTRUCT *)
  410.  
  411.    Purpose:  Retrieves the INFOSTRUCT specifications about the selected
  412.              file when the "Dib Information..." button is selected.
  413.  
  414.    Returns:  TRUE if successful
  415.              FALSE if an error occurs.
  416.  
  417.   Comments:  This routine will handle both Windows and PM bitmaps.
  418.              If an PM bitmap is found, NULL is returned for the
  419.              compression type.
  420.  
  421.    History:   Date     Reason
  422.  
  423.              6/27/91   Created
  424.  
  425. *************************************************************************/
  426.  
  427. int GetDibInfo (char * szFileName, INFOSTRUCT * info)
  428. {
  429.   BITMAPFILEHEADER   bmfHeader;
  430.   BITMAPINFOHEADER   DIBHeader;
  431.   DWORD              dwHeaderSize;
  432.   int                hFile;
  433.   OFSTRUCT           ofstruct;
  434.   BITMAPCOREHEADER   bmCore;
  435.   long               lFilePos;
  436.   char               szBuffer[20];
  437.  
  438.  
  439.   if (!szFileName[0])
  440.     return NULL;
  441.  
  442.   // fill in filename into structure.
  443.  
  444.   lstrcpy ((LPSTR) info->szName, (LPSTR) szFileName);
  445.  
  446.   hFile=OpenFile((LPSTR) szFileName, &ofstruct, OF_READ | OF_SHARE_DENY_WRITE);
  447.  
  448.   if (hFile == 0)
  449.     return NULL;
  450.  
  451.   // read the BITMAPFILEHEADER structure and check for BM marker
  452.  
  453.   if ((_lread (hFile, (LPSTR) &bmfHeader, sizeof (bmfHeader)) != sizeof (bmfHeader)) ||
  454.        (bmfHeader.bfType != DIB_HEADER_MARKER))
  455.      {
  456.      DIBError (ERR_NOT_DIB);
  457.      _lclose(hFile);
  458.      return NULL;
  459.      }
  460.  
  461.   // Get the current file pointer position, and then read the next
  462.   // DWORD.  This DWORD is the size of the following structure which
  463.   // will determine if it is a PM DIB or Windows DIB.
  464.  
  465.   if (((lFilePos = tell (hFile)) == -1) ||
  466.       (_lread (hFile, (LPSTR) &dwHeaderSize, sizeof (dwHeaderSize))
  467.         != sizeof (dwHeaderSize)))
  468.      {
  469.      _lclose(hFile);
  470.      return NULL;
  471.      }
  472.  
  473.   // Back the file pointer up a DWORD so that we can read the information
  474.   // into the correct data structure.
  475.  
  476.   lseek (hFile, lFilePos, SEEK_SET);
  477.  
  478.  
  479.   if (dwHeaderSize == sizeof (BITMAPCOREHEADER))      // PM dib
  480.      {
  481.      _lread (hFile, (LPSTR) &bmCore, sizeof (bmCore));
  482.  
  483.      LoadString (hInst, IDS_PMBMP, szBuffer, sizeof(szBuffer));
  484.      lstrcpy ((LPSTR)info->szType, (LPSTR) szBuffer);
  485.  
  486.      info->cbWidth  = bmCore.bcWidth;
  487.      info->cbHeight = bmCore.bcHeight;
  488.      info->cbColors = (DWORD)1L << (bmCore.bcBitCount);
  489.      szBuffer[0]=0;
  490.      lstrcpy ((LPSTR) info->szCompress, (LPSTR) szBuffer);
  491.  
  492.      }
  493.   else if (dwHeaderSize == sizeof (BITMAPINFOHEADER))  // windows dib
  494.      {
  495.      _lread (hFile, (LPSTR) &DIBHeader, sizeof (DIBHeader));
  496.  
  497.      LoadString (hInst, IDS_WINBMP, szBuffer, sizeof(szBuffer));
  498.      lstrcpy ((LPSTR)info->szType, (LPSTR) szBuffer);
  499.  
  500.      info->cbWidth  = DIBHeader.biWidth;
  501.      info->cbHeight = DIBHeader.biHeight;
  502.      info->cbColors = (DWORD)1L << DIBHeader.biBitCount;
  503.  
  504.      switch (DIBHeader.biCompression)
  505.        {
  506.        case BI_RGB:
  507.           LoadString (hInst, IDS_RGB, szBuffer, sizeof(szBuffer));
  508.           break;
  509.  
  510.        case BI_RLE4:
  511.           LoadString (hInst, IDS_RLE4, szBuffer, sizeof(szBuffer));
  512.           break;
  513.  
  514.        case BI_RLE8:
  515.           LoadString (hInst, IDS_RLE8, szBuffer, sizeof(szBuffer));
  516.           break;
  517.  
  518.        default:
  519.           szBuffer[0]=0;
  520.        }
  521.  
  522.      lstrcpy ((LPSTR) info->szCompress, (LPSTR) szBuffer);
  523.      }
  524.   else
  525.     {
  526.     DIBError (ERR_NOT_DIB);
  527.     _lclose(hFile);
  528.     return NULL;
  529.     }
  530.  
  531.   _lclose(hFile);
  532.   return 1;
  533. }
  534.  
  535.  
  536. /*************************************************************************
  537.  
  538.   Function:  InfoDlgProc (HWND, WORD, WORD, LONG)
  539.  
  540.    Purpose:  Window procedure for the Dib Information dialog box.
  541.  
  542.    Returns:  TRUE if the message was processed.
  543.              FALSE if the system needs to process the message.
  544.  
  545.   Comments:
  546.  
  547.    History:   Date     Reason
  548.  
  549.              6/27/91   Created
  550.  
  551. *************************************************************************/
  552.  
  553. BOOL FAR PASCAL __export InfoDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam)
  554. {
  555.   INFOSTRUCT * pInfo;
  556.   char         szBuffer[20];
  557.  
  558.   switch (message)
  559.     {
  560.     case WM_INITDIALOG:
  561.         pInfo = (INFOSTRUCT *) lParam;
  562.  
  563.         // Set the strings into the dialog box.
  564.  
  565.         SetDlgItemText(hDlg, IDD_NAME, (LPSTR) pInfo->szName);
  566.         SetDlgItemText(hDlg, IDD_FORMAT, (LPSTR) pInfo->szType);
  567.         wvsprintf ((LPSTR)szBuffer, (LPSTR) "%lu", (LPSTR) &pInfo->cbWidth);
  568.         SetDlgItemText(hDlg, IDD_WIDTH, (LPSTR) szBuffer);
  569.         wvsprintf ((LPSTR)szBuffer, (LPSTR) "%lu", (LPSTR) &pInfo->cbHeight);
  570.         SetDlgItemText(hDlg, IDD_HEIGHT, (LPSTR) szBuffer);
  571.         wvsprintf ((LPSTR)szBuffer, (LPSTR) "%lu", (LPSTR) &pInfo->cbColors);
  572.         SetDlgItemText(hDlg, IDD_COLORS, (LPSTR) szBuffer);
  573.  
  574.         if (pInfo->szCompress[0] == 0)
  575.            ShowWindow(GetDlgItem (hDlg, IDD_COMPHEAD), SW_HIDE);
  576.         else
  577.            SetDlgItemText(hDlg, IDD_COMPRESS, (LPSTR) pInfo->szCompress);
  578.  
  579.         return (TRUE);
  580.  
  581.     case WM_COMMAND:
  582.         if (wParam == IDOK || wParam == IDCANCEL)
  583.            {
  584.            EndDialog(hDlg, TRUE);
  585.            return (TRUE);
  586.            }
  587.            break;
  588.  
  589.     }
  590.   return (FALSE);
  591. }
  592.  
  593. /*************************************************************************
  594.  
  595.   Function:  SaveDIBFile (void)
  596.  
  597.    Purpose:  Prompts user for a filename, opens it, and writes DIB
  598.              out in format specified.
  599.  
  600.    Returns:  FALSE if no file is opened, or an error occurs writing the file.
  601.              TRUE  if successful
  602.  
  603.   Comments:
  604.  
  605.    History:   Date      Reason
  606.  
  607.              7/8/91    Created
  608.              10/1/91   BugFix -- wasn't freeing allocated memory,
  609.                         Cleaned up code, and added comments.
  610.              10/2/91   Added error checking/reporting
  611.  
  612. *************************************************************************/
  613.  
  614. BOOL SaveDIBFile (void)
  615. {
  616.    HANDLE    hDib, hDibInfo;
  617.    LPDIBINFO lpDIBInfo;
  618.  
  619.  
  620.       // Get the FileName to save under.
  621.  
  622.    if (GetFileName (szFileName, IDS_SAVEDLG))
  623.       {
  624.       SetCursor(LoadCursor(NULL, IDC_WAIT));
  625.  
  626.  
  627.          // Get all the info on the current DIB Window.
  628.  
  629.       hDibInfo  = (HANDLE) GetWindowWord (GetCurrentMDIWnd(), WW_DIB_HINFO);
  630.       lpDIBInfo = (LPDIBINFO) GlobalLock (hDibInfo);
  631.  
  632.  
  633.          // Convert the DDB to the format wanted.
  634.  
  635.       if (biStyle == BI_PM)
  636.         hDib = PMDibFromBitmap (lpDIBInfo->hBitmap,
  637.                                 biStyle,
  638.                                 biBits,
  639.                                 lpDIBInfo->hPal);
  640.       else
  641.         hDib = WinDibFromBitmap (lpDIBInfo->hBitmap,
  642.                                  biStyle,
  643.                                  biBits,
  644.                                  lpDIBInfo->hPal);
  645.  
  646.  
  647.          // Write out the DIB in the specified format.
  648.  
  649.       if (!WriteDIB ((LPSTR)szFileName, hDib))
  650.          DIBError (ERR_WRITEDIB);
  651.  
  652.  
  653.          // Clean up and return.
  654.  
  655.       GlobalFree (hDib);
  656.       GlobalUnlock (hDibInfo);
  657.       SetCursor(LoadCursor(NULL, IDC_ARROW));
  658.       return TRUE;
  659.       }
  660.  
  661.    return FALSE;
  662. }
  663.  
  664.  
  665.  
  666. /*************************************************************************
  667.  
  668.   Function:  FileSaveHookProc (HWND, WORD, WORD, LONG)
  669.  
  670.    Purpose:  Hook procedure for FileSave common dialog box.
  671.  
  672.    Returns:  TRUE if message was processed.
  673.              FALSE if the system needs to process the message.
  674.  
  675.   Comments:
  676.  
  677.    History:   Date    Reason
  678.  
  679.              7/8/91   Created
  680.  
  681. *************************************************************************/
  682.  
  683. BOOL FAR PASCAL __export FileSaveHookProc (HWND hDlg, WORD msg, WORD wParam, LONG lParam)
  684. {
  685.   HANDLE    hDibInfo;
  686.   LPDIBINFO ptr;
  687.   HWND      hGroup;
  688.   RECT      rect, DlgRect;
  689.  
  690.   switch (msg)
  691.     {
  692.     case WM_INITDIALOG:
  693.  
  694.         //  Get the memory handle stored in the extra words.
  695.         //  From this, insert the filename, and the file format
  696.  
  697.         hDibInfo = (HANDLE) GetWindowWord (GetCurrentMDIWnd(), WW_DIB_HINFO);
  698.         ptr = (LPDIBINFO) GlobalLock (hDibInfo);
  699.  
  700.         switch (ptr->wDIBType)
  701.           {
  702.           case BI_RGB:
  703.             SendDlgItemMessage (hDlg, IDD_RGB,  BM_SETCHECK, 1, 0L);
  704.             break;
  705.  
  706.           case BI_RLE4:
  707.             SendDlgItemMessage (hDlg, IDD_RLE4, BM_SETCHECK, 1, 0L);
  708.             break;
  709.  
  710.           case BI_RLE8:
  711.             SendDlgItemMessage (hDlg, IDD_RLE8, BM_SETCHECK, 1, 0L);
  712.             break;
  713.  
  714.           case BI_PM:
  715.             SendDlgItemMessage (hDlg, IDD_PM,   BM_SETCHECK, 1, 0L);
  716.             break;
  717.           }
  718.  
  719.         switch (ptr->wDIBBits)
  720.           {
  721.           case 1:
  722.             SendDlgItemMessage (hDlg, IDD_1,   BM_SETCHECK, 1, 0L);
  723.             break;
  724.  
  725.           case 4:
  726.             SendDlgItemMessage (hDlg, IDD_4,   BM_SETCHECK, 1, 0L);
  727.             break;
  728.  
  729.           case 8:
  730.             SendDlgItemMessage (hDlg, IDD_8,   BM_SETCHECK, 1, 0L);
  731.             break;
  732.  
  733.           case 24:
  734.             SendDlgItemMessage (hDlg, IDD_24,  BM_SETCHECK, 1, 0L);
  735.             break;
  736.           }
  737.  
  738.         GlobalUnlock (hDibInfo);
  739.         break;
  740.  
  741.     case WM_COMMAND:
  742.         switch (wParam)
  743.           {
  744.           case IDOK:
  745.             if (SendDlgItemMessage (hDlg, IDD_RGB, BM_GETCHECK, 0, 0L))
  746.                biStyle = BI_RGB;
  747.  
  748.             else if (SendDlgItemMessage (hDlg, IDD_RLE4, BM_GETCHECK, 0, 0L))
  749.                biStyle = BI_RLE4;
  750.  
  751.             else if (SendDlgItemMessage (hDlg, IDD_RLE8, BM_GETCHECK, 0, 0L))
  752.                biStyle = BI_RLE8;
  753.  
  754.             else
  755.                biStyle = BI_PM;
  756.  
  757.  
  758.             if (SendDlgItemMessage (hDlg, IDD_1, BM_GETCHECK, 0, 0L))
  759.                biBits = 1;
  760.  
  761.             else if (SendDlgItemMessage (hDlg, IDD_4, BM_GETCHECK, 0, 0L))
  762.                biBits = 4;
  763.  
  764.             else if (SendDlgItemMessage (hDlg, IDD_8, BM_GETCHECK, 0, 0L))
  765.                biBits = 8;
  766.  
  767.             else
  768.                biBits = 24;
  769.  
  770.             break;
  771.  
  772.           case IDD_FILETYPE:
  773.             hGroup = GetDlgItem (hDlg, IDD_FILETYPEGROUP);
  774.             GetWindowRect (hGroup, &rect);
  775.             GetWindowRect (hDlg, &DlgRect);
  776.             SetWindowPos (hDlg,0, DlgRect.left, DlgRect.top,
  777.                          (DlgRect.right-DlgRect.left),
  778.                           (rect.bottom+(rect.left-DlgRect.left)-DlgRect.top),
  779.                           SWP_NOMOVE | SWP_NOZORDER);
  780.             EnableWindow (GetDlgItem (hDlg, IDD_FILETYPE), 0);
  781.             SetFocus (hGroup);
  782.             break;
  783.  
  784.           case IDD_RLE4:
  785.             if (SendDlgItemMessage (hDlg, IDD_1, BM_GETCHECK, 0, 0L))
  786.                SendDlgItemMessage (hDlg, IDD_1, BM_SETCHECK, 0,0L);
  787.             if (SendDlgItemMessage (hDlg, IDD_8, BM_GETCHECK, 0, 0L))
  788.                SendDlgItemMessage (hDlg, IDD_8, BM_SETCHECK, 0,0L);
  789.             if (SendDlgItemMessage (hDlg, IDD_24, BM_GETCHECK, 0, 0L))
  790.                SendDlgItemMessage (hDlg, IDD_24, BM_SETCHECK, 0,0L);
  791.  
  792.             EnableWindow (GetDlgItem(hDlg, IDD_4), 1);
  793.             SendDlgItemMessage (hDlg, IDD_4, BM_SETCHECK, 1, 0L);
  794.             EnableWindow (GetDlgItem(hDlg, IDD_1), 0);
  795.             EnableWindow (GetDlgItem(hDlg, IDD_8), 0);
  796.             EnableWindow (GetDlgItem(hDlg, IDD_24), 0);
  797.             break;
  798.  
  799.           case IDD_RLE8:
  800.             if (SendDlgItemMessage (hDlg, IDD_1, BM_GETCHECK, 0, 0L))
  801.                SendDlgItemMessage (hDlg, IDD_1, BM_SETCHECK, 0,0L);
  802.             if (SendDlgItemMessage (hDlg, IDD_4, BM_GETCHECK, 0, 0L))
  803.                SendDlgItemMessage (hDlg, IDD_4, BM_SETCHECK, 0,0L);
  804.             if (SendDlgItemMessage (hDlg, IDD_24, BM_GETCHECK, 0, 0L))
  805.                SendDlgItemMessage (hDlg, IDD_24, BM_SETCHECK, 0,0L);
  806.  
  807.             EnableWindow (GetDlgItem(hDlg, IDD_8), 1);
  808.             SendDlgItemMessage (hDlg, IDD_8, BM_SETCHECK, 1, 0L);
  809.             EnableWindow (GetDlgItem(hDlg, IDD_1), 0);
  810.             EnableWindow (GetDlgItem(hDlg, IDD_4), 0);
  811.             EnableWindow (GetDlgItem(hDlg, IDD_24), 0);
  812.             break;
  813.  
  814.           case IDD_RGB:
  815.           case IDD_PM:
  816.             EnableWindow (GetDlgItem(hDlg, IDD_1), 1);
  817.             EnableWindow (GetDlgItem(hDlg, IDD_4), 2);
  818.             EnableWindow (GetDlgItem(hDlg, IDD_8), 3);
  819.             EnableWindow (GetDlgItem(hDlg, IDD_24), 1);
  820.             break;
  821.           }
  822.         break;
  823.  
  824.     default:
  825.       break;
  826.     }
  827.   return FALSE;
  828. }
  829.  
  830.  
  831. /****************************************************************************
  832.  
  833.   FUNCTION   : WinDibFromBitmap()
  834.  
  835.   PURPOSE    : Will create a global memory block in DIB format that
  836.          represents the Device-dependent bitmap (DDB) passed in.
  837.  
  838.               biStyle -> DIB format     ==  RGB, RLE
  839.               biBits  -> Bits per pixel ==  1,4,8,24
  840.  
  841.   RETURNS    : A handle to the DIB
  842.  
  843.  ****************************************************************************/
  844. HANDLE WinDibFromBitmap (HBITMAP hBitmap,
  845.                            DWORD dwStyle,
  846.                             WORD wBits,
  847.                         HPALETTE hPal)
  848. {
  849.    BITMAP               bm;
  850.    BITMAPINFOHEADER     bi;
  851.    BITMAPINFOHEADER FAR *lpbi;
  852.    DWORD                dwLen;
  853.    HANDLE               hDIB;
  854.    HANDLE               h;
  855.    HDC                  hDC;
  856.  
  857.    if (!hBitmap)
  858.       return NULL;
  859.  
  860.    if (hPal == NULL)
  861.       hPal = GetStockObject (DEFAULT_PALETTE);
  862.  
  863.    GetObject (hBitmap, sizeof (bm), (LPSTR)&bm);
  864.  
  865.    if (wBits == 0)
  866.       wBits =  bm.bmPlanes * bm.bmBitsPixel;
  867.  
  868.    if (wBits <= 1)
  869.       wBits = 1;
  870.    else if (wBits <= 4)
  871.       wBits = 4;
  872.    else if (wBits <= 8)
  873.       wBits = 8;
  874.    else
  875.       wBits = 24;
  876.  
  877.    bi.biSize               = sizeof (BITMAPINFOHEADER);
  878.    bi.biWidth              = bm.bmWidth;
  879.    bi.biHeight             = bm.bmHeight;
  880.    bi.biPlanes             = 1;
  881.    bi.biBitCount           = wBits;
  882.    bi.biCompression        = dwStyle;
  883.    bi.biSizeImage          = 0;
  884.    bi.biXPelsPerMeter      = 0;
  885.    bi.biYPelsPerMeter      = 0;
  886.    bi.biClrUsed            = 0;
  887.    bi.biClrImportant       = 0;
  888.  
  889.    dwLen  = bi.biSize + PaletteSize ((LPSTR) &bi);
  890.    hDIB = GlobalAlloc(GHND,dwLen);
  891.  
  892.    if (!hDIB)
  893.       return NULL;
  894.  
  895.    lpbi   = (VOID FAR *)GlobalLock(hDIB);
  896.    *lpbi  = bi;
  897.    hDC    = GetDC (NULL);
  898.    hPal   = SelectPalette (hDC, hPal, FALSE);
  899.    RealizePalette(hDC);
  900.  
  901.  
  902.  
  903.     /*   call GetDIBits with a NULL lpBits param, so it will calculate the
  904.      *  biSizeImage field for us
  905.      */
  906.    GetDIBits (hDC,
  907.               hBitmap,
  908.               0,
  909.               (WORD) bi.biHeight,
  910.               NULL,
  911.               (LPBITMAPINFO) lpbi,
  912.               DIB_RGB_COLORS);
  913.  
  914.    bi = *lpbi;
  915.    GlobalUnlock(hDIB);
  916.  
  917.     /* If the driver did not fill in the biSizeImage field, make one up */
  918.    if (bi.biSizeImage == 0)
  919.       {
  920.       bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * wBits) * bm.bmHeight;
  921.  
  922.       if (dwStyle != BI_RGB)
  923.          bi.biSizeImage = (bi.biSizeImage * 3) / 2;
  924.       }
  925.  
  926.     /*   realloc the buffer big enough to hold all the bits */
  927.  
  928.    dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + bi.biSizeImage;
  929.    if (h = GlobalReAlloc(hDIB,dwLen,0))
  930.       hDIB = h;
  931.    else
  932.       {
  933.       GlobalFree(hDIB);
  934.       hDIB = NULL;
  935.       SelectPalette(hDC,hPal,FALSE);
  936.       ReleaseDC(NULL,hDC);
  937.       return hDIB;
  938.       }
  939.  
  940.     /*   call GetDIBits with a NON-NULL lpBits param, and actualy get the
  941.      *  bits this time
  942.      */
  943.    lpbi = (VOID FAR *)GlobalLock(hDIB);
  944.  
  945.    if (GetDIBits( hDC,
  946.          hBitmap,
  947.          0,
  948.          (WORD) bi.biHeight,
  949.          (LPSTR) lpbi + (WORD) lpbi->biSize + PaletteSize((LPSTR) lpbi),
  950.          (LPBITMAPINFO) lpbi, DIB_RGB_COLORS) == 0)
  951.       {
  952.       GlobalUnlock (hDIB);
  953.       hDIB = NULL;
  954.       SelectPalette (hDC, hPal, FALSE);
  955.       ReleaseDC (NULL, hDC);
  956.       return NULL;
  957.       }
  958.  
  959.    bi = *lpbi;
  960.    GlobalUnlock (hDIB);
  961.  
  962.    SelectPalette (hDC, hPal, FALSE);
  963.    ReleaseDC (NULL, hDC);
  964.    return hDIB;
  965. }
  966.  
  967.  
  968.  
  969. /****************************************************************************
  970.  
  971.  FUNCTION   : WriteDIB(LPSTR szFile,HANDLE hdib)
  972.  
  973.  PURPOSE    : Write a global handle in CF_DIB format to a file.
  974.  
  975.  RETURNS    : TRUE  - if successful.
  976.          FALSE - otherwise
  977.  
  978.  ****************************************************************************/
  979. BOOL WriteDIB (szFile, hdib)
  980. LPSTR szFile;
  981. HANDLE hdib;
  982. {
  983.     BITMAPFILEHEADER    hdr;
  984.     LPBITMAPINFOHEADER  lpbi;
  985.     int                 fh;
  986.     OFSTRUCT            of;
  987.  
  988.     if (!hdib)
  989.     return FALSE;
  990.  
  991.     fh = OpenFile (szFile, &of, OF_CREATE|OF_READWRITE);
  992.     if (fh == -1)
  993.     return FALSE;
  994.  
  995.     lpbi = (VOID FAR *)GlobalLock (hdib);
  996.  
  997.     /* Fill in the fields of the file header */
  998.     hdr.bfType        = DIB_HEADER_MARKER;
  999.     hdr.bfSize        = GlobalSize (hdib) + sizeof (BITMAPFILEHEADER);
  1000.     hdr.bfReserved1     = 0;
  1001.     hdr.bfReserved2     = 0;
  1002.     hdr.bfOffBits       = (DWORD)sizeof(BITMAPFILEHEADER) + lpbi->biSize +
  1003.                           PaletteSize((LPSTR)lpbi);
  1004.  
  1005.     /* Write the file header */
  1006.     if (!_lwrite (fh, (LPSTR)&hdr, sizeof (BITMAPFILEHEADER)))
  1007.       {
  1008.       GlobalUnlock (hdib);
  1009.       _lclose (fh);
  1010.       return FALSE;
  1011.       }
  1012.  
  1013.     /* Write the DIB header and the bits */
  1014.     if (!lwrite (fh, (LPSTR)lpbi, GlobalSize (hdib)))
  1015.       {
  1016.       GlobalUnlock (hdib);
  1017.       _lclose (fh);
  1018.       return FALSE;
  1019.       }
  1020.  
  1021.     GlobalUnlock (hdib);
  1022.     _lclose (fh);
  1023.     return TRUE;
  1024. }
  1025.  
  1026. /****************************************************************************
  1027.  
  1028.  FUNCTION   : lwrite(int fh, VOID FAR *pv, DWORD ul)
  1029.  
  1030.  PURPOSE    : Writes data in steps of 32k till all the data is written.
  1031.  
  1032.  RETURNS    : 0 - If write did not proceed correctly.
  1033.          number of bytes written otherwise.
  1034.  
  1035.  ****************************************************************************/
  1036. DWORD PASCAL lwrite (fh, pv, ul)
  1037. int         fh;
  1038. VOID FAR     *pv;
  1039. DWORD         ul;
  1040. {
  1041.    DWORD     ulT = ul;
  1042.    BYTE huge *hp = pv;
  1043.  
  1044.    while (ul > BYTES_PER_READ)
  1045.       {
  1046.       if (_lwrite(fh, (LPSTR)hp, (WORD)BYTES_PER_READ) != BYTES_PER_READ)
  1047.            return 0;
  1048.  
  1049.       ul -= BYTES_PER_READ;
  1050.       hp += BYTES_PER_READ;
  1051.       }
  1052.  
  1053.    if (_lwrite(fh, (LPSTR)hp, (WORD)ul) != (WORD)ul)
  1054.       return 0;
  1055.  
  1056.    return ulT;
  1057. }
  1058.  
  1059. /****************************************************************************
  1060.  
  1061.  FUNCTION   : PMDibFromBitmap()
  1062.  
  1063.  PURPOSE    : Will create a global memory block in DIB format that
  1064.          represents the Device-dependent bitmap (DDB) passed in.
  1065.  
  1066.               biStyle -> DIB format     ==  PM
  1067.               biBits  -> Bits per pixel ==  1,4,8,24
  1068.  
  1069.  RETURNS    : A handle to the DIB
  1070.  
  1071.  ****************************************************************************/
  1072. HANDLE PMDibFromBitmap (hbm, biStyle, biBits, hpal)
  1073. HBITMAP      hbm;
  1074. DWORD         biStyle;
  1075. WORD         biBits;
  1076. HPALETTE     hpal;
  1077. {
  1078.     BITMAP               bm;
  1079.     BITMAPCOREINFO     bi;
  1080.     BITMAPCOREINFO FAR *lpbi;
  1081.     DWORD                dwLen;
  1082.     HANDLE               hdib;
  1083.     HDC                  hdc;
  1084.     DWORD                SizeImage;
  1085.  
  1086.     if (!hbm)
  1087.     return NULL;
  1088.  
  1089.     if (hpal == NULL)
  1090.         hpal = GetStockObject(DEFAULT_PALETTE);
  1091.  
  1092.     GetObject(hbm,sizeof(bm),(LPSTR)&bm);
  1093.  
  1094.     if (biBits == 0)
  1095.     biBits =  bm.bmPlanes * bm.bmBitsPixel;
  1096.  
  1097.     bi.bmciHeader.bcSize               = sizeof(BITMAPCOREHEADER);
  1098.     bi.bmciHeader.bcWidth              = bm.bmWidth;
  1099.     bi.bmciHeader.bcHeight             = bm.bmHeight;
  1100.     bi.bmciHeader.bcPlanes             = 1;
  1101.     bi.bmciHeader.bcBitCount           = biBits;
  1102.  
  1103.     SizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
  1104.  
  1105.     dwLen  = bi.bmciHeader.bcSize + PaletteSize((LPSTR)&bi) + SizeImage;
  1106.  
  1107.     hdc = GetDC(NULL);
  1108.     hpal = SelectPalette(hdc,hpal,FALSE);
  1109.      RealizePalette(hdc);
  1110.  
  1111.     hdib = GlobalAlloc(GHND,dwLen);
  1112.  
  1113.     if (!hdib)
  1114.       {
  1115.     SelectPalette(hdc,hpal,FALSE);
  1116.     ReleaseDC(NULL,hdc);
  1117.     return NULL;
  1118.       }
  1119.  
  1120.     lpbi = (VOID FAR *)GlobalLock(hdib);
  1121.  
  1122.     *lpbi = bi;
  1123.  
  1124.     if (GetDIBits( hdc,
  1125.            hbm,
  1126.            0,
  1127.            (WORD)bi.bmciHeader.bcHeight,
  1128.            (LPSTR)lpbi + (WORD)bi.bmciHeader.bcSize + PaletteSize((LPSTR)&bi),
  1129.            (LPBITMAPINFO)(LPBITMAPCOREINFO) lpbi, DIB_RGB_COLORS) == 0)
  1130.          {
  1131.      GlobalUnlock(hdib);
  1132.      hdib = NULL;
  1133.      SelectPalette(hdc,hpal,FALSE);
  1134.      ReleaseDC(NULL,hdc);
  1135.      return NULL;
  1136.          }
  1137.  
  1138.     bi = *lpbi;
  1139.     GlobalUnlock(hdib);
  1140.  
  1141.     SelectPalette(hdc,hpal,FALSE);
  1142.     ReleaseDC(NULL,hdc);
  1143.     return hdib;
  1144. }
  1145.  
  1146.  
  1147.  
  1148. LPSTR SkipCharacter(LPSTR lpSearch,
  1149.                     BYTE  cTarget)
  1150. {
  1151.   BYTE cLook;
  1152.  
  1153.   while(cLook=*lpSearch++)
  1154.     if(cLook!=cTarget)
  1155.       return --lpSearch;
  1156.  
  1157.   return NULL;
  1158. }
  1159.  
  1160.  
  1161. LPSTR FindCharacter(LPSTR lpSearch,
  1162.                     BYTE  cTarget)
  1163. {
  1164.   BYTE cLook;
  1165.  
  1166.   while(cLook=*lpSearch++)
  1167.     if(cLook==cTarget)
  1168.       return --lpSearch;
  1169.  
  1170.   return NULL;
  1171. }
  1172.  
  1173.  
  1174. /*************************************************************************
  1175.  
  1176.   Function:  GetSectionName (lpCmdLine)
  1177.  
  1178.    Purpose:  Check for command line switch and save it.
  1179.  
  1180.    Return:   Pointer to first non-space, non-section name character
  1181.  
  1182.   Comments:
  1183.  
  1184.    History:   Date     Reason
  1185.  
  1186.             11/13/91   Created
  1187.             11/15/91   Added code to skip leading spaces.
  1188.                        Otherwise would enter infinite loop
  1189.                        if >1 file specified on command line.
  1190.  
  1191. *************************************************************************/
  1192. LPSTR GetSectionName(LPSTR lpCmdLine)
  1193. {
  1194.   LPSTR lpWork;
  1195.   BOOL  bEndOfString = FALSE;
  1196. //  LPSTR lpStartHere;
  1197.  
  1198.  
  1199.   // Skip any leading spaces.
  1200.   while (*lpCmdLine == ' ')
  1201.       *lpCmdLine++;
  1202.   lpWork = lpCmdLine;
  1203.  
  1204.   // Use a switch instead of if, so we can easily add other switches in
  1205.   // the future.
  1206.  
  1207. //  switch(*lpWork)
  1208. //  {
  1209. //    case '/':
  1210. //    case '-':
  1211. //      switch(*(lpWork+1))
  1212. //      {
  1213. //         default:
  1214. //          break;
  1215. //      }
  1216. //      break;
  1217. //  }
  1218.  
  1219.   return lpCmdLine;
  1220. }
  1221.  
  1222.  
  1223.  
  1224.  
  1225. /*************************************************************************
  1226.  
  1227.   Function:  ParseCommandLine (lpCmdLine)
  1228.  
  1229.    Purpose:  Parse the command line arguments for filenames, and then
  1230.              open the DIB'S
  1231.  
  1232.    Return:   void
  1233.  
  1234.   Comments:
  1235.  
  1236.    History:   Date     Reason
  1237.  
  1238.              8/08/91   Created
  1239.             11/13/91   Added a switch for the section name
  1240.                        (Used only for the CT stuff)
  1241.  
  1242. *************************************************************************/
  1243. void ParseCommandLine (LPSTR lpCmdLine)
  1244. {
  1245. int  i;
  1246. char szBuffer[256];
  1247. HANDLE hDIB;
  1248.  
  1249.   while (*lpCmdLine != '\0')
  1250.     {
  1251.     // remove leading spaces & check for section name
  1252.     lpCmdLine = GetSectionName(lpCmdLine);
  1253.  
  1254.     i=0;
  1255.     while ((*lpCmdLine != ' ') && (*lpCmdLine != '\0'))
  1256.        szBuffer[i++]=*lpCmdLine++;
  1257.     szBuffer[i] = '\0';
  1258.  
  1259.     if (CheckIfFileExists (szBuffer))
  1260.       {
  1261.       lstrcpy ((LPSTR)szFileName, (LPSTR) szBuffer);
  1262.  
  1263.       hDIB = GetDIB ();
  1264.       if (hDIB)
  1265.         OpenDIBWindow(hDIB, szFileName);
  1266.       }
  1267.     }
  1268.   return;
  1269.  
  1270. }
  1271.  
  1272. /*************************************************************************
  1273.  
  1274.   Function:  GetDIB (void)
  1275.  
  1276.    Purpose:  Opens dib file and reads into memory.
  1277.  
  1278.    Return:   HDIB if successful.
  1279.              NULL if an error occurs
  1280.  
  1281.   Comments:
  1282.  
  1283.    History:   Date     Reason
  1284.  
  1285.              8/8/91    Created
  1286.  
  1287. *************************************************************************/
  1288.  
  1289.  
  1290. HANDLE GetDIB (void)
  1291. {
  1292.  
  1293.    int      hFile;
  1294.    OFSTRUCT ofs;
  1295.    HANDLE   hDIB;
  1296.  
  1297.    SetCursor(LoadCursor(NULL, IDC_WAIT));
  1298.  
  1299.    if ((hFile = OpenFile (szFileName, &ofs, OF_READ)) != -1)
  1300.       {
  1301.       hDIB = ReadDIBFile (hFile);
  1302.       _lclose (hFile);
  1303.       SetCursor(LoadCursor(NULL, IDC_ARROW));
  1304.       return hDIB;
  1305.       }
  1306.    else
  1307.       DIBError (ERR_FILENOTFOUND);
  1308.       SetCursor(LoadCursor(NULL, IDC_ARROW));
  1309.       return NULL;
  1310. }
  1311.