|
|
1.1 ! root 1: /************************************************************* ! 2: ! 3: This module contains subroutines for nead.c that specifically ! 4: deal with the Open file interface. Most of the routines were ! 5: taken from Charles Petzold's book "Programming the OS/2 ! 6: Presentation Manager" and were slightly modified. ! 7: ! 8: Procedures in this file: ! 9: OpenFile() Asks user for new file name and opens it ! 10: OpenFileProc() Dialog proc that prompts user for file name ! 11: FillDirListBox() Fills the directory list box ! 12: FillFileListBox() Fills the file list box ! 13: ! 14: **************************************************************/ ! 15: #include "nead.h" ! 16: ! 17: /************ External GLOBALS *******************************/ ! 18: ! 19: extern CHAR szFileName[CCHMAXPATH]; ! 20: extern CHAR szEAName[MAXEANAME+1]; ! 21: extern USHORT usRetEAType; ! 22: extern BOOL FILE_ISOPEN; ! 23: extern BOOL FILE_CHANGED; ! 24: extern BOOL COMMAND_LINE_FILE; ! 25: extern CHAR *pAlloc,*szEditBuf,*szAscii,*szScratch; ! 26: extern HOLDFEA *pHoldFEA; ! 27: extern DELETELIST *pDelList; ! 28: extern EADATA ConvTable[EATABLESIZE]; ! 29: ! 30: /*************************************************************/ ! 31: ! 32: ! 33: /* ! 34: * Function name: OpenFile() ! 35: * ! 36: * Parameters: hwnd which is the current window handle. ! 37: * usMode which will attempt to load the file from the command ! 38: * line iff usMode == ARGFILE which is set in main(). Otherwise, ! 39: * the selector box is brought up for the user to select from. ! 40: * ! 41: * Returns: TRUE iff a file is open upon exit. ! 42: * ! 43: * Purpose: This routine handles opening a new file. It will also query the ! 44: * user for the disposition of the current file if it has been ! 45: * modified before loading the new file. ! 46: * ! 47: * Usage/Warnings: Routine should be bullet proof as it does its own ! 48: * error checking. It assumes that hwnd points to the ! 49: * correct window with the name listbox in it. ! 50: * ! 51: * Calls: WriteEAs(), Free_FEAList() ! 52: */ ! 53: ! 54: BOOL OpenFile(HWND hwnd,USHORT usMode) ! 55: { ! 56: CHAR szOldFile[CCHMAXPATH]; ! 57: USHORT usRet; ! 58: ! 59: strcpy(szOldFile,szFileName); /* Save name of the currently open file */ ! 60: ! 61: if(usMode != ARGFILE) /* It isn't the command line file */ ! 62: { ! 63: if(!WinDlgBox(HWND_DESKTOP, /* Get the file name from the user */ ! 64: hwnd, ! 65: OpenFileProc, ! 66: NULL, ! 67: IDD_OPENBOX, ! 68: NULL)) ! 69: { ! 70: strcpy(szFileName,szOldFile); /* They canceled, restore old file */ ! 71: return(FILE_ISOPEN); ! 72: } ! 73: } ! 74: ! 75: if(FILE_CHANGED) /* Give them a chance to save modifications */ ! 76: { ! 77: usRet=WinMessageBox(HWND_DESKTOP,hwnd, ! 78: "The current file has been changed. Do you \ ! 79: wish to save the changes before proceeding?", ! 80: "Warning",NULL,MB_YESNOCANCEL | MB_ICONQUESTION); ! 81: switch(usRet) ! 82: { ! 83: case MBID_YES: ! 84: WriteEAs(); ! 85: break; ! 86: case MBID_CANCEL: ! 87: return FILE_ISOPEN; ! 88: } ! 89: } ! 90: ! 91: if(FILE_ISOPEN) /* Free up everything associated with the current file */ ! 92: { ! 93: Free_FEAList(pHoldFEA,pDelList); ! 94: FILE_ISOPEN = FALSE; ! 95: } ! 96: ! 97: if(QueryEAs(szFileName)) /* We were successful */ ! 98: { ! 99: HOLDFEA *pFEA=pHoldFEA; ! 100: ! 101: FILE_ISOPEN = TRUE; ! 102: FILE_CHANGED = FALSE; ! 103: ! 104: WinSendDlgItemMsg(hwnd, IDD_LBOX, LM_DELETEALL,0L,0L); /* Fill L-box */ ! 105: ! 106: while(pFEA) ! 107: { ! 108: WinSendDlgItemMsg(hwnd, IDD_LBOX, LM_INSERTITEM, ! 109: MPFROM2SHORT(LIT_END,0), ! 110: MPFROMP(pFEA->szName)); ! 111: pFEA = pFEA->next; ! 112: } ! 113: } ! 114: else /* We couldn't query the EAs */ ! 115: { ! 116: *szFileName = '\000'; ! 117: WinSetDlgItemText(hwnd,IDD_FNAME,szFileName); ! 118: return(FILE_ISOPEN = FALSE); ! 119: } ! 120: WinSetDlgItemText(hwnd,IDD_FNAME,szFileName); ! 121: pDelList = NULL; ! 122: return(TRUE); ! 123: } ! 124: ! 125: ! 126: /* ! 127: * Function name: OpenFileProc() ! 128: * ! 129: * Parameters: hwnd, msg, mp1, mp2. Standard PM Dialog Proc params. ! 130: * Expects no user pointer. ! 131: * ! 132: * Returns: TRUE if user selects OK, FALSE if Cancel is selected. ! 133: * ! 134: * Purpose: This proc handles the user interface to select a file name. ! 135: * Some elementary checks are done to make sure the filename is ! 136: * valid. ! 137: * ! 138: * Usage/Warnings: The interface is NOT foolproof as it is possible to ! 139: * continue with a non-existant file name. Also, users ! 140: * are not currently allowed to view/edit the EAs attached ! 141: * to a directory. ! 142: * ! 143: * Calls: FillDirListBox(), FillFileListBox(), ParseFileName() ! 144: */ ! 145: ! 146: MRESULT EXPENTRY OpenFileProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) ! 147: { ! 148: static CHAR szCurrentPath[CCHMAXPATH]={'.', '\\', '*', '\000'}, ! 149: szBuffer[CCHMAXPATH]; ! 150: CHAR szParsedPath[CCHMAXPATH]; ! 151: SHORT sSelect; ! 152: ! 153: switch(msg) ! 154: { ! 155: case WM_INITDLG: ! 156: FillDirListBox(hwnd,szCurrentPath); ! 157: FillFileListBox(hwnd); ! 158: WinSendDlgItemMsg(hwnd, IDD_FILEEDIT,EM_SETTEXTLIMIT, ! 159: MPFROM2SHORT(CCHMAXPATH,0),NULL); ! 160: return 0L; ! 161: ! 162: case WM_CONTROL: ! 163: if(SHORT1FROMMP(mp1) == IDD_DIRLIST || /* An lbox item is selected */ ! 164: SHORT1FROMMP(mp1) == IDD_FILELIST) ! 165: { ! 166: sSelect = (USHORT) WinSendDlgItemMsg(hwnd, /* Get item->szBuffer */ ! 167: SHORT1FROMMP(mp1), ! 168: LM_QUERYSELECTION, 0L, 0L); ! 169: ! 170: WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1), ! 171: LM_QUERYITEMTEXT, ! 172: MPFROM2SHORT(sSelect, sizeof(szBuffer)), ! 173: MPFROMP(szBuffer)); ! 174: } ! 175: ! 176: switch(SHORT1FROMMP(mp1)) ! 177: { ! 178: case IDD_DIRLIST: /* Item was in the directory lbox */ ! 179: switch(SHORT2FROMMP(mp1)) ! 180: { ! 181: case LN_ENTER: /* Go to the select drive/dir */ ! 182: if(*szBuffer == ' ') ! 183: DosSelectDisk(*(szBuffer+1) - '@'); ! 184: else ! 185: DosChDir(szBuffer); ! 186: ! 187: FillDirListBox(hwnd, szCurrentPath); ! 188: FillFileListBox(hwnd); ! 189: ! 190: WinSetDlgItemText(hwnd, IDD_FILEEDIT, ""); ! 191: return 0L; ! 192: } ! 193: break; ! 194: ! 195: case IDD_FILELIST: /* Item was in the file lbox */ ! 196: switch(SHORT2FROMMP(mp1)) ! 197: { ! 198: case LN_SELECT: /* Copy name to entry field */ ! 199: WinSetDlgItemText(hwnd, IDD_FILEEDIT, szBuffer); ! 200: return 0L; ! 201: ! 202: case LN_ENTER: /* Try to query the file */ ! 203: if(ParseFileName(szFileName, szBuffer) != FILE_VALID) ! 204: return 0; /* Some error, don't finish */ ! 205: WinDismissDlg(hwnd, TRUE); ! 206: return 0L; ! 207: } ! 208: break; ! 209: } ! 210: break; ! 211: ! 212: case WM_COMMAND: ! 213: switch(LOUSHORT(mp1)) ! 214: { ! 215: case DID_OK: /* Try to query file in the entry field */ ! 216: WinQueryDlgItemText(hwnd, IDD_FILEEDIT, ! 217: sizeof(szBuffer), szBuffer); ! 218: ! 219: switch(ParseFileName(szParsedPath, szBuffer)) ! 220: { ! 221: case FILE_INVALID: /* Can't open the file */ ! 222: WinAlarm(HWND_DESKTOP, WA_ERROR); ! 223: FillDirListBox(hwnd, szCurrentPath); ! 224: FillFileListBox(hwnd); ! 225: return 0L; ! 226: ! 227: case FILE_PATH: /* It was an incomplete path name */ ! 228: strcpy(szCurrentPath,szBuffer); ! 229: FillDirListBox(hwnd, szCurrentPath); ! 230: FillFileListBox(hwnd); ! 231: WinSetDlgItemText(hwnd, IDD_FILEEDIT, ""); ! 232: return 0L; ! 233: ! 234: case FILE_VALID: /* It was valid */ ! 235: strcpy(szFileName, szParsedPath); ! 236: WinDismissDlg(hwnd, TRUE); ! 237: return 0L; ! 238: } ! 239: break; ! 240: ! 241: case DID_CANCEL: ! 242: WinDismissDlg(hwnd, FALSE); ! 243: return 0L; ! 244: } ! 245: break; ! 246: } ! 247: return WinDefDlgProc(hwnd, msg, mp1, mp2); ! 248: } ! 249: ! 250: ! 251: /* ! 252: * Function name: FillDirListBox() ! 253: * ! 254: * Parameters: hwnd points to the current window handle ! 255: * pcCurrentPath points to a buffer which will be filled in ! 256: * with the current path. ! 257: * ! 258: * Returns: VOID ! 259: * ! 260: * Purpose: This routine is called by OpenFileProc to fill in the directory ! 261: * list box ! 262: * ! 263: * Usage/Warnings: Adequete error checking is NOT done on the return ! 264: * values of the system calls. Also, it is remotely ! 265: * possible that the calls to add to the list box could fail. ! 266: * ! 267: * Calls: ! 268: */ ! 269: ! 270: VOID FillDirListBox(HWND hwnd, CHAR *pcCurrentPath) ! 271: { ! 272: static CHAR szDrive [] = " :"; ! 273: FILEFINDBUF findbuf; ! 274: HDIR hDir = 1; ! 275: SHORT sDrive; ! 276: ! 277: ULONG ulCurPathLen, ulDriveMap, ulSearchCount = 1, ulDriveNum; ! 278: ! 279: DosQCurDisk(&ulDriveNum, &ulDriveMap); ! 280: *pcCurrentPath = (CHAR) ulDriveNum + '@'; ! 281: *(pcCurrentPath+1) = ':'; ! 282: *(pcCurrentPath+2) = '\\'; ! 283: ulCurPathLen = CCHMAXPATH; ! 284: DosQCurDir(0L, pcCurrentPath + 3, &ulCurPathLen); ! 285: ! 286: WinSetDlgItemText(hwnd, IDD_PATH, pcCurrentPath); ! 287: WinSendDlgItemMsg(hwnd, IDD_DIRLIST, LM_DELETEALL, NULL, NULL); ! 288: ! 289: for(sDrive = ('A'-'A'); sDrive <= ('Z'-'A'); sDrive++) ! 290: { ! 291: if(ulDriveMap & (1L << sDrive)) ! 292: { ! 293: *(szDrive+1) = (CHAR) sDrive + 'A'; ! 294: ! 295: WinSendDlgItemMsg(hwnd, IDD_DIRLIST, LM_INSERTITEM, ! 296: MPFROM2SHORT(LIT_END, 0), ! 297: MPFROMP(szDrive)); ! 298: } ! 299: } ! 300: DosFindFirst("*", &hDir, FILE_DIRECTORY | FILE_ALL, &findbuf, ! 301: sizeof(findbuf), &ulSearchCount, FIL_STANDARD); ! 302: while(ulSearchCount) ! 303: { ! 304: if((findbuf.attrFile & FILE_DIRECTORY) && ! 305: (findbuf.achName[0] != '.' || findbuf.achName[1])) ! 306: ! 307: WinSendDlgItemMsg(hwnd, IDD_DIRLIST, LM_INSERTITEM, ! 308: MPFROM2SHORT(LIT_SORTASCENDING, 0), ! 309: MPFROMP(findbuf.achName)); ! 310: ! 311: if(DosFindNext(hDir, &findbuf, sizeof(findbuf), &ulSearchCount)) ! 312: break; ! 313: } ! 314: } ! 315: ! 316: ! 317: /* This routine is called by OpenFileProc to fill the file list box */ ! 318: ! 319: /* ! 320: * Function name: FillFileListBox() ! 321: * ! 322: * Parameters: hwnd points to the current window handle ! 323: * ! 324: * Returns: VOID ! 325: * ! 326: * Purpose: This routine is called by OpenFileProc to fill in the file ! 327: * list box with files in the current directory. ! 328: * ! 329: * Usage/Warnings: Adequete error checking is NOT done on the return ! 330: * values of the system calls. Also, it is remotely ! 331: * possible that the calls to add to the list box could fail. ! 332: * ! 333: * Calls: ! 334: */ ! 335: ! 336: VOID FillFileListBox(HWND hwnd) ! 337: { ! 338: FILEFINDBUF findbuf; ! 339: HDIR hDir = 1; ! 340: ULONG ulSearchCount = 1; /* Read 1 entry at a time */ ! 341: ! 342: WinSendDlgItemMsg(hwnd, IDD_FILELIST, LM_DELETEALL, NULL, NULL); ! 343: ! 344: DosFindFirst("*", &hDir, FILE_ALL, &findbuf, sizeof(findbuf), ! 345: &ulSearchCount, FIL_STANDARD); ! 346: while(ulSearchCount) ! 347: { ! 348: WinSendDlgItemMsg(hwnd, IDD_FILELIST, LM_INSERTITEM, ! 349: MPFROM2SHORT(LIT_SORTASCENDING, 0), ! 350: MPFROMP(findbuf.achName)); ! 351: ! 352: if(DosFindNext(hDir, &findbuf, sizeof(findbuf), &ulSearchCount)) ! 353: break; ! 354: } ! 355: } ! 356: ! 357: ! 358: /* ! 359: * Function name: ParseFileName() ! 360: * ! 361: * Parameters: pcOut points to a buffer for the return file specification. ! 362: * pcIn points to the buffer containing the raw input spec. ! 363: * ! 364: * Returns: FILE_INVALID if pcIn had invalid drive or no directory ! 365: * FILE_PATH if pcIn was empty or had just a path/no file name. ! 366: * FILE_VALID if pcIn point to good file. ! 367: * ! 368: * Purpose: This routine changes drive and directory as per pcIn string. ! 369: * ! 370: * Usage/Warnings: Note that pcOut is only valid if FILE_VALID is returned. ! 371: * in place of strupr(), a codepage should be fetched and ! 372: * DosCaseMap() should be used to allow for extended chars. ! 373: * This routine could use some cleanup work. ! 374: * ! 375: * Calls: ! 376: */ ! 377: ! 378: SHORT ParseFileName(CHAR *pcOut, CHAR *pcIn) ! 379: { ! 380: CHAR *pcLastSlash, *pcFileOnly ; ! 381: ULONG ulDriveMap, ulDirLen = CCHMAXPATH, ulDriveNum; ! 382: ! 383: strupr(pcIn); /* Does NOT handle extended chars, should use DosCaseMap */ ! 384: ! 385: if(*pcIn == '\000') /* If string is empty, return FILE_PATH */ ! 386: ! 387: return FILE_PATH; ! 388: ! 389: /* Get drive from input string or use current drive */ ! 390: ! 391: if(*(pcIn+1) == ':') /* Yup, they specified a drive */ ! 392: { ! 393: if(DosSelectDisk(*pcIn - '@')) /* Change to selected drive */ ! 394: return FILE_INVALID; ! 395: pcIn += 2; ! 396: } ! 397: DosQCurDisk(&ulDriveNum, &ulDriveMap); /* Get current drive */ ! 398: ! 399: *pcOut++ = (CHAR) ulDriveNum + '@'; /* Build drive letter */ ! 400: *pcOut++ = ':'; ! 401: *pcOut++ = '\\'; ! 402: ! 403: if(*pcIn == '\000') /* If rest of the string is empty, return FILE_PATH */ ! 404: return FILE_PATH; ! 405: ! 406: /* Search for the last backslash. If none, it could be a directory. */ ! 407: ! 408: if(!(pcLastSlash = strrchr(pcIn, '\\'))) /* No slashes? */ ! 409: { ! 410: if(!DosChDir(pcIn)) ! 411: return FILE_PATH; /* It was a directory */ ! 412: ! 413: DosQCurDir(0L, pcOut, &ulDirLen); /* Get current dir & attach input fn */ ! 414: ! 415: if(*(pcOut+strlen(pcOut)-1) != '\\') ! 416: strcat(pcOut++, "\\"); ! 417: ! 418: strcat(pcOut, pcIn); ! 419: return FILE_VALID; ! 420: } ! 421: ! 422: /* If the only backslash is at the beginning, change to root */ ! 423: ! 424: if(pcIn == pcLastSlash) ! 425: { ! 426: DosChDir("\\"); ! 427: ! 428: if(*(pcIn+1) == '\000') ! 429: return FILE_PATH; ! 430: ! 431: strcpy(pcOut, pcIn+1); ! 432: return FILE_VALID; ! 433: } ! 434: ! 435: /* Attempt to change directory -- Get current dir if OK */ ! 436: ! 437: *pcLastSlash = NULL; ! 438: ! 439: if(DosChDir(pcIn)) ! 440: return FILE_INVALID; ! 441: ! 442: DosQCurDir(0L, pcOut, &ulDirLen); ! 443: ! 444: /* Append input filename if any */ ! 445: ! 446: pcFileOnly = pcLastSlash+1; ! 447: ! 448: if(*pcFileOnly == '\000') ! 449: return FILE_PATH; ! 450: ! 451: if(*(pcOut+strlen(pcOut)-1) != '\\') ! 452: strcat(pcOut++, "\\"); ! 453: ! 454: strcat(pcOut, pcFileOnly); ! 455: return FILE_VALID; ! 456: } ! 457:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.