home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / w / winsr173.zip / DIALOG.C < prev    next >
C/C++ Source or Header  |  1992-07-20  |  20KB  |  704 lines

  1. /*
  2.  
  3.     various dialog-box code - there's more in DIALOG2.C
  4.  
  5. */
  6.  
  7. #include "windows.h"
  8. #include "winfract.h"
  9. #include "mathtool.h"
  10. #include "fractint.h"
  11. #include <string.h>
  12. #include <math.h>
  13. #include <stdio.h>
  14. #include <sys\types.h>
  15. #include <sys\stat.h>
  16.  
  17. extern HWND hwnd;                               /* handle to main window */
  18. extern char szHelpFileName[];            /* Help file name*/
  19. extern HANDLE hThisInst;
  20.  
  21. extern LPBITMAPINFO pDibInfo;
  22. extern char huge *pixels;
  23. extern LPLOGPALETTE pLogPal;
  24.  
  25. char far DialogTitle[128];
  26.  
  27. char FullPathName[128];
  28. char FileName[128];
  29. char OpenName[128];
  30. char DefPath[128];
  31. char DefSpec[13];
  32. char DefExt[10];
  33. BOOL OperCancelled;
  34.  
  35. OFSTRUCT OfStruct;              /* information from OpenFile()     */
  36. struct stat FileStatus;           /* information from fstat()       */
  37.  
  38.  
  39. /****************************************************************************
  40.  
  41.     FUNCTION: SaveAsDlg(HWND, unsigned, WORD, LONG)
  42.  
  43.     PURPOSE: Allows user to change name to save file to
  44.  
  45.     COMMENTS:
  46.  
  47.     This will initialize the window class if it is the first time this
  48.     application is run.  It then creates the window, and processes the
  49.     message loop until a PostQuitMessage is received.  It exits the
  50.     application by returning the value passed by the PostQuitMessage.
  51.  
  52. ****************************************************************************/
  53.  
  54. BOOL bSaveEnabled = FALSE;
  55.  
  56. extern int time_to_save;
  57. extern int gif87a_flag;
  58. int FileFormat = 0;
  59. FARPROC lpStatusBox = NULL;
  60. HWND hStatusBox;
  61. char far StatusTitle[80];
  62.  
  63. BOOL FAR PASCAL StatusBoxProc(HWND hDlg, unsigned Msg, WORD wParam,
  64.                 LONG lParam)
  65. {
  66.    char PerStr[10];
  67.    RECT Rect, TextRect;
  68.    HWND hBar, hCancel;
  69.    HDC hBarDC;
  70.    unsigned Percent;
  71.  
  72.    switch(Msg)
  73.    {
  74.       case WM_INITDIALOG:
  75.          SetWindowText(hDlg, StatusTitle);
  76.          hCancel = GetDlgItem(hDlg, ID_CANCEL);
  77.          SetFocus(hCancel);
  78.          return(FALSE);
  79.  
  80.       case WM_CHAR:
  81.          if(wParam == VK_RETURN || wParam == VK_ESCAPE)
  82.             OperCancelled = TRUE;
  83.          break;
  84.  
  85.       case WM_COMMAND:
  86.  
  87.          if(wParam == ID_CANCEL)
  88.             OperCancelled = TRUE;
  89.          break;
  90.  
  91.       case WM_USER:
  92.          /* Invalidate Bar Window */
  93.          hBar = GetDlgItem(hDlg, ID_PERCENT);
  94.          GetClientRect(hBar, &TextRect);
  95.  
  96.          /* Calculate Percentage */
  97.          hBarDC = GetDC(hBar);
  98.          Percent = (unsigned)((lParam * 100) / wParam);
  99.          if(Percent <= 100)
  100.          {
  101.             wsprintf(PerStr, "%d", Percent);
  102.             strcat(PerStr, "%");
  103.  
  104.             /* Display Bar */
  105.             Rect = TextRect;
  106.             Rect.right = (unsigned)((((long)Percent) * Rect.right) / 100);
  107.             Rect.top += 2;
  108.             Rect.bottom -= 2;
  109.             Rectangle(hBarDC, Rect.left, Rect.top, Rect.right, Rect.bottom);
  110.  
  111.             /* Display Percentage */
  112.             DrawText(hBarDC, PerStr, lstrlen(PerStr), &TextRect,
  113.                      DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  114.          }
  115.  
  116.          ReleaseDC(hBar, hBarDC);
  117.          break;
  118.  
  119.       case WM_DESTROY:
  120.          break;
  121.  
  122.       default:
  123.          return(FALSE);
  124.    }
  125.    return(TRUE);
  126. }
  127.  
  128. void OpenStatusBox(HWND hWnd, HANDLE hInst)
  129. {
  130.    if(lpStatusBox == NULL)
  131.       lpStatusBox = MakeProcInstance(StatusBoxProc, hInst);
  132.    hStatusBox = CreateDialog(hInst, "StatusBox", hWnd, lpStatusBox);
  133. }
  134.  
  135. void CloseStatusBox(void)
  136. {
  137.    DestroyWindow(hStatusBox);
  138. }
  139.  
  140. void UpdateStatusBox(unsigned long Partial, unsigned long Total)
  141. {
  142.    if(Total > 0xffff)
  143.    {
  144.       Total >>= 16;
  145.       Partial >>= 16;
  146.    }
  147.    SendMessage(hStatusBox, WM_USER, (unsigned)Total, Partial);
  148. }
  149.  
  150. void AddFormatExt(void)
  151. {
  152.    unsigned n;
  153.    char *ExtStr;
  154.  
  155.    if(FileFormat == ID_BMP)
  156.       ExtStr = ".BMP";
  157.    else
  158.       ExtStr = ".GIF";
  159.    for(n = 0; FileName[n] && FileName[n] != '.'; n++);
  160.    lstrcpy(&FileName[n], ExtStr);
  161. }
  162.  
  163. void UpdateDefPath(HWND hDlg)
  164. {
  165.    unsigned char TempName[128];
  166.    int n;
  167.  
  168.    GetDlgItemText(hDlg, IDC_EDIT, TempName, sizeof(TempName));
  169.    for(n = lstrlen(TempName) - 1; n >= 0; n--)
  170.    {
  171.       if(TempName[n] == '\\')
  172.       {
  173.          HWND hEdit;
  174.  
  175.          lstrcpy(FileName, &TempName[n+1]);
  176.          hEdit = GetDlgItem(hDlg, IDC_EDIT);
  177.          SetWindowText(hEdit, FileName);
  178.          TempName[n] = 0;
  179.          DlgDirList(hDlg, TempName, NULL, IDC_PATH, 0x4010);
  180.          GetDlgItemText(hDlg, IDC_PATH, DefPath, sizeof(FullPathName));
  181.          break;
  182.       }
  183.    }
  184.    if(n < 0)
  185.       lstrcpy(FileName, TempName);
  186.    FileName[8] = 0;
  187.    AddFormatExt();
  188. }
  189.  
  190.  
  191. BOOL Check4Wildcards(hWnd, pSrc)
  192. HWND hWnd;
  193. PSTR pSrc;
  194. {
  195.     PSTR pTmp;
  196.  
  197.     if (!pSrc[0])
  198.     return (FALSE);           /* Indicates no filename was specified */
  199.  
  200.     pTmp = pSrc;
  201.     while (*pTmp) {            /* Searches the string for wildcards */
  202.     switch (*pTmp++) {
  203.         case '*':
  204.         case '?':
  205.         MessageBox(hWnd, "Wildcards not allowed.",
  206.             NULL, MB_OK | MB_ICONEXCLAMATION);
  207.         return (FALSE);
  208.     }
  209.     }
  210.     return(TRUE);
  211. }
  212.  
  213. int FAR PASCAL SaveAsDlg(hDlg, message, wParam, lParam)
  214. HWND hDlg;
  215. unsigned message;
  216. WORD wParam;
  217. LONG lParam;
  218. {
  219.     unsigned char TempName[128];
  220.  
  221.     switch (message) {
  222.  
  223.     case WM_INITDIALOG:
  224.  
  225.         SetDlgItemText(hDlg, ID_FILETITLE, DialogTitle);
  226.             AddFormatExt();
  227.             while(OpenFile(FileName, (LPOFSTRUCT) &OfStruct, OF_EXIST) >= 0)
  228.                updatesavename(FileName);
  229.  
  230.         EnableWindow(GetDlgItem(hDlg, IDOK), bSaveEnabled);
  231.  
  232.             if(FileFormat == 0)
  233.                FileFormat = (gif87a_flag) ? ID_GIF87A : ID_GIF89A;
  234.             CheckDlgButton(hDlg, FileFormat, 1);
  235.             SetDlgItemText(hDlg, IDC_EDIT, FileName);
  236.         SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  237.             UpdateDefPath(hDlg);
  238.             if(DefPath[0] == 0)
  239.             {
  240.                DlgDirList(hDlg, "*.*", NULL, IDC_PATH, 0x4010);
  241.                GetDlgItemText(hDlg, IDC_PATH, DefPath, sizeof(FullPathName));
  242.             }
  243.         SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, 0,
  244.             MAKELONG(0, 0x7fff));
  245.  
  246.         return (FALSE);            /* FALSE since Focus was changed */
  247.  
  248.     case WM_COMMAND:
  249.         switch (wParam) {
  250.  
  251.             /* MCP 10-27-91, Update file format */
  252.                 case ID_GIF87A:
  253.                 case ID_GIF89A:
  254.                 case ID_BMP:
  255.                    CheckDlgButton(hDlg, FileFormat, 0);
  256.                    FileFormat = wParam;
  257.                    CheckDlgButton(hDlg, FileFormat, 1);
  258.                    gif87a_flag = (wParam == ID_GIF87A);
  259.                    GetDlgItemText(hDlg, IDC_EDIT, FileName, 128);
  260.                    AddFormatExt();
  261.                    SetDlgItemText(hDlg, IDC_EDIT, FileName);
  262.                    return(TRUE);
  263.  
  264.         case IDC_EDIT:
  265.  
  266.             /* If there was previously no filename in the edit
  267.              * control, then the save control must be enabled as soon as
  268.              * a character is entered.
  269.              */
  270.  
  271.             if (HIWORD(lParam) == EN_CHANGE && !bSaveEnabled)
  272.                  EnableWindow(GetDlgItem(hDlg, IDOK), bSaveEnabled = TRUE);
  273.                     else if(HIWORD(lParam) == EN_KILLFOCUS)
  274.                        UpdateDefPath(hDlg);
  275.  
  276.                     return (TRUE);
  277.  
  278.         case IDOK:
  279.  
  280.            /* Get the filename from the edit control */
  281.  
  282.             GetDlgItemText(hDlg, IDC_EDIT, TempName, 128);
  283.  
  284.             /* If there are no wildcards, then separate the name into
  285.              * path and name.  If a path was specified, replace the
  286.              * default path with the new path.
  287.              */
  288.  
  289.                     UpdateDefPath(hDlg);
  290.                     lstrcpy(FullPathName, DefPath);
  291.                     if (FullPathName[0] != 0) {
  292.                         char i;
  293.                         i = FullPathName[lstrlen(FullPathName)-1];
  294.                         if (i != '\\' && i != '/' && i != ':')
  295.                             lstrcat(FullPathName,"\\");
  296.                             }
  297.                     lstrcat(FullPathName, FileName);
  298.                 SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  299.                     SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, 0,
  300.                MAKELONG(0, 0x7fff));
  301.             if (Check4Wildcards(hDlg, FullPathName)) {
  302.                         if (OpenFile(FullPathName, (LPOFSTRUCT) &OfStruct,
  303.                            OF_EXIST) >= 0)
  304.                         {
  305.                             char str[255];
  306.                             
  307.                         sprintf(str, "Replace existing %s?", FullPathName);
  308.                         if (MessageBox(hDlg, str, "Save . . .",
  309.                        MB_YESNO | MB_ICONQUESTION) == IDNO)
  310.                                return(TRUE);
  311.                         }
  312.  
  313.                          /* Tell the caller a filename was selected */
  314.                EndDialog(hDlg, IDOK);
  315.                time_to_save = 1;
  316.                        OperCancelled = FALSE;
  317.                     }
  318.             return(TRUE);
  319.  
  320.         case IDCANCEL:
  321.  
  322.             /* Tell the caller the user canceled the SaveAs function */
  323.  
  324.             EndDialog(hDlg, IDCANCEL);
  325.             time_to_save = 0;
  326.             return (TRUE);
  327.         }
  328.         break;
  329.  
  330.     }
  331.     return (FALSE);
  332. }
  333.  
  334. /****************************************************************************
  335.  
  336.     FUNCTION: OpenDlg(HWND, unsigned, WORD, LONG)
  337.  
  338.     PURPOSE: Let user select a file, and return.  Open code not provided.
  339.  
  340. ****************************************************************************/
  341.  
  342. HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
  343. HWND hDlg;
  344. unsigned message;
  345. WORD wParam;
  346. LONG lParam;
  347. {
  348.     HANDLE hFile=1;    /* Temp value for return */
  349.     char str[255];
  350.  
  351.     switch (message) {
  352.  
  353.     case WM_COMMAND:
  354.         switch (wParam) {
  355.  
  356.         case IDC_LISTBOX:
  357.             switch (HIWORD(lParam)) {
  358.                 char str[255];
  359.  
  360.             case LBN_SELCHANGE:
  361.                 /* If item is a directory name, append "*.*" */
  362.                 if (DlgDirSelect(hDlg, str, IDC_LISTBOX))
  363.                 lstrcat(str, DefSpec);
  364.  
  365.                 SetDlgItemText(hDlg, IDC_EDIT, str);
  366.                 SendDlgItemMessage(hDlg,
  367.                 IDC_EDIT,
  368.                 EM_SETSEL,
  369.                 NULL,
  370.                 MAKELONG(0, 0x7fff));
  371.                 break;
  372.  
  373.             case LBN_DBLCLK:
  374.                 goto openfile;
  375.             }
  376.             return (TRUE);
  377.  
  378.         case IDOK:
  379. openfile:
  380.             GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
  381.             if (strchr(OpenName, '*') || strchr(OpenName, '?')) {
  382.             SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
  383.                 (LPSTR) OpenName);
  384.             if (str[0])
  385.                 lstrcpy(DefPath, str);
  386.             ChangeDefExt(DefExt, DefSpec);
  387.             UpdateListBox(hDlg);
  388.             return (TRUE);
  389.             }
  390.  
  391.             if (!OpenName[0]) {
  392.             MessageBox(hDlg, "No filename specified.",
  393.                 NULL, MB_OK | MB_ICONHAND);
  394.             return (TRUE);
  395.             }
  396.  
  397.             AddExt(OpenName, DefExt);
  398.             lstrcpy(FileName, OpenName);
  399.  
  400.             /* The routine to open the file would go here, and the */
  401.             /* file handle would be returned instead of NULL.        */
  402.             EndDialog(hDlg, hFile);
  403.             return (TRUE);
  404.  
  405.         case IDCANCEL:
  406.             EndDialog(hDlg, NULL);
  407.             return (FALSE);
  408.         }
  409.         break;
  410.  
  411.     case WM_INITDIALOG:               /* message: initialize    */
  412.         UpdateListBox(hDlg);
  413.         SetDlgItemText(hDlg, ID_FILETITLE, DialogTitle);
  414.         SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
  415.         SendDlgItemMessage(hDlg,           /* dialog handle     */
  416.         IDC_EDIT,               /* where to send message  */
  417.         EM_SETSEL,               /* select characters      */
  418.         NULL,                   /* additional information */
  419.         MAKELONG(0, 0x7fff));           /* entire contents       */
  420.         SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  421.         return (FALSE); /* Indicates the focus is set to a control */
  422.     }
  423.     return FALSE;
  424. }
  425.  
  426. /****************************************************************************
  427.  
  428.     FUNCTION: UpdateListBox(HWND);
  429.  
  430.     PURPOSE: Update the list box of OpenDlg
  431.  
  432. ****************************************************************************/
  433.  
  434. void UpdateListBox(hDlg)
  435. HWND hDlg;
  436. {
  437.     char str[255];
  438.     
  439.     lstrcpy(str, DefPath);
  440.     if (DefPath[0] != 0) {
  441.         char i;
  442.         i = DefPath[lstrlen(DefPath)-1];
  443.         if (i != '\\' && i != '/' && i != ':')
  444.            strcat(str,"\\");
  445.         }
  446.     lstrcat(str, DefSpec);
  447.     DlgDirList(hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010);
  448.  
  449.     /* To ensure that the listing is made for a subdir. of
  450.      * current drive dir...
  451.      */
  452.     if (!strchr (DefPath, ':'))
  453.     DlgDirList(hDlg, DefSpec, IDC_LISTBOX, IDC_PATH, 0x4010);
  454.  
  455.     /* Remove the '..' character from path if it exists, since this
  456.      * will make DlgDirList move us up an additional level in the tree
  457.      * when UpdateListBox() is called again.
  458.      */
  459.     if (strstr (DefPath, ".."))
  460.     DefPath[0] = '\0';
  461.  
  462.     SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
  463. }
  464.  
  465. /****************************************************************************
  466.  
  467.     FUNCTION: ChangeDefExt(PSTR, PSTR);
  468.  
  469.     PURPOSE: Change the default extension
  470.  
  471. ****************************************************************************/
  472.  
  473. void ChangeDefExt(Ext, Name)
  474. PSTR Ext, Name;
  475. {
  476.     PSTR pTptr;
  477.  
  478.     pTptr = Name;
  479.     while (*pTptr && *pTptr != '.')
  480.     pTptr++;
  481.     if (*pTptr)
  482.     if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
  483.         strcpy(Ext, pTptr);
  484. }
  485.  
  486. /****************************************************************************
  487.  
  488.     FUNCTION: SeparateFile(HWND, LPSTR, LPSTR, LPSTR)
  489.  
  490.     PURPOSE: Separate filename and pathname
  491.  
  492. ****************************************************************************/
  493.  
  494. void SeparateFile(hDlg, lpDestPath, lpDestFileName, lpSrcFileName)
  495. HWND hDlg;
  496. LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
  497. {
  498.     LPSTR lpTmp;
  499.     char  cTmp;
  500.  
  501.     lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
  502.     while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
  503.     lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
  504.     if (*lpTmp != ':' && *lpTmp != '\\') {
  505.     lstrcpy(lpDestFileName, lpSrcFileName);
  506.     lpDestPath[0] = 0;
  507.     return;
  508.     }
  509.     lstrcpy(lpDestFileName, lpTmp + 1);
  510.     cTmp = *(lpTmp + 1);
  511.     lstrcpy(lpDestPath, lpSrcFileName);
  512.      *(lpTmp + 1) = cTmp;
  513.     lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
  514. }
  515.  
  516. /****************************************************************************
  517.  
  518.     FUNCTION: AddExt(PSTR, PSTR);
  519.  
  520.     PURPOSE: Add default extension
  521.  
  522. ***************************************************************************/
  523.  
  524. void AddExt(Name, Ext)
  525. PSTR Name, Ext;
  526. {
  527.     PSTR pTptr;
  528.  
  529.     pTptr = Name;
  530.     while (*pTptr && *pTptr != '.')
  531.     pTptr++;
  532.     if (*pTptr != '.')
  533.     strcat(Name, Ext);
  534. }
  535.  
  536. /****************************************************************************
  537.  
  538.     FUNCTION: CheckFileName(HWND, PSTR, PSTR)
  539.  
  540.     PURPOSE: Check for wildcards, add extension if needed
  541.  
  542.     COMMENTS:
  543.  
  544.     Make sure you have a filename and that it does not contain any
  545.     wildcards.  If needed, add the default extension.  This function is
  546.     called whenever your application wants to save a file.
  547.  
  548. ****************************************************************************/
  549.  
  550. BOOL CheckFileName(hWnd, pDest, pSrc)
  551. HWND hWnd;
  552. PSTR pDest, pSrc;
  553. {
  554.     PSTR pTmp;
  555.     char str[255];
  556.  
  557.     if (!pSrc[0])
  558.     return (FALSE);           /* Indicates no filename was specified */
  559.  
  560.     pTmp = pSrc;
  561.     while (*pTmp) {            /* Searches the string for wildcards */
  562.     switch (*pTmp++) {
  563.         case '*':
  564.         case '?':
  565.         MessageBox(hWnd, "Wildcards not allowed.",
  566.             NULL, MB_OK | MB_ICONEXCLAMATION);
  567.         return (FALSE);
  568.     }
  569.     }
  570.  
  571.     AddExt(pSrc, DefExt);         /* Adds the default extension if needed */
  572.  
  573.     if (OpenFile(pSrc, (LPOFSTRUCT) &OfStruct, OF_EXIST) >= 0) {
  574.     sprintf(str, "Replace existing %s?", pSrc);
  575.     if (MessageBox(hWnd, str, "SaveFile",
  576.         MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
  577.         return (FALSE);
  578.     }
  579.     strcpy(pDest, pSrc);
  580.     return (TRUE);
  581. }
  582.  
  583. /****************************************************************************
  584.  
  585.     FUNCTION: center_window(HWND, int, int)
  586.  
  587.     PURPOSE:  Center the specified window within client area of parent.
  588.           Works only with popups which all the ones we want seem to be.
  589.           This function should be called before first paint of window.
  590.  
  591. ****************************************************************************/
  592.  
  593. void center_window(HWND hchild, int xadj, int yadj)
  594. {
  595.     RECT crect,prect;
  596.     int i,cwidth,cheight;
  597.     POINT center;
  598.     GetWindowRect(hchild, &crect);
  599.     GetClientRect(hwnd, &prect);   /* main Fractint window */
  600.     cwidth  = crect.right - crect.left;
  601.     cheight = crect.bottom - crect.top;
  602.     center.x = (prect.right + prect.left) / 2;
  603.     center.y = (prect.bottom + prect.top) / 2;
  604.     ClientToScreen(hwnd, ¢er);
  605.     if ((center.x += xadj - (cwidth  / 2)) < 0) center.x = 0;
  606.     if ((center.y += yadj - (cheight / 2)) < 0) center.y = 0;
  607.     if ((i = GetSystemMetrics(SM_CXSCREEN) - cwidth ) < center.x) center.x = i;
  608.     if ((i = GetSystemMetrics(SM_CYSCREEN) - cheight) < center.y) center.y = i;
  609.     MoveWindow(hchild, center.x, center.y, cwidth, cheight, FALSE);
  610. }
  611.  
  612. void SaveBitmapFile(HWND hWnd, char *FullPathName)
  613. {
  614.    long TotalSize, Saved = 0, ImageSize, n;
  615.    BITMAPFILEHEADER FileHeader;
  616.    unsigned PalSize, BitCount;
  617.    unsigned BlockSize = 10240;
  618.    int hFile;
  619.    char Temp[128];
  620.    OFSTRUCT OfStruct;
  621.    HANDLE hPal;
  622.    RGBQUAD FAR *Pal;
  623.  
  624.    hFile = OpenFile(FullPathName, &OfStruct, OF_CREATE);
  625.    if(hFile == NULL)
  626.    {
  627. FileError:
  628.       wsprintf(Temp, "File I/O error while saving %s.", (LPSTR)FullPathName);
  629.       MessageBox(hWnd, Temp, "File Error . . .", MB_OK | MB_ICONEXCLAMATION);
  630.  
  631. GeneralError:
  632.       _lclose(hFile);
  633.       OpenFile(FullPathName, &OfStruct, OF_DELETE);
  634.       CloseStatusBox();
  635.       return;
  636.    }
  637.  
  638.    BitCount = pDibInfo->bmiHeader.biBitCount;
  639.    if(BitCount != 24)
  640.       PalSize = (1 << BitCount) * sizeof(RGBQUAD);
  641.    else
  642.       PalSize = 0;
  643.  
  644.    ImageSize = pDibInfo->bmiHeader.biSizeImage;
  645.    FileHeader.bfType = 0x4d42; /* 'BM'; */
  646.    FileHeader.bfSize = sizeof(FileHeader) +
  647.                        pDibInfo->bmiHeader.biSize +
  648.                        PalSize + ImageSize;
  649.    TotalSize = FileHeader.bfSize;
  650.    FileHeader.bfReserved1 = FileHeader.bfReserved2 = 0;
  651.    FileHeader.bfOffBits = FileHeader.bfSize - ImageSize;
  652.    Saved += _lwrite(hFile, (LPSTR)&FileHeader, sizeof(FileHeader));
  653.    Saved += _lwrite(hFile, (LPSTR)pDibInfo, (int)pDibInfo->bmiHeader.biSize);
  654.    if(PalSize)
  655.    {
  656.       hPal = GlobalAlloc(GMEM_FIXED, PalSize);
  657.       Pal = (RGBQUAD FAR *)GlobalLock(hPal);
  658.       if(Pal == NULL)
  659.       {
  660.          MessageBox(hWnd, "Insufficient Memory", "Memory Error . . .",
  661.                           MB_ICONEXCLAMATION | MB_OK);
  662.          goto GeneralError;
  663.       }
  664.       for(n = 0; n < (1 << BitCount); n++)
  665.       {
  666.          Pal[n].rgbRed   = pLogPal->palPalEntry[n].peRed;
  667.          Pal[n].rgbGreen = pLogPal->palPalEntry[n].peGreen;
  668.          Pal[n].rgbBlue  = pLogPal->palPalEntry[n].peBlue;
  669.          Pal[n].rgbReserved = 0;
  670.       }
  671.       Saved += _lwrite(hFile, (LPSTR)Pal, PalSize);
  672.       GlobalUnlock(hPal);
  673.       GlobalFree(hPal);
  674.    }
  675.    UpdateStatusBox(Saved, TotalSize);
  676.    keypressed();
  677.  
  678.    /* We should have saved enough bytes to reach the image offset.  If not,
  679.       then there was an error. */
  680.    if(Saved != FileHeader.bfOffBits)
  681.       goto FileError;
  682.  
  683.    for(n = 0; n < (ImageSize - BlockSize); n += BlockSize)
  684.    {
  685.       if(_lwrite(hFile, (LPSTR)&pixels[n], BlockSize) != BlockSize)
  686.          goto FileError;
  687.       Saved += BlockSize;
  688.       UpdateStatusBox(Saved, TotalSize);
  689.       keypressed();
  690.       if(OperCancelled)
  691.       {
  692.          MessageBox(hWnd, "File save cancelled.", "Save Cancelled", MB_OK);
  693.          goto GeneralError;
  694.       }
  695.    }
  696.    Saved += _lwrite(hFile, (LPSTR)&pixels[n], (int)(ImageSize - n));
  697.    if(Saved != TotalSize)
  698.       goto FileError;
  699.  
  700.    UpdateStatusBox(Saved, TotalSize);
  701.    _lclose(hFile);
  702.    CloseStatusBox();
  703. }
  704.