home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / graphic / fractint / sources / pmfruser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-25  |  38.8 KB  |  1,162 lines

  1. /*--------------------------------------------------
  2.    PMFRUSER.C -- FRACTINT for PM
  3.  
  4.    User Action (Menus mostly) handling
  5.  
  6.    04/16/91      Code by Donald P. Egen (with help)
  7.  
  8.    The main function (PMfrCommands) acts on the
  9.    events generated by the user on the menus.
  10.    Actions necessary to carry out user requests
  11.    from the menus and/or with mouse and keyboard
  12.    on the main window are performed by the
  13.    subroutines in this module.
  14.  
  15.    Decoding of mouse/keyboard events into these
  16.    action sets is done by the main window procedure
  17.    (ClientWndProc in PMFRACT.C).
  18.  
  19.    All this code is a separate module from the main
  20.    window procedure, so that it can be a separate
  21.    segment, and therefore only be in memory when
  22.    the user is futzing with the program's controls.
  23.  
  24.  ---------------------------------------------------*/
  25.  
  26. #define INCL_WIN
  27. #define INCL_GPI
  28. #define INCL_DOS
  29. #include <os2.h>
  30. #include <process.h>
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <smplhelp.h>
  35.  
  36. #include <opendlg.h>
  37.  
  38. #include "pmfract.h"
  39. #include "fractint.h"
  40. #include "fractype.h"
  41.  
  42. MRESULT PMfrCommands (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  43.      {
  44.      /*
  45.         These are the routnes that handle the commands issued by
  46.         the FRACTINT for PM menus.
  47.  
  48.         In most cases, they call another support routine to
  49.         handle or schedule the event requested by the user.
  50.      */
  51.  
  52.      SHORT sCommand = SHORT1FROMMP(mp1);
  53.  
  54.  
  55.      switch (sCommand)
  56.           {
  57.           case IDM_GO:
  58.                /* fire up the subtask */
  59.                cp.fContinueCalc = TRUE ;
  60.                if (npNewParms.fNewParms)
  61.                   {
  62.                   CopyParmsToBase();
  63.                   /* GetMemoryBitmap(); */
  64.                   SetSwitchEntry (hwnd, szTitleBar,
  65.                                   GetFractalName(cp.iFractType) );
  66.                   }
  67.  
  68.                cp.sSubAction = SUB_ACT_CALC;   /* we want a Calculation */
  69.  
  70.                DosSemClear (&cp.ulSemTrigger) ;  /* release the subthread */
  71.  
  72.                sStatus = STATUS_WORKING ;
  73.                /* WinInvalidateRect (hwnd, NULL, FALSE) ; */
  74.                UpdateMenuText (hwnd, IDM_FREEZE_HALT, szHalt);
  75.                EnableMenuItem (hwnd, IDM_GO, FALSE) ;
  76.                EnableMenuItem (hwnd, IDM_FREEZE_HALT, TRUE) ;
  77.                /* WinStartTimer (hab, hwnd, ID_TIMER, 5000); */
  78.                return 0 ;
  79.  
  80.           case IDM_PAN:
  81.                /* Pan selected.  Pan to where the cross hairs were */
  82.                PanNewCenter(hwnd);
  83.                fGoodPan = FALSE;
  84.                return 0;
  85.  
  86.           case IDM_ZIN_WIN:
  87.                /* Zoom to the Window selected. */
  88.                EraseZoomBox(hwnd);
  89.                ZoomNewWindow(hwnd, TRUE);   /* zoom in */
  90.                fGoodZoom = FALSE;
  91.                return 0;
  92.  
  93.           case IDM_ZOUT_WIN:
  94.                /* Zoom to the Window selected. */
  95.                EraseZoomBox(hwnd);
  96.                ZoomNewWindow(hwnd, FALSE);   /* zoom out */
  97.                fGoodZoom = FALSE;
  98.                return 0;
  99.  
  100.           case IDM_FREEZE_HALT:
  101.                if (sStatus == STATUS_WORKING)
  102.                   {
  103.                   /* schedule the subthread to find a stopping place */
  104.                   cp.fContinueCalc = FALSE ;
  105.                   EnableMenuItem (hwnd, IDM_FREEZE_HALT, FALSE) ;
  106.                   }
  107.                if (sStatus == STATUS_READY)
  108.                   {
  109.                   /* we Freeze to play with parms repeatedly */
  110.                   /* make a copy to play with.  We will keep */
  111.                   /* working with only this copy */
  112.                   InitNewParms(NULL);
  113.                   /* now change state */
  114.                   sStatus = STATUS_FROZEN;
  115.                   EnableMenuItem (hwnd, IDM_FREEZE_HALT, FALSE);
  116.                   }
  117.  
  118.                return 0 ;
  119.  
  120.           case IDM_ABOUT:
  121.                /* send up the About box */
  122.                WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc,
  123.                     (HMODULE) 0, IDD_ABOUT, NULL) ;
  124.  
  125.                return 0 ;
  126.  
  127.           case IDM_NEW_FRACTAL:
  128.                /*
  129.                 * send up the Select Fractal Type box.
  130.                 * On OK return, schedule the new parameters.
  131.                 * Handle the special cases needing files or other data
  132.                 * as part of exiting the initial dialog box.
  133.                */
  134.                if (WinDlgBox (HWND_DESKTOP, hwnd, SelFractalDlgProc,
  135.                        (HMODULE) 0, IDD_SET_FRACTTYPE, NULL) )
  136.                   ScheduleNewParms (hwnd);
  137.  
  138.                return 0 ;
  139.  
  140.           case IDM_SET_PARAMS:
  141.                /*
  142.                 * send up the Set Paramters box.
  143.                 * On OK return, schedule the new parameters.
  144.                */
  145.                if (WinDlgBox (HWND_DESKTOP, hwnd, SetParametersDlgProc,
  146.                        (HMODULE) 0, IDD_SET_PARAMS, NULL) )
  147.                ScheduleNewParms (hwnd);
  148.  
  149.                return 0 ;
  150.  
  151.           case IDM_SET_OPTIONS:
  152.                /*
  153.                 * send up the Set Options box.
  154.                 * On OK return, schedule the new parameters.
  155.                */
  156.                if (WinDlgBox (HWND_DESKTOP, hwnd, SetOptionsDlgProc,
  157.                        (HMODULE) 0, IDD_SET_OPTIONS, NULL) )
  158.                ScheduleNewParms (hwnd);
  159.  
  160.                return 0 ;
  161.  
  162.           case IDM_SET_IMAGE:
  163.                /*
  164.                 * send up the Set Image box.
  165.                 * On OK return, schedule the new parameters.
  166.                */
  167.                if (WinDlgBox (HWND_DESKTOP, hwnd, SetImageDlgProc,
  168.                        (HMODULE) 0, IDD_SET_IMAGE, NULL) )
  169.                ScheduleNewParms (hwnd);
  170.  
  171.                return 0 ;
  172.  
  173.           case IDM_SET_PALETTE:
  174.                /*
  175.                 * send up the Set Palette box.
  176.                 * Return is not checked because effects are immediate
  177.                */
  178.                WinDlgBox (HWND_DESKTOP, hwnd, SetPaletteDlgProc,
  179.                        (HMODULE) 0, IDD_SET_PALETTE, NULL) ;
  180.  
  181.                return 0 ;
  182.  
  183.           case IDM_ZIN_PICK:
  184.           case IDM_ZOUT_PICK:
  185.                /*
  186.                 * Send up the Zoom Value dialog box.
  187.                 * On OK return, schedule the new parameters.
  188.                */
  189.                if ( WinDlgBox (HWND_DESKTOP, hwnd, ZoomValueDlgProc,
  190.                         (HMODULE) 0, IDD_NUMBER_PICK,
  191.                         MPFROMP((PVOID) &COMMANDMSG(&msg)->cmd)) )
  192.                   ScheduleNewParms (hwnd);
  193.  
  194.                return 0 ;
  195.  
  196.           case IDM_ZIN_2:
  197.           case IDM_ZIN_5:
  198.           case IDM_ZIN_10:
  199.                /*
  200.                 * Zoom in by fixed value.
  201.                 * Schedule the new parameters.
  202.                */
  203.                InitNewParms(NULL);
  204.                CalcZoomValues(&npNewParms,
  205.                       (double) (sCommand), TRUE );
  206.                npNewParms.fNewParms = TRUE;
  207.                ScheduleNewParms(hwnd);
  208.  
  209.                return 0;
  210.  
  211.           case IDM_ZOUT_2:
  212.           case IDM_ZOUT_5:
  213.           case IDM_ZOUT_10:
  214.                /*
  215.                 * Zoom out by fixed value.
  216.                 * Schedule the new parameters.
  217.                */
  218.                InitNewParms(NULL);
  219.                CalcZoomValues(&npNewParms,
  220.                       (double) (sCommand - 10), FALSE );
  221.                npNewParms.fNewParms = TRUE;
  222.                ScheduleNewParms(hwnd);
  223.  
  224.                return 0;
  225.  
  226.           case IDM_SET_EXTENTS:
  227.                /*
  228.                 * Send up the Set Extents dialog box.
  229.                 * On OK return, schedule the new parameters.
  230.                */
  231.                if ( WinDlgBox (HWND_DESKTOP, hwnd, SetExtentsDlgProc,
  232.                       (HMODULE) 0, IDD_SET_EXTENTS, NULL) )
  233.                    ScheduleNewParms (hwnd);
  234.  
  235.                return 0;
  236.  
  237.           case IDM_SET_SWAP:
  238.                /* swap Mandel for Julia or vice versa.
  239.                   Handle it as a parm change */
  240.                InitNewParms(NULL);
  241.                if (fractalspecific[npNewParms.iFractType].tojulia != NOFRACTAL
  242.                       && npNewParms.param[0] == 0.0
  243.                       && npNewParms.param[1] == 0.0)
  244.                   {
  245.                   /* switch to corresponding Julia set */
  246.                   npNewParms.iFractType =
  247.                          fractalspecific[npNewParms.iFractType].tojulia;
  248.                   npNewParms.param[0] = npNewParms.XCenter;
  249.                   npNewParms.param[1] = npNewParms.YCenter;
  250.  
  251.                   npNewParms.mxXL = fractalspecific[npNewParms.iFractType].xmin;
  252.                   npNewParms.mxXR = fractalspecific[npNewParms.iFractType].xmax;
  253.                   npNewParms.mxYB = fractalspecific[npNewParms.iFractType].ymin;
  254.                   npNewParms.mxYT = fractalspecific[npNewParms.iFractType].ymax;
  255.  
  256.                   }
  257.  
  258.                else if (fractalspecific[npNewParms.iFractType].tomandel != NOFRACTAL)
  259.                   {
  260.                   /* switch to corresponding Mandel set */
  261.                   npNewParms.iFractType =
  262.                          fractalspecific[npNewParms.iFractType].tomandel;
  263.                   npNewParms.param[0] = 0.0;
  264.                   npNewParms.param[1] = 0.0;
  265.                   npNewParms.mxXL = fractalspecific[npNewParms.iFractType].xmin;
  266.                   npNewParms.mxXR = fractalspecific[npNewParms.iFractType].xmax;
  267.                   npNewParms.mxYB = fractalspecific[npNewParms.iFractType].ymin;
  268.                   npNewParms.mxYT = fractalspecific[npNewParms.iFractType].ymax;
  269.                   }
  270.  
  271.                npNewParms.fNewParms = TRUE;
  272.                ScheduleNewParms (hwnd);
  273.                return 0;
  274.  
  275.           case IDM_SET_RESET:
  276.                /* copy the work copy of the parms back from the
  277.                   set used by the calculation engine.
  278.                   This resets any dicking around done with the
  279.                   dialogs.
  280.                   Note: this is only active during FREEZE mode.
  281.                */
  282.  
  283.                CopyParmsToNew();
  284.  
  285.                return 0;
  286.  
  287.           case IDM_HELP_INTRO:
  288.                /* basic Introductory Help */
  289.                SimpleHelp(hab, hwnd, szTitleBar,
  290.                          (HMODULE) 0, IDT_TEXT, IDT_HELP_INTRO);
  291.                return 0;
  292.  
  293.           case IDM_HELP_FRACTTYPE:
  294.                /* Fractal list Help */
  295.                SimpleHelp(hab, hwnd, szTitleBar,
  296.                          (HMODULE) 0, IDT_TEXT, IDT_HELP_TYPES);
  297.                return 0;
  298.  
  299.           case IDM_HELP_OPERATE:
  300.                /* Menu Help */
  301.                SimpleHelp(hab, hwnd, szTitleBar,
  302.                        (HMODULE) 0, IDT_TEXT, IDT_HELP_OPERATE);
  303.                return 0;
  304.  
  305.           case IDM_PRINT_FILE:
  306.                /* Send up the Print Where Dialog.
  307.                   On OK return, fire up the subtask */
  308.                if ( WinDlgBox(HWND_DESKTOP, hwnd, PrintOptionsDlgProc,
  309.                     (HMODULE) 0, IDD_PRINT, NULL) )
  310.                   {
  311.                   /* fire up the subtask */
  312.                   cp.sSubAction = SUB_ACT_PRINT;   /* we want a Print */
  313.  
  314.                   cp.fContinueCalc = TRUE;
  315.                   DosSemClear (&cp.ulSemTrigger) ;  /* release the subthread */
  316.  
  317.                   sStatus = STATUS_WORKING ;
  318.                   UpdateMenuText (hwnd, IDM_FREEZE_HALT, szHalt);
  319.                   EnableMenuItem (hwnd, IDM_GO, FALSE) ;
  320.                   EnableMenuItem (hwnd, IDM_FREEZE_HALT, TRUE) ;
  321.                   cp.fSuppressPaint = TRUE;
  322.                   WinInvalidateRect(hwnd, NULL, FALSE);
  323.                   }
  324.  
  325.                return 0 ;
  326.  
  327.           case IDM_READ_FILE:
  328.                /* Send up the Load/Save Format Dialog to find
  329.                   out the format we will read.
  330.                   Then send up the generic Open File dialog.
  331.                   On OK return, fire up the subtask */
  332.                {
  333.                DLF dlf;
  334.                HFILE hfDummy;
  335.                PSZ pszExt;
  336.  
  337.                if ( WinDlgBox(HWND_DESKTOP, hwnd, LoadSaveFmtDlgProc,
  338.                     (HMODULE) 0, IDD_LOADSAVE_TYPE, szLoadWhatFmt) )
  339.                   {
  340.  
  341.                   FileFmtExt (&pszExt);
  342.  
  343.                   SetupDLF (&dlf, DLG_OPENDLG, &hfDummy,
  344.                             pszExt, szTitleBar,
  345.                             szOpenTitle, szOpenHelp);
  346.  
  347.                   if (TDF_OLDOPEN == DlgFile(hwnd, &dlf) )
  348.                      {
  349.                      /* close the dummy file handle */
  350.                      DosClose(hfDummy);
  351.                      /* fire up the subtask */
  352.                      cp.sSubAction = SUB_ACT_LOAD;   /* we want a Load */
  353.                      cp.sSubFunction = cp.sLastLoadSaveType;
  354.                      _fstrcpy(cp.szFileName, dlf.szOpenFile);
  355.  
  356.                      cp.fContinueCalc = TRUE;
  357.                      DosSemClear (&cp.ulSemTrigger) ;  /* release the subthread */
  358.  
  359.                      sStatus = STATUS_WORKING ;
  360.                      UpdateMenuText (hwnd, IDM_FREEZE_HALT, szHalt);
  361.                      EnableMenuItem (hwnd, IDM_GO, FALSE) ;
  362.                      EnableMenuItem (hwnd, IDM_FREEZE_HALT, TRUE) ;
  363.                      cp.fSuppressPaint = TRUE;
  364.                      WinInvalidateRect(hwnd, NULL, FALSE);
  365.                      }
  366.                   }
  367.  
  368.                return 0 ;
  369.                }
  370.  
  371.           case IDM_SAVE_FILE:
  372.                /* Send up the Load/Save Format Dialog to find
  373.                   out the format we will be writing.
  374.                   Then send up the generic Save File dialog.
  375.                   On OK return, fire up the subtask */
  376.                {
  377.                DLF dlf;
  378.                HFILE hfDummy;
  379.                PSZ pszExt;
  380.  
  381.                if ( WinDlgBox(HWND_DESKTOP, hwnd, LoadSaveFmtDlgProc,
  382.                     (HMODULE) 0, IDD_LOADSAVE_TYPE, szSaveWhatFmt) )
  383.                   {
  384.  
  385.                   FileFmtExt (&pszExt);
  386.  
  387.                   SetupDLF (&dlf, DLG_SAVEDLG, &hfDummy,
  388.                             pszExt, szTitleBar,
  389.                             szOpenTitle, szOpenHelp);
  390.                   _fstrcpy(dlf.szOpenFile, cp.szFileName);
  391.  
  392.                   if (TDF_NOSAVE != DlgFile(hwnd, &dlf) )
  393.                      {
  394.                      /* close the dummy file handle */
  395.                      DosClose(hfDummy);
  396.                      /* and delete the dummy file */
  397.                      DosDelete(dlf.szOpenFile, 0);
  398.                      /* fire up the subtask */
  399.                      cp.sSubAction = SUB_ACT_SAVE;   /* we want a Save */
  400.                      cp.sSubFunction = cp.sLastLoadSaveType;
  401.                      _fstrcpy(cp.szFileName, dlf.szOpenFile);
  402.  
  403.                      cp.fContinueCalc = TRUE;
  404.                      DosSemClear (&cp.ulSemTrigger) ;  /* release the subthread */
  405.  
  406.                      sStatus = STATUS_WORKING ;
  407.                      UpdateMenuText (hwnd, IDM_FREEZE_HALT, szHalt);
  408.                      EnableMenuItem (hwnd, IDM_GO, FALSE) ;
  409.                      EnableMenuItem (hwnd, IDM_FREEZE_HALT, TRUE) ;
  410.                      cp.fSuppressPaint = TRUE;
  411.                      WinInvalidateRect(hwnd, NULL, FALSE);
  412.                      }
  413.                  }
  414.  
  415.                return 0 ;
  416.                }
  417.  
  418.           case IDM_READ_COLORMAP:
  419.                /* Send up the generic Open File dialog.
  420.                   On OK return, read in the file via subroutine. */
  421.                {
  422.                DLF dlf;
  423.                HFILE hfDummy;
  424.  
  425.                SetupDLF (&dlf, DLG_OPENDLG, &hfDummy,
  426.                          "\\*.map", szTitleBar,
  427.                          szColorMapTitle, szColorMapHelp);
  428.  
  429.                if (TDF_OLDOPEN == DlgFile(hwnd, &dlf) )
  430.                   {
  431.                   /* close the dummy file handle */
  432.                   DosClose(hfDummy);
  433.                   /* throw up the hour-glass */
  434.                   WinSetCapture(HWND_DESKTOP, hwnd);
  435.                   WinSetPointer(HWND_DESKTOP, hptrWait);
  436.                   /* read it in */
  437.                   LoadColorMap(dlf.szOpenFile);
  438.                   /* now clean up */
  439.                   WinSetPointer(HWND_DESKTOP, hptrArrow);
  440.                   WinSetCapture(HWND_DESKTOP, (HWND) NULL);
  441.                   }
  442.                }
  443.  
  444.                return 0;
  445.  
  446.           case IDM_WRITE_COLORMAP:
  447.                /* Send up the generic Save File dialog.
  448.                   On OK return, write the file via subroutine */
  449.                {
  450.                DLF dlf;
  451.                HFILE hfDummy;
  452.  
  453.                SetupDLF (&dlf, DLG_SAVEDLG, &hfDummy,
  454.                          "\\*.map", szTitleBar,
  455.                          szColorMapTitle, szColorMapHelp);
  456.  
  457.                if (TDF_NOSAVE != DlgFile(hwnd, &dlf) )
  458.                   {
  459.                   /* close the dummy file handle */
  460.                   DosClose(hfDummy);
  461.                   /* throw up the hour-glass */
  462.                   WinSetCapture(HWND_DESKTOP, hwnd);
  463.                   WinSetPointer(HWND_DESKTOP, hptrWait);
  464.                   /* write it out */
  465.                   SaveColorMap(dlf.szOpenFile);
  466.                   /* now clean up */
  467.                   WinSetPointer(HWND_DESKTOP, hptrArrow);
  468.                   WinSetCapture(HWND_DESKTOP, (HWND) NULL);
  469.                   }
  470.                }
  471.  
  472.                return 0;
  473.  
  474.           case IDM_CLEAR_CLPB:
  475.                /* clear the current contents of the clipboard */
  476.                WinOpenClipbrd (hab);
  477.                WinEmptyClipbrd (hab);
  478.                WinCloseClipbrd (hab);
  479.  
  480.                return 0;
  481.  
  482.           case IDM_PASTE:
  483.                {  /* paste from the clipboard into us */
  484.                USHORT usClipBrdInfo;
  485.  
  486.                if ( WinQueryClipbrdFmtInfo(hab, CF_BITMAP, &usClipBrdInfo) )
  487.                   {  /* we have a bitmap to fetch */
  488.                   /* draw the curtain over the display */
  489.                   cp.fSuppressPaint = TRUE;
  490.                   WinInvalidateRect(hwnd, NULL, FALSE);
  491.                   WinUpdateWindow(hwnd);
  492.                   /* throw up the hour-glass */
  493.                   WinSetCapture(HWND_DESKTOP, hwnd);
  494.                   WinSetPointer(HWND_DESKTOP, hptrWait);
  495.                   /* fetch the bitmap */
  496.                   PMfrFetchClipbrdBmp(hab);
  497.                   /* now clean up */
  498.                   WinSetPointer(HWND_DESKTOP, hptrArrow);
  499.                   WinSetCapture(HWND_DESKTOP, (HWND) NULL);
  500.                   /* and schedule redrawing the window */
  501.                   SetSwitchEntry (hwnd, szTitleBar,
  502.                                   GetFractalName(cp.iFractType) );
  503.                   cp.fSuppressPaint = FALSE;
  504.                   WinInvalidateRect(hwnd, NULL, FALSE);
  505.                   }
  506.                }
  507.  
  508.                return 0;
  509.  
  510.           case IDM_COPY_BMP:
  511.                {  /* copy to the clipboard from us */
  512.  
  513.                /* throw up the hour-glass */
  514.                WinSetCapture(HWND_DESKTOP, hwnd);
  515.                WinSetPointer(HWND_DESKTOP, hptrWait);
  516.                /* write the bitmap */
  517.                PMfrWriteClipbrdBmp(hab);
  518.                /* now clean up */
  519.                WinSetPointer(HWND_DESKTOP, hptrArrow);
  520.                WinSetCapture(HWND_DESKTOP, (HWND) NULL);
  521.  
  522.                }
  523.  
  524.                return 0;
  525.  
  526.           }
  527.  
  528.      return 0;
  529.  
  530.      }
  531.  
  532. /* --------------------------------------------------------------------- */
  533.  
  534. /*
  535.    Helper functions for reading and writing color palette files.
  536. */
  537.  
  538. VOID LoadColorMap(PSZ szFileName)
  539.    {
  540.  
  541.    FILE *file;
  542.    char tempname[128];
  543.    char line[128];
  544.    SHORT i;
  545.    RGB _far *prgb;
  546.    BYTE r, g, b;
  547.  
  548.    _fstrcpy(tempname, szFileName);
  549.  
  550.    prgb = &bmiColorTableUser.argbColor[0];
  551.  
  552.    file = fopen(tempname, "r" );
  553.  
  554.    if (file == NULL)
  555.           return;
  556.  
  557.    for( i = 0; i < 256; i++ )
  558.         {
  559.         if (fgets(line,100,file) == NULL)
  560.              break;
  561.  
  562.         sscanf( line, "%d %d %d",    /* R G B */
  563.                &r, &g, &b);
  564.         prgb[i].bRed = r;
  565.         prgb[i].bGreen = g;
  566.         prgb[i].bBlue = b;
  567.         }
  568.  
  569.    fclose(file);
  570.  
  571.    /* now effect a switch to the new palette */
  572.    cp.pbmiMemory = &bmiColorTableUser;
  573.    cp.sCurrentPalette = IDD_PAL_USER;
  574.    cp.fNewBits = TRUE;
  575.    cp.fHaveUserPalette = TRUE;
  576.    WinInvalidateRect(cp.hwnd, NULL, FALSE);
  577.  
  578.    }
  579.  
  580. VOID SaveColorMap(PSZ szFileName)
  581.    {
  582.  
  583.    FILE *file;
  584.    char tempname[128];
  585.    SHORT i;
  586.    RGB _far *prgb;
  587.    BYTE r, g, b;
  588.  
  589.    _fstrcpy(tempname, szFileName);
  590.  
  591.    file = fopen(tempname,"w");
  592.    if (file == NULL)
  593.        return;
  594.  
  595.    prgb = &cp.pbmiMemory->argbColor[0];
  596.  
  597.    fprintf(file,"  0   0   0\n");
  598.  
  599.    for (i = 1; i < 256; i++)
  600.        {
  601.        r = prgb[i].bRed;
  602.        g = prgb[i].bGreen;
  603.        b = prgb[i].bBlue;
  604.        fprintf(file, "%3d %3d %3d\n",  /* R G B */
  605.                      r, g, b);
  606.        }
  607.  
  608.    fclose(file);
  609.  
  610.    }
  611.  
  612. /* --------------------------------------------------------------------- */
  613.  
  614. /*
  615.    Helper functions for handling user interfact needs like
  616.    zooming and panning.
  617. */
  618. VOID InitCrossHairs(VOID)
  619.      {
  620.      ptlCrossHairs.x = -1;
  621.      ptlCrossHairs.y = -1;
  622.      }
  623.  
  624. VOID DrawCrossHairsInner (HWND hwnd)
  625.      {
  626.      POINTL ptl1;
  627.  
  628.      GpiSetMix (cp.hpsScreen, FM_INVERT) ;
  629.  
  630.      ptl1.x = 0; ptl1.y = ptlCrossHairs.y;
  631.      GpiMove (cp.hpsScreen, &ptl1);
  632.      ptl1.x = cxClient-1;
  633.      GpiLine (cp.hpsScreen, &ptl1);
  634.      ptl1.x = ptlCrossHairs.x; ptl1.y = 0;
  635.      GpiMove (cp.hpsScreen, &ptl1);
  636.      ptl1.y = cyClient-1;
  637.      GpiLine (cp.hpsScreen, &ptl1);
  638.  
  639.      GpiSetMix (cp.hpsScreen, FM_DEFAULT);
  640.      }
  641.  
  642. VOID DrawCrossHairs (HWND hwnd, PPOINTL pptlMouse)
  643.      {
  644.  
  645.      if (ptlCrossHairs.x != -1)
  646.         DrawCrossHairsInner(hwnd);    /* erase old lines */
  647.  
  648.      ptlCrossHairs.x = pptlMouse->x;
  649.      ptlCrossHairs.y = pptlMouse->y;
  650.      DrawCrossHairsInner(hwnd);
  651.  
  652.      }
  653.  
  654. VOID MoveCrossHairs (HWND hwnd, MPARAM mp1)
  655.      {
  656.       SHORT xMouse = SHORT1FROMMP (mp1);
  657.       SHORT yMouse = SHORT2FROMMP (mp1);
  658.       POINTL ptl1;
  659.  
  660.       /* limit mouse coordinates to window bounds */
  661.       xMouse = min(xMouse, cxClient-1);
  662.       xMouse = max(xMouse, 0);
  663.       yMouse = min(yMouse, cyClient-1);
  664.       yMouse = max(yMouse, 0);
  665.       /* update the cross hairs */
  666.       ptl1.x = (LONG) xMouse;
  667.       ptl1.y = (LONG) yMouse;
  668.       DrawCrossHairs (hwnd, &ptl1);
  669.  
  670.      }
  671.  
  672. VOID    EraseCrossHairs(HWND hwnd)
  673.     {
  674.     DrawCrossHairsInner(hwnd);
  675.     }
  676.  
  677. VOID  InitZoomBox(SHORT x, SHORT y)
  678.      {
  679.       ptlZBox1.x = x;
  680.       ptlZBox1.y = y;
  681.       ptlZBox2.x = -1;
  682.       ptlZBox2.y = -1;
  683.  
  684.      }
  685.  
  686. VOID DrawZoomBoxInner (HWND hwnd)
  687.      {
  688.  
  689.      GpiSetMix (cp.hpsScreen, FM_INVERT) ;
  690.  
  691.      GpiMove (cp.hpsScreen, &ptlZBox1);
  692.      GpiBox (cp.hpsScreen, DRO_OUTLINE, &ptlZBox2, 0L, 0L);
  693.  
  694.      GpiSetMix (cp.hpsScreen, FM_DEFAULT);
  695.      }
  696.  
  697. VOID DrawZoomBox (HWND hwnd, PPOINTL pptlMouse)
  698.      {
  699.  
  700.      if (ptlZBox2.x != -1)
  701.         DrawZoomBoxInner(hwnd);    /* erase old box */
  702.  
  703.      ptlZBox2.x = pptlMouse->x;
  704.      ptlZBox2.y = pptlMouse->y;
  705.      DrawZoomBoxInner(hwnd);
  706.  
  707.      }
  708.  
  709. VOID MoveZoomBox (HWND hwnd, MPARAM mp1)
  710.      {
  711.       SHORT xMouse = SHORT1FROMMP (mp1);
  712.       SHORT yMouse = SHORT2FROMMP (mp1);
  713.       POINTL ptl1;
  714.  
  715.       /* limit mouse coordinates to window bounds */
  716.       xMouse = min(xMouse, cxClient-1);
  717.       xMouse = max(xMouse, 0);
  718.       yMouse = min(yMouse, cyClient-1);
  719.       yMouse = max(yMouse, 0);
  720.       /* update the Zoom Box */
  721.       ptl1.x = (LONG) xMouse;
  722.       ptl1.y = (LONG) yMouse;
  723.       DrawZoomBox (hwnd, &ptl1);
  724.  
  725.      }
  726.  
  727. VOID EraseZoomBox (HWND hwnd)
  728.      {
  729.       DrawZoomBoxInner (hwnd);
  730.  
  731.      }
  732.  
  733. /*------------------------------------------------
  734.    We did a pan.  Find out where we are now
  735.    and schedule the parameter change.
  736.  ------------------------------------------------*/
  737. VOID PanNewCenter(HWND hwnd)
  738.      {
  739.      double dTemp, dDelta;
  740.  
  741.      /* process the parms change */
  742.      InitNewParms(NULL);
  743.      dTemp = npNewParms.XL + (npNewParms.XR - npNewParms.XL) *
  744.                 ( ((double) ptlCrossHairs.x) / ((double) (cxClient-1)) );
  745.      dDelta = dTemp - npNewParms.XCenter;
  746.      npNewParms.XCenter = dTemp;
  747.      if (dDelta < 0.0)
  748.         {   /* shift left - check left edge first for out of bounds */
  749.         dTemp = npNewParms.XL + dDelta;   /* new assumed left edge */
  750.         npNewParms.XL = max(dTemp, npNewParms.mxXL); /* corrected left edge */
  751.         dDelta = npNewParms.XL - npNewParms.XCenter;
  752.         npNewParms.XR = npNewParms.XCenter - dDelta;
  753.         }
  754.      else
  755.         {   /* shift right - check right edge first for out of bounds */
  756.         dTemp = npNewParms.XR + dDelta;   /* new assumed right edge */
  757.         npNewParms.XR = min(dTemp,  npNewParms.mxXR); /* corrected right edge */
  758.         dDelta = npNewParms.XR - npNewParms.XCenter;
  759.         npNewParms.XL = npNewParms.XCenter - dDelta;
  760.         }
  761.      dTemp = npNewParms.YB + (npNewParms.YT - npNewParms.YB) *
  762.              ( ((double) ptlCrossHairs.y) / ((double) (cyClient-1)) ) ;
  763.      dDelta = dTemp - npNewParms.YCenter;
  764.      npNewParms.YCenter = dTemp;
  765.      if (dDelta < 0.0)
  766.         {   /* shift down - check bottom edge first for out of bounds */
  767.         dTemp = npNewParms.YB + dDelta;   /* new assumed bottom edge */
  768.         npNewParms.YB = max(dTemp, npNewParms.mxYB); /* corrected bottom edge */
  769.         dDelta = npNewParms.YB - npNewParms.YCenter;
  770.         npNewParms.YT = npNewParms.YCenter - dDelta;
  771.         }
  772.      else
  773.         {   /* shift up - check top edge first for out of bounds */
  774.         dTemp = npNewParms.YT + dDelta;   /* new assumed top edge */
  775.         npNewParms.YT = min(dTemp,  npNewParms.mxYT); /* corrected top edge */
  776.         dDelta = npNewParms.YT - npNewParms.YCenter;
  777.         npNewParms.YB = npNewParms.YCenter - dDelta;
  778.         }
  779.      npNewParms.fNewParms = TRUE;
  780.      ScheduleNewParms(hwnd);
  781.  
  782.      }
  783.  
  784. /*----------------------------------------------
  785.    We did a zoom window.  Find out where we are
  786.    now and schdedule the parameter change.
  787.  ----------------------------------------------*/
  788. VOID ZoomNewWindow (HWND hwnd, BOOL InOrOut)
  789.     {
  790.     NEWPARAM npTempParms;
  791.     double dTemp, dDXOld, dDXNew, dDYOld, dDYNew;
  792.     LONG   lDXOld, lDYOld;
  793.  
  794.     /* process the parms change */
  795.     InitNewParms(&npTempParms);
  796.  
  797.     if (InOrOut)
  798.        {  /* TRUE == Zoom In */
  799.        /* left edge */
  800.        dTemp = (double) min(ptlZBox1.x, ptlZBox2.x);
  801.        npNewParms.XL = npTempParms.XL + (npTempParms.XR - npTempParms.XL) *
  802.                        ( dTemp / ((double) (cxClient-1)) );
  803.        /* right edge */
  804.        dTemp = (double) max(ptlZBox1.x, ptlZBox2.x);
  805.        npNewParms.XR = npTempParms.XL + (npTempParms.XR - npTempParms.XL) *
  806.                        ( dTemp / ((double) (cxClient-1)) );
  807.        /* top edge */
  808.        dTemp = (double) max(ptlZBox1.y, ptlZBox2.y);
  809.        npNewParms.YT = npTempParms.YB + (npTempParms.YT - npTempParms.YB) *
  810.                        ( dTemp / ((double) (cyClient-1)) );
  811.        /* bottom edge */
  812.        dTemp = (double) min(ptlZBox1.y, ptlZBox2.y);
  813.        npNewParms.YB = npTempParms.YB + (npTempParms.YT - npTempParms.YB) *
  814.                        ( dTemp / ((double) (cyClient-1)) );
  815.        }
  816.     else
  817.        {  /* FALSE == Zoom Out */
  818.  
  819.        /* lDXOld is the new zoom box dimensions, representing the old
  820.           screen complex range */
  821.  
  822.        lDXOld = labs(ptlZBox2.x - ptlZBox1.x);
  823.        lDYOld = labs(ptlZBox2.y - ptlZBox1.y);
  824.        dDXOld = npTempParms.XR - npTempParms.XL;
  825.        dDYOld = npTempParms.YT - npTempParms.YB;
  826.  
  827.        dDXNew = dDXOld * ((double) cxClient)/((double) lDXOld);
  828.        dDYNew = dDYOld * ((double) cyClient)/((double) lDYOld);
  829.  
  830.        /* calculate a new center point */
  831.        npNewParms.XCenter = npTempParms.XL +
  832.             ( (double) ((ptlZBox1.x + ptlZBox2.x)/2L) / (double) cxClient )
  833.                       * dDXOld ;
  834.        npNewParms.YCenter = npTempParms.YB +
  835.             ( (double) ((ptlZBox1.y + ptlZBox2.y)/2L) / (double) cyClient )
  836.                       * dDYOld ;
  837.  
  838.        /* left edge */
  839.        npNewParms.XL = npNewParms.XCenter - dDXNew / 2.0e0L;
  840.  
  841.        /* right edge */
  842.        npNewParms.XR = npNewParms.XCenter + dDXNew / 2.0e0L;
  843.  
  844.        /* top edge */
  845.        npNewParms.YT = npNewParms.YCenter + dDYNew / 2.0e0L;
  846.  
  847.        /* bottom edge */
  848.        npNewParms.YB = npNewParms.YCenter - dDYNew / 2.0e0L;
  849.  
  850.        /* now clip to the max size */
  851.        npNewParms.XL = max(npNewParms.XL, npNewParms.mxXL);
  852.        npNewParms.XR = min(npNewParms.XR, npNewParms.mxXR);
  853.        npNewParms.YT = min(npNewParms.YT, npNewParms.mxYT);
  854.        npNewParms.YB = max(npNewParms.YB, npNewParms.mxYB);
  855.        }
  856.  
  857.     /* always recalculate a valid center point */
  858.     npNewParms.XCenter = (npNewParms.XL + npNewParms.XR)/2.0;
  859.     npNewParms.YCenter = (npNewParms.YT + npNewParms.YB)/2.0;
  860.  
  861.     npNewParms.fNewParms = TRUE;
  862.     ScheduleNewParms(hwnd);
  863.     }
  864.  
  865. /*-----------------------------------------------
  866.    Back us out of zoom or pan mode.
  867.    Called for a variety of reasons from the
  868.    main window function.
  869.  -----------------------------------------------*/
  870. VOID CancelZoomOrPan (HWND hwnd)
  871.     {
  872.      if (fPan)    /* Panning */
  873.         {
  874.         /* erase the cross hairs */
  875.         EraseCrossHairs(hwnd);
  876.         WinSetCapture (HWND_DESKTOP, (HWND) NULL);
  877.         WinShowPointer (HWND_DESKTOP, TRUE);  /* reshow normal mouse pointer */
  878.         fPan = FALSE;
  879.         fGoodPan = FALSE;
  880.         fZoomWin = FALSE;
  881.         }
  882.  
  883.      if (fZoomWin)    /* Zooming */
  884.         {
  885.         /* erase the Zoom Box */
  886.         EraseZoomBox(hwnd);
  887.         WinSetCapture (HWND_DESKTOP, (HWND) NULL);
  888.         WinShowPointer (HWND_DESKTOP, TRUE);  /* reshow normal mouse pointer */
  889.         fZoomWin = FALSE;
  890.         fGoodZoom = FALSE;
  891.         fPan = FALSE;
  892.         }
  893.     }
  894.  
  895. /*---------------------------------------------
  896.    Helper subroutines to work over menu items.
  897.  ---------------------------------------------*/
  898. VOID EnableMenuItem (HWND hwnd, SHORT sMenuItem, BOOL fEnable)
  899.      {
  900.      HWND  hwndParent = WinQueryWindow (hwnd, QW_PARENT, FALSE) ;
  901.      HWND  hwndMenu   = WinWindowFromID (hwndParent, FID_MENU) ;
  902.  
  903.      WinSendMsg (hwndMenu, MM_SETITEMATTR,
  904.                  MPFROM2SHORT (sMenuItem, TRUE),
  905.                  MPFROM2SHORT (MIA_DISABLED, fEnable ? 0 : MIA_DISABLED)) ;
  906.      }
  907.  
  908. VOID    UpdateMenuText (HWND hwnd, SHORT sMenuItem, PSZ szNewText)
  909.      {
  910.      HWND hwndParent = WinQueryWindow (hwnd, QW_PARENT, FALSE);
  911.      HWND hwndMenu   = WinWindowFromID (hwndParent, FID_MENU);
  912.  
  913.      WinSendMsg (hwndMenu, MM_SETITEMTEXT,
  914.                  MPFROMSHORT ( sMenuItem ),
  915.                  MPFROMP ( szNewText) ) ;
  916.      }
  917.  
  918. BOOL UpdateMenuStatus (HWND hwnd, SHORT sMenuID)
  919.      {
  920.  
  921.      /*
  922.       *  UpdateMenuStatus tests for and keeps updated the
  923.       *  state of the GO button on the main menu bar.
  924.       *  Also the selectability and text of the
  925.       *  Swap between Mandel/Julia selection on the Set menu.
  926.       *  Also other menu items.
  927.      */
  928.  
  929.      int iWhatFractal;
  930.      double ccreal, ccimag;
  931.      USHORT usClipBrdInfo;
  932.  
  933.      switch (sMenuID)
  934.             {
  935.             case ID_RESOURCE:
  936.  
  937.                  if (tidCalc == -1)
  938.                       EnableMenuItem (hwnd, IDM_GO, FALSE) ;
  939.                  return TRUE;
  940.  
  941.             case IDM_OPTIONS_MENU:
  942.  
  943.                  /* keep Mandel/Julia status up to date */
  944.                  /* keep Reset status up to date */
  945.  
  946.                  if (sStatus == STATUS_FROZEN)
  947.                     {
  948.                     iWhatFractal = npNewParms.iFractType;
  949.                     ccreal = npNewParms.param[0];
  950.                     ccimag = npNewParms.param[1];
  951.                     }
  952.                  else
  953.                     {
  954.                     iWhatFractal = cp.iFractType;
  955.                     ccreal = cp.param[0];
  956.                     ccimag = cp.param[1];
  957.                     }
  958.  
  959.                  if (fractalspecific[iWhatFractal].tojulia != NOFRACTAL
  960.                        && ccreal == 0.0 && ccimag == 0.0)
  961.                     {   /* to julia is kosher */
  962.                     UpdateMenuText (hwnd, IDM_SET_SWAP, szSwapJulia);
  963.                     EnableMenuItem (hwnd, IDM_SET_SWAP, TRUE);
  964.                     }
  965.                  else
  966.                  if (fractalspecific[iWhatFractal].tomandel != NOFRACTAL)
  967.                     {   /* to mandel is kosher */
  968.                     UpdateMenuText (hwnd, IDM_SET_SWAP, szSwapMandel);
  969.                     EnableMenuItem (hwnd, IDM_SET_SWAP, TRUE);
  970.                     }
  971.                  else
  972.                     {   /* this is a stand-alone fractal, swap disabled */
  973.                     UpdateMenuText (hwnd, IDM_SET_SWAP, szSwapMandel);
  974.                     EnableMenuItem (hwnd, IDM_SET_SWAP, FALSE);
  975.                     }
  976.  
  977.                  EnableMenuItem (hwnd, IDM_SET_RESET,
  978.                                         sStatus == STATUS_FROZEN );
  979.                  EnableMenuItem (hwnd, IDM_SET_EXTENTS,
  980.                        (sStatus != STATUS_NEWPARMS) &&
  981.                        (sStatus != STATUS_INIT) );
  982.                  EnableMenuItem (hwnd, IDM_SET_PARAMS,
  983.                        (sStatus != STATUS_NEWPARMS) &&
  984.                        (sStatus != STATUS_INIT) );
  985.                  EnableMenuItem (hwnd, IDM_SET_OPTIONS,
  986.                        (sStatus != STATUS_NEWPARMS) &&
  987.                        (sStatus != STATUS_INIT) );
  988.                  EnableMenuItem (hwnd, IDM_SET_IMAGE,
  989.                        (sStatus != STATUS_NEWPARMS) &&
  990.                        (sStatus != STATUS_INIT) );
  991.                  EnableMenuItem (hwnd, IDM_SET_PALETTE,
  992.                        (sStatus != STATUS_NEWPARMS) &&
  993.                        (sStatus != STATUS_INIT) );
  994.  
  995.                  return TRUE;
  996.  
  997.             case IDM_EDIT_MENU:
  998.  
  999.                  EnableMenuItem (hwnd, IDM_COPY_BMP,
  1000.                        sStatus == STATUS_READY);
  1001.                  EnableMenuItem (hwnd, IDM_COPY_MET,
  1002.                        sStatus == STATUS_READY);
  1003.                  EnableMenuItem (hwnd, IDM_PASTE,
  1004.                       ( sStatus == STATUS_READY ) &&
  1005.                       ( WinQueryClipbrdFmtInfo(hab, CF_BITMAP, &usClipBrdInfo)
  1006.                         /* || WinQueryClipbrdFmtInfo(hab, CF_METAFILE, &usClipBrdInfo) */
  1007.                         ) ) ;
  1008.                  EnableMenuItem (hwnd, IDM_CLPB_TEXT,
  1009.                         WinQueryClipbrdFmtInfo(hab, CF_TEXT, &usClipBrdInfo) );
  1010.                  EnableMenuItem (hwnd, IDM_CLPB_BMP,
  1011.                         WinQueryClipbrdFmtInfo(hab, CF_BITMAP, &usClipBrdInfo) );
  1012.                  EnableMenuItem (hwnd, IDM_CLPB_MET,
  1013.                         WinQueryClipbrdFmtInfo(hab, CF_METAFILE, &usClipBrdInfo) );
  1014.  
  1015.                  return TRUE;
  1016.  
  1017.             case IDM_FILE_MENU:
  1018.  
  1019.                  EnableMenuItem (hwnd, IDM_NEW_FRACTAL,
  1020.                        (sStatus != STATUS_NEWPARMS) &&
  1021.                        (sStatus != STATUS_INIT) );
  1022.                  EnableMenuItem (hwnd, IDM_PRINT_FILE,
  1023.                        sStatus == STATUS_READY);
  1024.                  EnableMenuItem (hwnd, IDM_SAVE_FILE,
  1025.                        sStatus == STATUS_READY);
  1026.                  EnableMenuItem (hwnd, IDM_READ_FILE,
  1027.                        sStatus == STATUS_READY);
  1028.                  EnableMenuItem (hwnd, IDM_READ_COLORMAP,
  1029.                        sStatus != STATUS_INIT);
  1030.                  EnableMenuItem (hwnd, IDM_WRITE_COLORMAP,
  1031.                        sStatus != STATUS_INIT);
  1032.  
  1033.                  return TRUE;
  1034.  
  1035.             case IDM_VIEW_MENU:
  1036.  
  1037.                  EnableMenuItem (hwnd, IDM_ZIN_WIN, fGoodZoom);
  1038.                  EnableMenuItem (hwnd, IDM_ZOUT_WIN, fGoodZoom);
  1039.                  EnableMenuItem (hwnd, IDM_PAN,
  1040.                         fGoodPan && (sStatus != STATUS_NEWPARMS) &&
  1041.                                     (sStatus != STATUS_INIT) );
  1042.                  EnableMenuItem (hwnd, IDM_ZIN_MENU,
  1043.                        (sStatus != STATUS_NEWPARMS) &&
  1044.                        (sStatus != STATUS_INIT) );
  1045.                  EnableMenuItem (hwnd, IDM_ZOUT_MENU,
  1046.                        (sStatus != STATUS_NEWPARMS) &&
  1047.                        (sStatus != STATUS_INIT) );
  1048.  
  1049.                  return TRUE;
  1050.  
  1051.             default:
  1052.                  break;
  1053.  
  1054.             }
  1055.  
  1056.      return FALSE;
  1057.  
  1058.      }
  1059.  
  1060. /*-----------------------------------------------
  1061.    Helper function to keep the title bar and the
  1062.    switch entry up to date.
  1063.  -----------------------------------------------*/
  1064. VOID SetSwitchEntry(HWND hwnd, PSZ szTitleBar, PSZ szFract)
  1065. {
  1066.     PID pid;
  1067.     static SWCNTRL swcntrl;
  1068.     static HSWITCH hswitch = NULL;
  1069.     HWND hwndFrame;
  1070.  
  1071.     hwndFrame = WinQueryWindow (hwnd, QW_PARENT, FALSE);
  1072.  
  1073.     if (hswitch == (HSWITCH) NULL) {  /* if first time */
  1074.  
  1075.         /* get our process ID for the Switch structure */
  1076.         WinQueryWindowProcess(hwndFrame, &pid, NULL);
  1077.  
  1078.         /* add/change switch list entry */
  1079.         swcntrl.hwnd             = hwndFrame;
  1080.         swcntrl.hwndIcon         = (HWND) NULL;
  1081.         swcntrl.hprog            = (HPROGRAM) NULL;
  1082.         swcntrl.idProcess        = pid;
  1083.         swcntrl.idSession        = 0;
  1084.         swcntrl.uchVisibility    = SWL_VISIBLE;
  1085.         swcntrl.fbJump           = SWL_JUMPABLE;
  1086.         _fstrcpy( swcntrl.szSwtitle, szTitleBar);
  1087.         strcat( swcntrl.szSwtitle, " - ");
  1088.         _fstrcat( swcntrl.szSwtitle, szFract);
  1089.         swcntrl.fReserved        = '\0';
  1090.  
  1091.         hswitch = WinAddSwitchEntry( &swcntrl );
  1092.     }
  1093.     else {   /* do an update */
  1094.         _fstrcpy( swcntrl.szSwtitle, szTitleBar);
  1095.         strcat( swcntrl.szSwtitle, " - ");
  1096.         _fstrcat( swcntrl.szSwtitle, szFract);
  1097.  
  1098.         WinChangeSwitchEntry( hswitch, &swcntrl);
  1099.     }
  1100.  
  1101.     /* now put it in the titlebar also */
  1102.     WinSetWindowText(hwndFrame, swcntrl.szSwtitle);
  1103.  
  1104. }
  1105.  
  1106. /*--------------------------------------------------
  1107.   Subfunction for all dialog boxes.
  1108.  
  1109.   Arrange for the dialog box to be centered on the
  1110.   screen.
  1111.  --------------------------------------------------*/
  1112. VOID CenterDialogBox (HWND hwnd)
  1113.    {
  1114.    SWP swpMe;
  1115.    SHORT xNew, yNew;
  1116.  
  1117.    WinQueryWindowPos(hwnd, &swpMe);
  1118.  
  1119.    xNew = ((SHORT) cxScreen - swpMe.cx) / 2;
  1120.    yNew = ((SHORT) cyScreen - swpMe.cy) / 2;
  1121.  
  1122.    WinSetWindowPos(hwnd, HWND_TOP, xNew, yNew, 0, 0,
  1123.                SWP_MOVE);
  1124.    }
  1125.  
  1126. /* --------------------------------------------------------------------- */
  1127.  
  1128. /*
  1129.    Helper function for specifying file load/save extension.
  1130. */
  1131.  
  1132. VOID FileFmtExt (PSZ far *ppszFmt)
  1133.    {
  1134.  
  1135.    switch (cp.sLastLoadSaveType)
  1136.       {
  1137.       case SUB_LOADSAVE_GIF:
  1138.            *ppszFmt = szExtGIF;
  1139.            break;
  1140.  
  1141.       case SUB_LOADSAVE_BMP:
  1142.            *ppszFmt = szExtBMP;
  1143.            break;
  1144.  
  1145.       case SUB_LOADSAVE_MET:
  1146.            *ppszFmt = szExtMET;
  1147.            break;
  1148.  
  1149.       case SUB_LOADSAVE_WIN3BMP:
  1150.            *ppszFmt = szExtBMP;
  1151.            break;
  1152.  
  1153.       case SUB_LOADSAVE_PCX:
  1154.            *ppszFmt = szExtPCX;
  1155.            break;
  1156.  
  1157.       default:
  1158.            *ppszFmt = szExtGIF;
  1159.       }
  1160.  
  1161.    }
  1162.