home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
TOOLKIT
/
OS2
/
EAEDIT
/
EASFILE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-17
|
19KB
|
458 lines
/*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;
}