home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / d / d020_1_4 / 6.ddi / SHOWDIB / DLGOPEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-01  |  14.3 KB  |  490 lines

  1. /*******************************************************************************
  2.  *                                           *
  3.  *  MODULE    : DLGOPEN.C                               *
  4.  *                                           *
  5.  *  DESCRIPTION : Routines to display a standard File/Open and File/Save       *
  6.  *          dialog boxes.                            *
  7.  *                                           *
  8.  *  FUNCTIONS    : DlgOpenFile() - Displays a dialog box for opening or saving a*
  9.  *                  file.                        *
  10.  *                                           *
  11.  *          DlgfnOpen()    - Dialog function for the above dialog.        *
  12.  *                                           *
  13.  *          AddExt()    - Adds an extension to a filename if not       *
  14.  *                  already present.                   *
  15.  *                                           *
  16.  *          FSearchSpec() - Checks if given string contains a wildcard   *
  17.  *                  character.                       *
  18.  *                                           *
  19.  *          FillListBox() - Fills listbox with files that match specs.   *
  20.  *                                           *
  21.  *          DlgCheckOkEnable() - Enables <OK> button iff there's text in *
  22.  *                       the edit control.               *
  23.  *                                           *
  24.  *          NOTE : These routines require that the app. be running       *
  25.  *             SS = DS since they use near pointers into the stack.  *
  26.  *                                           *
  27.  *******************************************************************************/
  28. #include <windows.h>
  29. #include "showdib.h"
  30.  
  31. static PSTR         szExt;
  32. static PSTR         szFileName;
  33. static PSTR         szTitle;
  34. static DWORD        flags;
  35. static WORD         fOpt;
  36.  
  37. /* Forward declarations of helper functions */
  38.  
  39. static void  NEAR DlgCheckOkEnable(HWND hwnd, int idEdit, unsigned message);
  40. static char *NEAR FillListBox (HWND,char*);
  41. static BOOL  NEAR FSearchSpec (char*);
  42. static void  NEAR AddExt (char*,char*);
  43. extern PASCAL chdir(LPSTR);         /* in dlgopena.asm */
  44.  
  45. #define DLGOPEN_UNUSED     0
  46.  
  47. /* Mask to eliminate bogus style and bitcount combinations ...
  48.  * RLE formats, if chosen should be matched with the bitcounts:
  49.  *   RLE4 scheme should be used only for 4 bitcount DIBs.
  50.  *   RLE8   "      "     "   "     "    "  8   "       "
  51.  *
  52.  * BITCOUNTMASK is indexed by DLGOPEN_RLE4 >> 4, DLGOPEN_RLE8 >> 4
  53.  * and DLGOPEN_RLE8 >> 4
  54.  */
  55.  
  56. static WORD BITCOUNTMASK[] = { DLGOPEN_UNUSED,
  57.                    DLGOPEN_1BPP | DLGOPEN_8BPP | DLGOPEN_24BPP,
  58.                    DLGOPEN_1BPP | DLGOPEN_4BPP | DLGOPEN_24BPP,
  59.                    DLGOPEN_UNUSED,
  60.                    0 };
  61.  
  62. /*******************************************************************************
  63.  *                                           *
  64.  *  FUNCTION   :DlgOpen(LPSTR szFile)                           *
  65.  *                                           *
  66.  *  PURPOSE    :Display dialog box for opening files. Allow user to interact   *
  67.  *        with dialogbox, change directories as necessary, and try to    *
  68.  *        open file if user selects one. Automatically append           *
  69.  *        extension to filename if necessary.                   *
  70.  *        This routine correctly parses filenames containing KANJI       *
  71.  *        characters.                               *
  72.  *                                           *
  73.  *  RETURNS    :  - Handle to the opened file if legal filename.           *
  74.  *          - 0 if user presses <cancel>                       *
  75.  *          - 1 if filename entered is illegal                   *
  76.  *                                           *
  77.  *******************************************************************************/
  78. int FAR PASCAL DlgOpenFile (hwndParent, szTitleIn, flagsIn, szExtIn,
  79.                 szFileNameIn, pfOpt)
  80.  
  81. HWND      hwndParent;
  82. char      *szTitleIn;
  83. DWORD      flagsIn;
  84. char      *szExtIn;
  85. char      *szFileNameIn;
  86. WORD      *pfOpt;
  87. {
  88.     int      fh;
  89.     FARPROC  lpProc;
  90.     char     achFile[128];
  91.     char     achExt[128];
  92.     HANDLE   hInstance;
  93.     WORD     w;
  94.  
  95.     if (pfOpt == NULL)
  96.         pfOpt = &w;
  97.  
  98.     flags    = flagsIn;
  99.     fOpt     = *pfOpt;
  100.  
  101.     lstrcpy (szFileName = achFile, szFileNameIn);
  102.     lstrcpy (szExt = achExt, szExtIn);
  103.     szTitle = szTitleIn;
  104.  
  105.     hInstance = GetWindowWord (hwndParent, GWW_HINSTANCE);
  106.  
  107.     /* Show the dialog box */
  108.     lpProc = MakeProcInstance ((FARPROC)DlgfnOpen, hInstance);
  109.     fh = DialogBox (hInstance, "DlgOpenBox", hwndParent, lpProc);
  110.     FreeProcInstance (lpProc);
  111.  
  112.     if (fh != 0){
  113.     lstrcpy (szFileNameIn, szFileName);
  114.         *pfOpt = fOpt;
  115.     }
  116.     return fh;
  117. }
  118.  
  119. /****************************************************************************
  120.  *                                        *
  121.  *  FUNCTION   :DlgfnOpen (hwnd, msg, wParam, lParam)                *
  122.  *                                        *
  123.  *  PURPOSE    :Dialog function for File/Open dialog.                *
  124.  *                                        *
  125.  ****************************************************************************/
  126. int far PASCAL DlgfnOpen (hwnd, msg, wParam, lParam)
  127.  
  128. HWND hwnd;
  129. unsigned msg;
  130. WORD wParam;
  131. LONG lParam;
  132. {
  133.     int      result = -1;    /* Assume illegal filename initially */
  134.     WORD     w;
  135.     char     c;
  136.     WORD     f;
  137.     OFSTRUCT of;
  138.     RECT     rc, rcCtl;
  139.     HWND     hwndT;
  140.     BOOL     fEnable;
  141.  
  142.     switch (msg) {
  143.     case WM_INITDIALOG:
  144.         if (szTitle && *szTitle)
  145.         SetWindowText (hwnd, szTitle);
  146.  
  147.         /* Set text on <OK> button according to mode (File/Open or File/Save) */
  148.         if (flags & OF_SAVE)
  149.         SetDlgItemText (hwnd, IDOK, "&Save");
  150.         if (flags & OF_OPEN)
  151.         SetDlgItemText (hwnd, IDOK, "&Open");
  152.  
  153.         if ((flags & OF_NOOPTIONS) &&
  154.         (hwndT = GetDlgItem(hwnd,DLGOPEN_FOLDOUT)))
  155.         EnableWindow (hwndT,FALSE);
  156.  
  157.         if (hwndT = GetDlgItem (hwnd, DLGOPEN_SMALL)) {
  158.         GetWindowRect (hwnd,&rc);
  159.         GetWindowRect (GetDlgItem(hwnd,DLGOPEN_SMALL),&rcCtl);
  160.  
  161.         SetWindowPos (hwnd,
  162.                   NULL,
  163.                   0,
  164.                   0,
  165.                   rcCtl.left - rc.left,
  166.                   rc.bottom - rc.top,
  167.                   SWP_NOZORDER | SWP_NOMOVE);
  168.         }
  169.         /* fill list box with filenames that match specifications, and
  170.          * fill static field with path name.
  171.          */
  172.         FillListBox(hwnd,szExt);
  173.  
  174.         /* If in Save mode, set the edit control with default (current)
  175.          * file name,and select the corresponding entry in the listbox.
  176.          */
  177.         if ((flags & OF_SAVE) && *szFileName) {
  178.         SetDlgItemText (hwnd, DLGOPEN_EDIT, szFileName);
  179.         SendDlgItemMessage (hwnd,
  180.                     DLGOPEN_FILE_LISTBOX,
  181.                     LB_SELECTSTRING,
  182.                     0,
  183.                     (LONG)(LPSTR)szFileName);
  184.         }
  185.         else {
  186.         /*  Set the edit field with the default extensions... */
  187.         if (flags & OF_NOSHOWSPEC)
  188.             SetDlgItemText (hwnd, DLGOPEN_EDIT, "");
  189.         else
  190.             SetDlgItemText (hwnd, DLGOPEN_EDIT, szExt);
  191.         }
  192.         /*    ...and select all text in the edit field */
  193.         SendDlgItemMessage (hwnd, DLGOPEN_EDIT, EM_SETSEL, 0, 0x7FFF0000L);
  194.  
  195.         /*    check all options that are set */
  196.         for ( f = DLGOPEN_1BPP; f; f<<=1)
  197.         CheckDlgButton(hwnd, FID(f), fOpt & f);
  198.  
  199.         break;
  200.  
  201.     case WM_COMMAND:
  202.         w = wParam;
  203.         switch (w) {
  204.         case IDOK:
  205.             if (IsWindowEnabled (GetDlgItem(hwnd, IDOK))) {
  206.             /* Get contents of edit field and add search spec. if it
  207.              * does not contain one.
  208.              */
  209.             GetDlgItemText (hwnd, DLGOPEN_EDIT, (LPSTR)szFileName, 128);
  210.  
  211.             w = lstrlen(szFileName)-1;
  212.             c = szFileName[w];
  213.             switch (c) {
  214.                 case '\\':
  215.                 case '/':
  216.                 szFileName[w] = 0;
  217.                 break;
  218.             }
  219.             if (chdir ((LPSTR)szFileName))
  220.                 lstrcpy (szFileName,szExt);
  221.  
  222.             /*  Try to open path.  If successful, fill listbox with
  223.              *  contents of new directory.    Otherwise, open datafile.
  224.              */
  225.             if (FSearchSpec(szFileName)) {
  226.                 lstrcpy (szExt, FillListBox (hwnd, szFileName));
  227.                 if (flags & OF_NOSHOWSPEC)
  228.                 SetDlgItemText (hwnd, DLGOPEN_EDIT, "");
  229.                 else
  230.                 SetDlgItemText (hwnd, DLGOPEN_EDIT, szExt);
  231.                 break;
  232.             }
  233.  
  234.             /*  Make filename upper case and if it's a legal DOS
  235.              *  name, try to open the file.
  236.              */
  237.             AnsiUpper(szFileName);
  238.             AddExt(szFileName,szExt);
  239.             result = OpenFile(szFileName, &of, (WORD)flags);
  240.  
  241.             if (result != -1) {
  242.                 lstrcpy(szFileName,of.szPathName);
  243.             }
  244.             else if (flags & OF_MUSTEXIST) {
  245.                 MessageBeep(0);
  246.                 return 0L;
  247.             }
  248.  
  249.             /*  Get the state of all checked options */
  250.             for (f = DLGOPEN_1BPP; f; f <<= 1){
  251.                 if (IsDlgButtonChecked (hwnd, FID (f)))
  252.                 fOpt |= f;
  253.                 else
  254.                 fOpt &= ~f;
  255.             }
  256.  
  257.             EndDialog (hwnd, result);
  258.             }
  259.             break;
  260.  
  261.         case DLGOPEN_OPTION + DLGOPEN_RLE4:
  262.         case DLGOPEN_OPTION + DLGOPEN_RLE8:
  263.         case DLGOPEN_OPTION + DLGOPEN_RGB:
  264.             /* Mask out incompatible bitcount options and gray the
  265.              * appropriate radiobuttons.
  266.              */
  267.             for (f = DLGOPEN_1BPP; f <= DLGOPEN_24BPP; f <<= 1){
  268.             fEnable = !(f & BITCOUNTMASK [IDF(w) >> 4 ]);
  269.             EnableWindow (GetDlgItem (hwnd, FID(f)), fEnable);
  270.  
  271.             /* If the radiobutton is being grayed, uncheck it and
  272.              * and check an "allowed" option so the bitcount group
  273.              * is still accessible via the keyboard
  274.              */
  275.             if (!fEnable && IsDlgButtonChecked (hwnd, FID (f))){
  276.                 CheckDlgButton(hwnd, FID(f), FALSE);
  277.                 CheckDlgButton(hwnd, FID(IDF(w) >> 3), TRUE);
  278.             }
  279.             }
  280.             break;
  281.  
  282.         case IDCANCEL:
  283.             /* User pressed cancel.  Just take down dialog box. */
  284.             EndDialog (hwnd, 0);
  285.             break;
  286.  
  287.         /*  User single clicked or doubled clicked in listbox -
  288.          *  Single click means fill edit box with selection.
  289.          *  Double click means go ahead and open the selection.
  290.          */
  291.         case DLGOPEN_FILE_LISTBOX:
  292.         case DLGOPEN_DIR_LISTBOX:
  293.  
  294.             switch (HIWORD(lParam)) {
  295.             /* Single click case */
  296.             case 1:
  297.                 /* Get selection, which may be either a prefix to a
  298.                  * new search path or a filename. DlgDirSelect parses
  299.                  * selection, and appends a backslash if selection
  300.                  * is a prefix
  301.                  */
  302.                 DlgDirSelect(hwnd,szFileName,wParam);
  303.                 w = lstrlen(szFileName)-1;
  304.                 c = szFileName[w];
  305.                 switch (c) {
  306.                 case ':':
  307.                     lstrcat (szFileName,".");
  308.                     break;
  309.                 case '\\':
  310.                 case '/':
  311.                     szFileName[w] = 0;
  312.                     break;
  313.                 }
  314.                 SetDlgItemText(hwnd, DLGOPEN_EDIT, szFileName);
  315.                 break;
  316.             /* Double click case - first click has already been
  317.              * processed as single click
  318.              */
  319.             case 2:
  320.                 PostMessage (hwnd,WM_COMMAND,IDOK,0L);
  321.                 break;
  322.             }
  323.             break;
  324.  
  325.         case DLGOPEN_EDIT:
  326.             DlgCheckOkEnable(hwnd, DLGOPEN_EDIT, HIWORD(lParam));
  327.             break;
  328.  
  329.         case DLGOPEN_FOLDOUT:
  330.             GetWindowRect(hwnd,&rc);
  331.             GetWindowRect(GetDlgItem(hwnd,DLGOPEN_BIG),&rcCtl);
  332.  
  333.             if ((rcCtl.left <= rc.right) && (rcCtl.top <= rc.bottom))
  334.              GetWindowRect (GetDlgItem (hwnd, DLGOPEN_SMALL), &rcCtl);
  335.  
  336.             SetWindowPos (hwnd,
  337.                   NULL,
  338.                   0,
  339.                   0,
  340.                   rcCtl.left - rc.left,
  341.                   rc.bottom - rc.top,
  342.                   SWP_NOZORDER | SWP_NOMOVE);
  343.             break;
  344.         }
  345.     default:
  346.         return FALSE;
  347.     }
  348.     return TRUE;
  349. }
  350.  
  351. /****************************************************************************
  352.  *                                        *
  353.  *  FUNCTION   : static void NEAR DlgCheckOkEnable(hwnd, idEdit, message)   *
  354.  *                                        *
  355.  *  PURPOSE    : Enables the <OK> button in a dialog box iff the edit item  *
  356.  *         contains text.                         *
  357.  *                                        *
  358.  ****************************************************************************/
  359. static void NEAR DlgCheckOkEnable(hwnd, idEdit, message)
  360.  
  361. HWND    hwnd;
  362. int    idEdit;
  363. unsigned message;
  364. {
  365.     if (message == EN_CHANGE) {
  366.     EnableWindow ( GetDlgItem (hwnd, IDOK),
  367.                (BOOL)SendMessage (GetDlgItem (hwnd, idEdit),
  368.                       WM_GETTEXTLENGTH,
  369.                       0, 0L));
  370.     }
  371. }
  372.  
  373. /****************************************************************************
  374.  *                                        *
  375.  *  FUNCTION   : AddExt (pch, ext)                        *
  376.  *                                        *
  377.  *  PURPOSE    : Add an extension to a filename if none is already specified*
  378.  *                                        *
  379.  ****************************************************************************/
  380. static void NEAR AddExt (pch,ext)
  381.  
  382. char *pch;    /* File name      */
  383. char *ext;    /* Extension to add */
  384. {
  385.     char acExt[20];
  386.     char *pext = acExt;
  387.  
  388.     while (*ext && *ext != '.')
  389.     ext++;
  390.     while (*ext && *ext != ';')
  391.     *pext++ = *ext++;
  392.     *pext = 0;
  393.     pext = acExt;
  394.  
  395.     while (*pch == '.') {
  396.     pch++;
  397.     if ((*pch == '.') && pch[1] == '\\')
  398.         pch += 2;                /* ..\ */
  399.     if (*pch == '\\')
  400.         pch++;               /* .\ */
  401.     }
  402.     while (*pch != '\0')
  403.     if (*pch++ == '.')
  404.         return;
  405.  
  406.     // *pch++ = '.';
  407.     do
  408.     *pch++ = *pext;
  409.     while (*pext++ != '\0');
  410. }
  411. /****************************************************************************
  412.  *                                        *
  413.  *  FUNCTION   : FSearchSpec (sz)                        *
  414.  *                                        *
  415.  *  PURPOSE    : Checks to see if NULL-terminated strings contains a "*" or *
  416.  *         a "?".                             *
  417.  *                                        *
  418.  *  RETURNS    : TRUE  - if the above characters are found in the string    *
  419.  *         FALSE - otherwise.                        *
  420.  *                                        *
  421.  ****************************************************************************/
  422. static BOOL NEAR FSearchSpec(sz)
  423. char    *sz;
  424. {
  425.     for (; *sz ;sz++) {
  426.     if (*sz == '*' || *sz == '?')
  427.         return TRUE;
  428.     }
  429.     return FALSE;
  430. }
  431.  
  432. /****************************************************************************
  433.  *                                        *
  434.  *  FUNCTION   : static char * NEAR FillListBox (hDlg,pFile)            *
  435.  *                                        *
  436.  *  PURPOSE    : Fill list box with filenames that match specifications, and*
  437.  *         fills the static field with the path name.            *
  438.  *                                        *
  439.  *  RETURNS    : A pointer to the pathname.                                  *
  440.  *                                        *
  441.  ****************************************************************************/
  442. static char * NEAR FillListBox (hDlg,pFile)
  443.  
  444. HWND  hDlg;
  445. char  *pFile;  /* [path]{list of file wild cards, separated by ';'} */
  446. {
  447.     char  ach[20];
  448.     char  *pch;
  449.     char  *pDir;   /* Directory name or path */
  450.  
  451.     pch  = pFile;
  452.     pDir = ach;
  453.  
  454.     while (*pch && *pch != ';')
  455.     pch++;
  456.     while ((pch > pFile) && (*pch != '/') && (*pch != '\\'))
  457.     pch--;
  458.     if (pch > pFile) {
  459.        *pch = 0;
  460.        lstrcpy (pDir, pFile);
  461.        pFile = pch + 1;
  462.     }
  463.     else {
  464.        lstrcpy (pDir,".");
  465.     }
  466.  
  467.     DlgDirList (hDlg, pDir, DLGOPEN_DIR_LISTBOX, DLGOPEN_PATH,ATTRDIRLIST);
  468.     SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, LB_RESETCONTENT, 0, 0L);
  469.     SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, FALSE, 0L);
  470.     pDir = pFile;         /* save pFile to return */
  471.     while (*pFile) {
  472.     pch = ach;
  473.     while (*pFile==' ')
  474.         pFile++;
  475.     while (*pFile && *pFile != ';')
  476.         *pch++ = *pFile++;
  477.     *pch = 0;
  478.     if (*pFile)
  479.         pFile++;
  480.     SendDlgItemMessage (hDlg,
  481.                 DLGOPEN_FILE_LISTBOX,
  482.                 LB_DIR,ATTRFILELIST,
  483.                 (LONG)(LPSTR)ach);
  484.     }
  485.     SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, TRUE, 0L);
  486.     InvalidateRect (GetDlgItem (hDlg, DLGOPEN_FILE_LISTBOX), NULL, TRUE);
  487.  
  488.     return pDir;
  489. }
  490.