home *** CD-ROM | disk | FTP | other *** search
- /*static char *SCCSID = "@(#)easfile.c 6.13 92/03/18";*/
- /*==============================================================*\
- * *
- * EASFILE.C *
- * (C) Copyright IBM Corporation 1992. *
- *--------------------------------------------------------------*
- * This module contains subroutines for eas.c that specifically*
- * deal with the Open file interface. Most of the routines were*
- * taken from Charles Petzold's book "Programming the OS/2 *
- * Presentation Manager" and were slightly modified. *
- * *
- *--------------------------------------------------------------*
- * Procedures in this file: *
- * OpenFile() Asks user for new file name and opens it *
- * OpenFileProc() Dialog proc that prompts user file name *
- * FillDirListBox() Fills the directory list box *
- * FillFileListBox() Fills the file list box *
- * *
- \*==============================================================*/
- /*--------------------------------------------------------------*\
- * Include files, macros, defined constants, and externs *
- \*--------------------------------------------------------------*/
- #include "eas.h"
-
- extern EADATA ConvTable[EATABLESIZE];
-
- /****************************************************************\
- * *
- * Name: OpenFile(hwnd, usMode) *
- * *
- * Purpose: This routine handles opening a new file. It will *
- * also query the user for the disposition of the *
- * current file if it has been modified before loading*
- * the new file. *
- * *
- * Usage : This routine is called by MainDlgProc to deal with *
- * the Open file interface. *
- * *
- * Method : Routine should be bullet proof as it does its own *
- * error checking. It assumes that hwnd points to the*
- * correct window with the name listbox in it. *
- * *
- * Returns: TRUE if a file is open upon exit. *
- * *
- \****************************************************************/
- BOOL OpenFile(HWND hwnd, ULONG usMode)
- {
- CHAR szOldFile[CCHMAXPATH];
- HFILE FileHandle=0;
- ULONG ulAct=0L;
-
- strcpy(szOldFile,szFileName); /* Save name of the currently open file */
-
- if(usMode != ARGFILE) /* It isn't the command line file */
- {
- if(!WinDlgBox(HWND_DESKTOP, /* Get the file name from the user */
- hwnd,
- OpenFileProc,
- '\0',
- IDD_OPENBOX,
- NULL))
- {
- strcpy(szFileName,szOldFile); /* They canceled, restore old file */
- return(FILE_ISOPEN);
- }
- }
- /* Check filename availble or not */
- if( DosOpen(szFileName, &FileHandle, &ulAct, 0L, FILE_NORMAL,
- FILE_OPEN, OPEN_SHARE_DENYWRITE, NULL) )
- {
- MessageBox(hwnd, IDMSG_ERRORFILEOPEN, "Error !",
- MB_OK | MB_ERROR, TRUE);
- return(FILE_ISOPEN);
- }
- else /* File is existed and availble to use */
- DosClose(FileHandle);
-
- if(FILE_ISOPEN) /* Free up everything associated with the current file */
- {
- Free_FEAList(pHoldFEA,pDelList);
- FILE_ISOPEN = FALSE;
- }
-
- if(QueryEAs(szFileName)) /* We were successful */
- {
- HOLDFEA *pFEA=pHoldFEA;
-
- FILE_ISOPEN = TRUE;
- FILE_CHANGED = FALSE;
-
- WinSendDlgItemMsg(hwnd, IDD_WINLBOX, LM_DELETEALL,0L,0L); /* Fill L-box */
-
- while(pFEA)
- {
- WinSendDlgItemMsg(hwnd, IDD_WINLBOX, LM_INSERTITEM,
- MPFROM2SHORT(LIT_END,0),
- MPFROMP(pFEA->szName));
- pFEA = pFEA->next;
- }
- }
- else /* We couldn't query the EAs */
- {
- *szFileName = '\000';
- memset(szEAType, 0, sizeof(szEAType) );
- WinInvalidateRect(hwndMain, NULL, FALSE);
- FILE_ISOPEN = FALSE;
- return (FILE_ISOPEN);
- }
- memset(szEAType, 0, sizeof(szEAType) );
- WinInvalidateRect(hwndMain, NULL, FALSE);
- pDelList = NULL;
- return(TRUE);
- }
-
- /****************************************************************\
- * *
- * Name: OpenFileProc(hwnd, msg, mp1, mp2) *
- * *
- * Purpose: This proc handles the user interface to select a *
- * file name. Some elementary checks are done to make *
- * sure the filename is valid. *
- * *
- * Usage : This routine is called by OpenFile to open the file*
- * *
- * Method : The interface is NOT foolproof as it is possible to*
- * continue with a non-existant file name. Also, *
- * users are not currently allowed to view/edit the *
- * EAs attached to a directory. *
- * *
- * Returns: TRUE if selects OK, FALSE if Cancel is selected. *
- * *
- \****************************************************************/
- MRESULT EXPENTRY OpenFileProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- static CHAR szCurrentPath[CCHMAXPATH]={'.', '\\', '*', '\000'},
- szBuffer[CCHMAXPATH];
- CHAR szParsedPath[CCHMAXPATH];
- SHORT sSelect;
- MRESULT sRC;
-
- switch(msg)
- {
- case WM_INITDLG:
- FixSysMenu(hwnd);
- FillDirListBox(hwnd,szCurrentPath);
- FillFileListBox(hwnd);
- WinSendDlgItemMsg(hwnd, IDD_FILEEDIT,EM_SETTEXTLIMIT,
- MPFROM2SHORT(CCHMAXPATH,0),NULL);
- return (MRESULT)0L;
-
- case WM_CONTROL: /* An lbox item is selected */
- if(SHORT1FROMMP(mp1) == IDD_DIRLIST ||
- SHORT1FROMMP(mp1) == IDD_FILELIST)
- { /* Get item->szBuffer */
- sSelect = (USHORT) WinSendDlgItemMsg(hwnd,
- SHORT1FROMMP(mp1),
- LM_QUERYSELECTION, 0L, 0L);
-
- WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1),
- LM_QUERYITEMTEXT,
- MPFROM2SHORT(sSelect, sizeof(szBuffer)),
- MPFROMP(szBuffer));
- }
-
- switch(SHORT1FROMMP(mp1))
- {
- case IDD_DIRLIST: /* Item was in the directory lbox */
- switch(SHORT2FROMMP(mp1))
- {
- case LN_ENTER: /* Go to the select drive/dir */
- if(*szBuffer == ' ')
- DosSelectDisk(*(szBuffer+1) - '@');
- else
- DosSetCurrentDir(szBuffer);
-
- FillDirListBox(hwnd, szCurrentPath);
- FillFileListBox(hwnd);
-
- WinSetDlgItemText(hwnd, IDD_FILEEDIT, "");
- return (MRESULT)0L;
- }
- break;
-
- case IDD_FILELIST: /* Item was in the file lbox */
- switch(SHORT2FROMMP(mp1))
- {
- case LN_SELECT: /* Copy name to entry field */
- WinSetDlgItemText(hwnd, IDD_FILEEDIT, szBuffer);
- return (MRESULT)0L;
-
- case LN_ENTER: /* Try to query the file */
- if(ParseFileName(szFileName, szBuffer) != FILE_VALID)
- return 0; /* Some error, don't finish */
- WinDismissDlg(hwnd, TRUE);
- return (MRESULT)0L;
- }
- break;
- }
- break;
-
- case WM_COMMAND:
- switch(LOUSHORT(mp1))
- {
- case DID_OK: /* Try to query file in the entry field */
- memset(szBuffer, 0, sizeof(szBuffer) );
- WinQueryDlgItemText(hwnd, IDD_FILEEDIT,
- sizeof(szBuffer), szBuffer);
- /* Check filename availble or not */
- if(*szBuffer == '\000')
- {
- MessageBox(hwnd, IDMSG_NOFILEOPEN, "Error !",
- MB_OK | MB_ERROR, TRUE);
- return FALSE;
- }
- switch(ParseFileName(szParsedPath, szBuffer))
- {
- case FILE_INVALID: /* Can't open the file */
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- FillDirListBox(hwnd, szCurrentPath);
- FillFileListBox(hwnd);
- return (MRESULT)0L;
-
- case FILE_PATH: /* It was an incomplete path name */
- strcpy(szCurrentPath,szBuffer);
- FillDirListBox(hwnd, szCurrentPath);
- FillFileListBox(hwnd);
- WinSetDlgItemText(hwnd, IDD_FILEEDIT, "");
- return (MRESULT)0L;
-
- case FILE_VALID: /* It was valid */
- strcpy(szFileName, szParsedPath);
- WinDismissDlg(hwnd, TRUE);
- return (MRESULT)0L;
- }
- break;
-
- case DID_CANCEL:
- WinDismissDlg(hwnd, FALSE);
- return (MRESULT)0L;
- }
- break;
-
- case WM_CLOSE:
- WinDismissDlg(hwnd, FALSE);
- return (MRESULT)0L;
-
- }
- sRC = WinDefDlgProc(hwnd, msg, mp1, mp2);
- return sRC;
- }
-
- /****************************************************************\
- * *
- * Name: FillDirListBox(hwnd, pcCurrentPath) *
- * *
- * Purpose: This routine is called by OpenFileProc to fill in *
- * the directory list box *
- * *
- * Usage : This routine is called by OpenFileProc to fill the *
- * file list box. *
- * *
- * Method : Adequete error checking is NOT done on the return *
- * values of the system calls. Also, it is remotely *
- * possible that the calls to add to the list box *
- * could fail. *
- * *
- * Returns: VOID *
- * *
- \* **************************************************************/
- VOID FillDirListBox(HWND hwnd, CHAR *pcCurrentPath)
- {
- static CHAR szDrive [] = " :";
- FILEFINDBUF3 findbuf;
- HDIR hDir = HDIR_CREATE;
- SHORT sDrive;
- ULONG ulCurPathLen, ulDriveMap=0L, ulSearchCount = 1, ulDriveNum=0L;
-
- memset(&findbuf,0,sizeof(FILEFINDBUF) );
-
- DosQueryCurrentDisk(&ulDriveNum, &ulDriveMap);
- *pcCurrentPath = (CHAR) (ulDriveNum + '@');
- *(pcCurrentPath+1) = ':';
- *(pcCurrentPath+2) = '\\';
- ulCurPathLen = CCHMAXPATH;
- DosQueryCurrentDir(0L, pcCurrentPath + 3, &ulCurPathLen);
-
- WinSetDlgItemText(hwnd, IDD_PATH, pcCurrentPath);
- WinSendDlgItemMsg(hwnd, IDD_DIRLIST, LM_DELETEALL, NULL, NULL);
-
- for(sDrive = ('A'-'A'); sDrive <= ('Z'-'A'); sDrive++)
- {
- if(ulDriveMap & (1L << sDrive))
- {
- *(szDrive+1) = (CHAR) (sDrive + 'A');
-
- WinSendDlgItemMsg(hwnd, IDD_DIRLIST, LM_INSERTITEM,
- MPFROM2SHORT(LIT_END, 0),
- MPFROMP(szDrive));
- }
- }
- if (DosFindFirst("*", &hDir, FILE_DIRECTORY, &findbuf,
- sizeof(findbuf), &ulSearchCount, FIL_STANDARD))
- {
- DosBeep(500,110);
- return;
- }
- while(ulSearchCount)
- {
- if(findbuf.attrFile & 0x0010 &&
- (findbuf.achName[0] != '.' || findbuf.achName[1]))
-
- WinSendDlgItemMsg(hwnd, IDD_DIRLIST, LM_INSERTITEM,
- MPFROM2SHORT(LIT_SORTASCENDING, 0),
- MPFROMP(findbuf.achName));
-
- if(DosFindNext(hDir, &findbuf, sizeof(findbuf), &ulSearchCount))
- break;
- }
- return;
- }
-
- /****************************************************************\
- * *
- * Name: FillFileListBox(hwnd) *
- * *
- * Purpose: This routine is called by OpenFileProc to fill in *
- * the file list box with files in the current *
- * directory. *
- * *
- * Usage : This routine is called by OpenFileProc to fill the *
- * file list box. *
- * *
- * Method : Adequete error checking is NOT done on the return *
- * values of the system calls. Also, it is remotely *
- * possible that the calls to add to the list box *
- * could fail. *
- * *
- * Returns: VOID *
- * *
- \****************************************************************/
- VOID FillFileListBox(HWND hwnd)
- {
- FILEFINDBUF3 findbuf;
- HDIR hDir = HDIR_CREATE;
- ULONG ulSearchCount = 1; /* Read 1 entry at a time */
-
- memset(&findbuf,0,sizeof(FILEFINDBUF) );
- WinSendDlgItemMsg(hwnd, IDD_FILELIST, LM_DELETEALL, NULL, NULL);
-
- if (DosFindFirst("*", &hDir, FILE_NORMAL, &findbuf, sizeof(findbuf),
- &ulSearchCount,FIL_STANDARD))
- {
- DosBeep(700,110);
- return;
- }
- while(ulSearchCount)
- {
- WinSendDlgItemMsg(hwnd, IDD_FILELIST, LM_INSERTITEM,
- MPFROM2SHORT(LIT_SORTASCENDING, 0),
- MPFROMP(findbuf.achName));
-
- if(DosFindNext(hDir, &findbuf, sizeof(findbuf), &ulSearchCount))
- break;
- }
- return;
- }
-
- /****************************************************************\
- * *
- * Name: ParseFileName(pcOut, pcIn) *
- * *
- * Purpose: This routine changes drive and directory as per *
- * pcIn string. *
- * *
- * Usage: Note that pcOut is only valid if FILE_VALID is *
- * returned. In place of strupr(), a codepage should *
- * be fetched and DosCaseMap() should be used to allow*
- * for extended chars. This routine could use some *
- * cleanup work. *
- * *
- * Returns: FILE_INVALID if pcIn had invalid drive or no *
- * directory *
- * FILE_PATH if pcIn was empty or had just a path/ *
- * no file name. *
- * FILE_VALID if pcIn point to good file. *
- * *
- \****************************************************************/
- LONG ParseFileName(CHAR *pcOut, CHAR *pcIn)
- {
- CHAR *pcLastSlash, *pcFileOnly ;
- ULONG ulDriveMap, ulDirLen = CCHMAXPATH, ulDriveNum=0L;
-
- strupr(pcIn); /* Does NOT handle extended chars, should use DosCaseMap */
-
- if(*pcIn == '\000') /* If string is empty, return FILE_PATH */
-
- return FILE_PATH;
-
- /* Get drive from input string or use current drive */
- if(*(pcIn+1) == ':') /* Yup, they specified a drive */
- {
- if(DosSelectDisk(*pcIn - '@')) /* Change to selected drive */
- return FILE_INVALID;
- pcIn += 2;
- }
- DosQueryCurrentDisk(&ulDriveNum, &ulDriveMap); /* Get current drive */
- *pcOut++ = (CHAR) (ulDriveNum + '@'); /* Build drive letter */
- *pcOut++ = ':';
- *pcOut++ = '\\';
-
- if(*pcIn == '\000') /* If rest of the string is empty, return FILE_PATH */
- return FILE_PATH;
-
- /* Search for the last backslash. If none, it could be a directory. */
- if(!(pcLastSlash = strrchr(pcIn, '\\'))) /* No slashes? */
- {
- if(!DosSetCurrentDir(pcIn))
- return FILE_PATH; /* It was a directory */
- /* Get current dir & attach input fn */
- DosQueryCurrentDir(0L, pcOut, &ulDirLen);
-
- if(*(pcOut+strlen(pcOut)-1) != '\\')
- strcat(pcOut++, "\\");
-
- strcat(pcOut, pcIn);
- return FILE_VALID;
- }
- /* If the only backslash is at the beginning, change to root */
- if(pcIn == pcLastSlash)
- {
- DosSetCurrentDir("\\");
-
- if(*(pcIn+1) == '\000')
- return FILE_PATH;
-
- strcpy(pcOut, pcIn+1);
- return FILE_VALID;
- }
- /* Attempt to change directory -- Get current dir if OK */
- *pcLastSlash = '\0';
-
- if(DosSetCurrentDir(pcIn))
- return FILE_INVALID;
-
- DosQueryCurrentDir(0L, pcOut, &ulDirLen);
- /* Append input filename if any */
- pcFileOnly = pcLastSlash+1;
-
- if(*pcFileOnly == '\000')
- return FILE_PATH;
-
- if(*(pcOut+strlen(pcOut)-1) != '\\')
- strcat(pcOut++, "\\");
-
- strcat(pcOut, pcFileOnly);
- return FILE_VALID;
- }
-