home *** CD-ROM | disk | FTP | other *** search
- /* The routines in this file provide support for file access under the
- Microsoft Windows environment on an IBM-PC or compatible computer.
-
- Must be compiled with Borland C++ 2.0 or later version.
-
- It should not be compiled if the WINDOW_MSWIN symbol is not set */
-
- #include "estruct.h"
- #include <stdio.h>
- #include <dir.h>
- #include "eproto.h"
- #include "edef.h"
- #if TURBO
- #define malloc dummy_malloc
- #define realloc dummy_realloc
- #include <stdlib.h>
- #undef malloc
- #undef realloc
-
- struct ffblk fileblock; /* structure for directory searches */
- #endif
- #if MSC | ZTC
- #include <dos.h>
-
- struct find_t fileblock; /* structure for directory searches */
- #endif
-
- #include "mswin.h"
-
- /* macros */
- #define ATTR_DIR (0x4010 | 0x8000) /* attributes for dir listbox */
- #define ATTR_FIL (0x0021) /* attributes for file listbox */
-
- /* structures */
- typedef struct PARAMS { /* parameters between filenamedlg and
- FileDlgProc (pointed by Par) */
- char Name [13]; /* file name */
- char *Prompt; /* prompt text for the caption */
- } PARAMS;
-
- /* static variables */
- static char Path [NFILEN] = ""; /* directory path */
- static char StarName [13] = "*.*"; /* starname */
- static PARAMS *Par;
-
- /* function prototypes */
- int EXPORT far pascal FileDlgProc (HWND hDlg, WORD wMsg, WORD wParam,
- DWORD lParam);
- static void near CompletePath (char *s, char *FileName);
- static void near UpdateAll (HWND hDlg, char *s);
-
- /* ChangeWorkingDir: sets the working dir to match the supplied path */
- /* ================ */
-
- static int near ChangeWorkingDir (char * FilePath)
-
- /* returns 0 if successful, -1 otherwise */
- {
- char *WorkPath;
- char *Backslash; /* will find the last backslash in the path */
- char Crushed;
- int Result;
-
- WorkPath = FilePath;
- if (*WorkPath == '\0') return 0; /* empty path! */
- if (WorkPath[1] == ':') { /* drive specification */
- int disk;
-
- setdisk (disk = (tolower(*WorkPath) - 'a'));
- if (disk != getdisk ()) return -1;
- WorkPath += 2; /* skip that drive spec */
- }
-
- for (Backslash = WorkPath; *Backslash != '\0'; Backslash++) ;
- while (*Backslash != '\\') {
- if (Backslash == WorkPath) break;
- --Backslash;
- }
- /* Backslash now points at the last backslash in the file path. That
- is the end of the directory path */
- if ((Backslash == WorkPath) && (*Backslash == '\\')) ++Backslash;
- Crushed = *Backslash;
- *Backslash = '\0'; /* temporarily terminate the path there */
- if (*WorkPath == '\0') Result = TRUE;
- else Result = chdir (WorkPath);
- *Backslash = Crushed; /* restore the file path before returning */
- return Result;
- } /* ChangeWorkingDir */
-
- /* SetWorkingDir: sets the working dir to the current window's path */
- /* ============= */
-
- int far pascal SetWorkingDir (void)
-
- /* returns 0 if successful, -1 otherwise */
- /* this function also sets the text of the Path displayed in the FILE
- dialog */
- {
- int Result;
-
- Result = ChangeWorkingDir (curbp->b_fname);
- if (Result == 0) getcwd (Path, NFILEN);
- return Result;
- } /* SetWorkingDir */
-
- /* fullpathname: fully qualifies the given pathname */
- /* ============ */
-
- char * pascal fullpathname (char *PathName, int Nbuf)
-
- /* the PathName argument is assumed to be at least Nbuf characters
- long. It is modified to contain the corresponding full pathname. The
- returned address is the PathName argument. */
- {
- char FullName [_MAX_PATH];
-
- if (_fullpath(FullName, PathName, Nbuf) != NULL) {
- strcpy (PathName, FullName);
- }
- return PathName;
- } /* fullpathname */
-
- /* filenamedlg: equivalent of mlreply, but specifically to get a filename */
- /* =========== */
-
- PASCAL filenamedlg (char *prompt, char *buf, int nbuf, int fullpath)
- {
- PARAMS Parameters;
- FARPROC ProcInstance;
- BOOL Result;
-
- SetWorkingDir ();
- if (clexec || (kbdmode != STOP)) { /* not interactive */
- Result = mlreply (prompt, buf, nbuf);
- if (Result == TRUE) {
- if (fullpath) fullpathname (buf, nbuf);
- }
- return Result;
- }
- Parameters.Prompt = prompt;
- Par = &Parameters;
- ProcInstance = MakeProcInstance ((FARPROC)FileDlgProc, hEmacsInstance);
- if (Result = (DialogBox (hEmacsInstance, "FILE", hFrameWnd,
- ProcInstance) >= 0)) {
- CompletePath (buf, Parameters.Name);
- }
- FreeProcInstance (ProcInstance);
- SetWorkingDir ();
- return Result;
- } /* filenamedlg */
-
- /* FileDlgOK: process OK in File Dialog */
- /* ========= */
-
- static BOOL pascal near FileDlgOK (HWND hDlg)
-
- /* this is a service function for FileDlgProc. It processes the OK case.
- The returned value is TRUE if the dialog box is ending, FALSE
- otherwise */
- {
- char s [NFILEN];
-
- GetDlgItemText (hDlg, ID_FILENAME, s, NFILEN);
- if (*s == 0) return FALSE; /* empty name, ignore it! */
- if (strchr (s, '*') || strchr (s, '?')) {
- /* there is a starname here! */
- UpdateAll (hDlg, s);
- }
- else {
- int l;
- char *n;
-
- l = strlen (s);
- n = &s[l - 1];
- if ((*n == '\\') || (*n == ':')) {
- /* it is a directory or drive */
- if (l < NFILEN - 13) {
- strcat (s, StarName);
- UpdateAll (hDlg, s);
- }
- }
- else {
- /* it looks like a bonafide file name ! */
- int nl = 1;
-
- /* first, we extract the filename portion...*/
- do {
- if (n-- == &s[0]) goto ExtractedOK;
- if ((*n == ':') || (*n == '\\')) goto ExtractedOK;
- } while (++nl < 13);
- return FALSE;
- ExtractedOK:
- strcpy (Par->Name, ++n);
- if (&s[0] - n < NFILEN - 13) {
- strcpy (n, StarName);
- /* now, we use DlgDirList to generate the full directory
- path */
- if (DlgDirList (hDlg, s, NULL, ID_PATH, ATTR_FIL)) {
- GetDlgItemText (hDlg, ID_PATH, Path, NFILEN);
- EndDialog (hDlg, 0);
- return TRUE;
- }
- }
- }
- }
- return FALSE;
- } /* FileDlgOK */
-
- /* FileNameCompletion: process filename edit box for name completion */
- /* ================== */
-
- /* scrolls the file list box to bring the first match into view and
- attempt filename completion if a space is placed at the end of the
- edit field. Returns TRUE if filename completion was attempted and
- successful, FALSE otherwise. */
- static BOOL pascal near FileNameCompletion (HWND hDlg)
- {
- char s [NFILEN];
- int i;
- BOOL PleaseComplete = FALSE;
-
- i = GetDlgItemText (hDlg, ID_FILENAME, s, NFILEN);
- while ((i > 0) && (s[--i] == ' ')) {
- PleaseComplete = TRUE;
- s[i] = '\0';
- }
- if (PleaseComplete) {
- DWORD LastSel;
-
- LastSel = SendDlgItemMessage (hDlg, ID_FILENAME, EM_GETSEL, 0, 0L);
- SetDlgItemText (hDlg, ID_FILENAME, s); /* remove the spaces */
- SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL, 0, LastSel);
- }
- if (strchr (s, '\\') || strchr (s, ':') || strchr (s, '[')) {
- return FALSE; /* contains more than a plain file name. The
- file list box will not be appropriate for
- completion so we do not attempt anything */
- }
- i = LOWORD(SendDlgItemMessage (hDlg, ID_FILES, LB_SELECTSTRING,
- -1, (DWORD)(LPSTR)&s[0]));
- if (i == LB_ERR) {
- /* no match, give up! */
- return FALSE;
- }
- SendDlgItemMessage (hDlg, ID_FILES, LB_SETTOPINDEX, i, 0L);
- if (PleaseComplete) {
- if (i != LOWORD(SendDlgItemMessage (hDlg, ID_FILES, LB_FINDSTRING,
- i, (DWORD)(LPSTR)&s[0]))) {
- return FALSE; /* not unique ==> completion fails */
- }
- else {
- SendDlgItemMessage (hDlg, ID_FILES, LB_GETTEXT,
- i, (DWORD)(LPSTR)&s[0]);
- SetDlgItemText (hDlg, ID_FILENAME, s);
- return TRUE;
- }
- }
- return FALSE;
- } /* FileNameCompletion */
-
- /* FileDlgProc: Open file dialog function */
- /* =========== */
- int EXPORT far pascal FileDlgProc (HWND hDlg, WORD wMsg, WORD wParam,
- DWORD lParam)
- {
- char s [NFILEN]; /* all purpose */
- int i;
-
- switch (wMsg) {
-
- case WM_INITDIALOG:
- { /* let's build the caption */
- char DlgTitle [sizeof(PROGNAME) + 3 + 30];
-
- strcpy (DlgTitle, ProgName);
- strcat (DlgTitle, " - ");
- strcat (DlgTitle, Par->Prompt); /* hopefully, the prompt is
- under 30 char! */
- i = strlen (DlgTitle) - 1;
- while (DlgTitle[i] == ' ') i--;
- if (DlgTitle[i] == ':') DlgTitle[i] = 0;
- /* we remove the colon+spaces at the end of the prompt */
- SetWindowText (hDlg, DlgTitle);
- }
- SetFocus (GetDlgItem (hDlg, ID_FILENAME));
- CompletePath (s, StarName);
- UpdateAll (hDlg, s);
- i = 0;
- while (in_check()) {
- /* we need to send to the dialog box the characters stored
- into the in_put() buffer. For instance, if the user typed
- ^X^F while the startup script was running (to specify the
- first file to read in) and quickly followed this by
- typing a file name. The Find file dialog box would not
- receive those characters which would already have been
- absorbed into the in_put() pipe and would later end up
- inserted at the beginning of the buffer! */
- int c;
-
- c = in_get();
- switch (c) {
- case 0: /* escape sequence, discard it... */
- if (in_get() & (MOUS >> 8)) {
- in_get();
- in_get();
- }
- in_get();
- break;
- case '\b': /* backspace */
- if (i > 0) i--;
- break;
- case '\r': /* Enter */
- s[i] = '\0';
- SetDlgItemText (hDlg, ID_FILENAME, s);
- if (FileDlgOK (hDlg)) goto NoMoreTypeAhead;
- break;
- case 0x1B: /* Escape */
- EndDialog (hDlg, -1);
- goto NoMoreTypeAhead;
- default:
- if ((c > 0x1F) && (c < 0x7F)) {
- /* regular ASCII char, stuff it into the filename */
- s[i++] = c;
- }
- /* else, discard it */
- break;
- }
- }
- if (i > 0) {
- s[i] = '\0';
- SetDlgItemText (hDlg, ID_FILENAME, s);
- SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL, 0,
- MAKELONG(i, i));
- }
- else {
- SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL, 0,
- MAKELONG(0, 32767));
- }
- if (FileNameCompletion (hDlg)) FileDlgOK (hDlg);
- NoMoreTypeAhead:
- return FALSE;
-
- case WM_COMMAND:
- switch (wParam) {
-
- case ID_FILENAME:
- if (HIWORD(lParam) == EN_CHANGE) {
- if (FileNameCompletion (hDlg)) FileDlgOK (hDlg);
- }
- break;
-
- case ID_DIRECTORIES:
- switch (HIWORD(lParam)) {
- case LBN_SELCHANGE:
- DlgDirSelect (hDlg, s, ID_DIRECTORIES);
- strcat (s, StarName);
- SetDlgItemText (hDlg, ID_FILENAME, s);
- break;
- case LBN_DBLCLK:
- FileDlgOK (hDlg); /* same as OK */
- }
- break;
-
- case ID_FILES:
- switch (HIWORD(lParam)) {
- case LBN_SELCHANGE:
- DlgDirSelect (hDlg, s, ID_FILES);
- i = strlen (s) - 1;
- if (s[i] == '.') s[i] = 0; /* zap dot at end of file
- name */
- SetDlgItemText (hDlg, ID_FILENAME, s);
- break;
- case LBN_DBLCLK:
- FileDlgOK (hDlg); /* same as OK */
- }
- break;
-
- case IDOK:
- FileDlgOK (hDlg);
- break;
-
- case IDCANCEL:
- EndDialog (hDlg, -1);
- break;
- }
- break;
-
- default:
- return FALSE;
- }
- return FALSE;
- } /* FileDlgProc */
-
- /* CompletePath: prepend Path to the FileName, result in s */
- /* ============ */
-
- static void near CompletePath (char *s, char *FileName)
-
- /* s must be at least NFILEN characters long, while the length of Path +
- the length of FileName must be < NFILEN */
- {
- strcpy (s, Path);
- if ((*s != 0) && (s[strlen (s) - 1] != '\\')) strcat (s, "\\");
- strcat (s, FileName);
- } /* CompletePath */
-
- /* UpdateAll: updates all the controls from the path in s */
- /* ========= */
-
- static void near UpdateAll (HWND hDlg, char *s)
-
- /* this function also keeps the static variables Path and StarName up to
- date */
- {
- if (DlgDirList (hDlg, s, ID_DIRECTORIES, ID_PATH, ATTR_DIR)) {
- GetDlgItemText (hDlg, ID_PATH, Path, NFILEN);
- strcpy (StarName, s);
- DlgDirList (hDlg, s, ID_FILES, NULL, ATTR_FIL);
- SetDlgItemText (hDlg, ID_FILENAME, StarName);
- SendDlgItemMessage (hDlg, ID_FILENAME, EM_SETSEL, 0,
- MAKELONG(0, 32767));
- }
- } /* UpdateAll */
-
- #if TURBO
- /* FILE Directory routines */
- /* all borrowed from MSDOS.C */
-
- char path[NFILEN]; /* path of file to find */
- char rbuf[NFILEN]; /* return file buffer */
-
- /* do a wild card directory search (for file name completion) */
-
- char *pascal getffile(fspec)
-
- char *fspec; /* pattern to match */
-
- {
- register int index; /* index into various strings */
- register int point; /* index into other strings */
- register int extflag; /* does the file have an extention? */
- char fname[NFILEN]; /* file/path for DOS call */
-
- /* first parse the file path off the file spec */
- strcpy(path, fspec);
- index = strlen(path) - 1;
- while (index >= 0 && (path[index] != '/' &&
- path[index] != '\\' && path[index] != ':'))
- --index;
- path[index+1] = 0;
-
- /* check for an extension */
- point = strlen(fspec) - 1;
- extflag = FALSE;
- while (point > index) {
- if (fspec[point] == '.') {
- extflag = TRUE;
- break;
- }
- point--;
- }
-
- /* construct the composite wild card spec */
- strcpy(fname, path);
- strcat(fname, &fspec[index+1]);
- strcat(fname, "*");
- if (extflag == FALSE)
- strcat(fname, ".*");
-
- /* and call for the first file */
- if (findfirst(fname, &fileblock, FA_DIREC) == -1)
- return(NULL);
-
- /* return the first file name! */
- strcpy(rbuf, path);
- strcat(rbuf, fileblock.ff_name);
- mklower(rbuf);
- if (fileblock.ff_attrib == 16)
- strcat(rbuf, DIRSEPSTR);
- return(rbuf);
- }
-
- char *pascal getnfile()
-
- {
- register int index; /* index into various strings */
- register int point; /* index into other strings */
- register int extflag; /* does the file have an extention? */
- char fname[NFILEN]; /* file/path for DOS call */
-
- /* and call for the first file */
- if (findnext(&fileblock) == -1)
- return(NULL);
-
- /* return the first file name! */
- strcpy(rbuf, path);
- strcat(rbuf, fileblock.ff_name);
- mklower(rbuf);
- if (fileblock.ff_attrib == 16)
- strcat(rbuf, DIRSEPSTR);
- return(rbuf);
- }
- #else
- #if MSC | ZTC
- /* FILE Directory routines */
-
- char path[NFILEN]; /* path of file to find */
- char rbuf[NFILEN]; /* return file buffer */
-
- /* do a wild card directory search (for file name completion) */
-
- char *pascal getffile(fspec)
-
- char *fspec; /* pattern to match */
-
- {
- register int index; /* index into various strings */
- register int point; /* index into other strings */
- register int extflag; /* does the file have an extention? */
- char fname[NFILEN]; /* file/path for DOS call */
-
- /* first parse the file path off the file spec */
- strcpy(path, fspec);
- index = strlen(path) - 1;
- while (index >= 0 && (path[index] != '/' &&
- path[index] != '\\' && path[index] != ':'))
- --index;
- path[index+1] = 0;
-
- /* check for an extension */
- point = strlen(fspec) - 1;
- extflag = FALSE;
- while (point > index) {
- if (fspec[point] == '.') {
- extflag = TRUE;
- break;
- }
- point--;
- }
-
- /* construct the composite wild card spec */
- strcpy(fname, path);
- strcat(fname, &fspec[index+1]);
- strcat(fname, "*");
- if (extflag == FALSE)
- strcat(fname, ".*");
-
- /* and call for the first file */
- if (_dos_findfirst(fname, _A_NORMAL|_A_SUBDIR, &fileblock) != 0)
- return(NULL);
-
- /* return the first file name! */
- strcpy(rbuf, path);
- strcat(rbuf, fileblock.name);
- mklower(rbuf);
- if (fileblock.attrib == 16)
- strcat(rbuf, DIRSEPSTR);
- return(rbuf);
- }
-
- char *pascal getnfile()
-
- {
- register int index; /* index into various strings */
- register int point; /* index into other strings */
- register int extflag; /* does the file have an extention? */
- char fname[NFILEN]; /* file/path for DOS call */
-
- /* and call for the first file */
- if (_dos_findnext(&fileblock) != 0)
- return(NULL);
-
- /* return the first file name! */
- strcpy(rbuf, path);
- strcat(rbuf, fileblock.name);
- mklower(rbuf);
- if (fileblock.attrib == 16)
- strcat(rbuf, DIRSEPSTR);
- return(rbuf);
- }
- #else
- char *pascal getffile(fspec)
-
- char *fspec; /* file to match */
-
- {
- return(NULL);
- }
-
- char *pascal getnfile()
-
- {
- return(NULL);
- }
- #endif
- #endif
-
-