|
|
1.1 ! root 1: /************************************************************* ! 2: ! 3: New Extended Attribute Display (NEAD) ! 4: ! 5: Created by Microsoft, IBM Corporation, 1990 ! 6: ! 7: DISCLAIMER OF WARRANTIES. The following [enclosed] code is ! 8: sample code created by Microsoft Corporation and/or IBM ! 9: Corporation. This sample code is not part of any standard ! 10: Microsoft or IBM product and is provided to you solely for ! 11: the purpose of assisting you in the development of your ! 12: applications. The code is provided "AS IS", without ! 13: warranty of any kind. Neither Microsoft nor IBM shall be ! 14: liable for any damages arising out of your use of the sample ! 15: code, even if they have been advised of the possibility of ! 16: such damages. ! 17: ! 18: This program implements an extended attributes editor. ! 19: Included in this file are all of the PM interface procedures. ! 20: All of these procs represent procedures for dialog boxes. ! 21: ! 22: This code is not fully implemented as it was written to show ! 23: how to use EAs. Specifically, the Copy, Copy all, and Paste ! 24: buttons are not implemented, Icons and bitmaps are not ! 25: supported, and Multi-value, single-type EAs are also not ! 26: implemented. ! 27: ! 28: The EA code revolves around the HoldFEA structure. This ! 29: structure is a linked list which contains one EA per ! 30: structure. Each HoldFEA structure is dynamically allocated ! 31: as are the two string pointer members of the structure, ! 32: szName and aValue. This is done to make handling the EAs ! 33: easier and more flexable. ! 34: ! 35: Procedures in this file: ! 36: main() Sets up the PM environment and heap and ! 37: calls the main dialog procedure MainDlgProc ! 38: MainDlgProc() Handles the main window messages ! 39: AddEAProc() Handles new EA name entry and type selection ! 40: AsciiEditProc() Handles editing of EA name/value ! 41: IconDlgProc() Unimplemented icon procedure handler ! 42: MultiTypeProc() Handles the Multi-type dialog box ! 43: ShowEAType() Shows Selected EA Type for MainDlgProc ! 44: EditEA() Handles selection of an EA in the listbox ! 45: GetCurFEA() Gets a ptr to the hi-lited EA in the listbox ! 46: ! 47: **************************************************************/ ! 48: ! 49: #include "nead.h" ! 50: ! 51: /********************* GLOBALS *******************************/ ! 52: ! 53: CHAR szFileName[CCHMAXPATH]; /* Holds current EA file */ ! 54: CHAR szEAName[MAXEANAME+1]; /* Used to return the EA name +1 for NULL */ ! 55: USHORT usRetEAType; /* Used to return selected EA Type */ ! 56: BOOL FILE_ISOPEN = FALSE; /* File Open flag */ ! 57: BOOL FILE_CHANGED = FALSE; /* File Changed flag */ ! 58: BOOL COMMAND_LINE_FILE = FALSE; /* Flag to determine if a file was on the CL */ ! 59: CHAR *szAscii,*szScratch; /* 2 Pointer used to return misc. strings */ ! 60: HOLDFEA *pHoldFEA; /* Global EA linked-list pointer */ ! 61: DELETELIST *pDelList; /* Global ptr to l-l of deleted EAs */ ! 62: EADATA ConvTable[EATABLESIZE] = { /* Setup the table */ ! 63: { EA_LPBINARY ,"Length preceeded hex binary\0 ",IDD_LPDATA}, ! 64: { EA_LPASCII ,"Length preceeded ascii\0 ",IDD_LPDATA}, ! 65: { EA_ASCIIZ ,"Asciiz\0 ",IDD_ASCIIZ}, ! 66: { EA_LPBITMAP ,"Length preceeded bitmap\0 ",IDD_LPDATA}, ! 67: { EA_LPMETAFILE,"Metafile\0 ",IDD_LPDATA}, ! 68: { EA_LPICON ,"Length preceeded icon\0 ",IDD_LPDATA}, ! 69: { EA_ASCIIZFN ,"Asciiz file name of associated data\0",IDD_ASCIIZ}, ! 70: { EA_ASCIIZEA ,"Asciiz EA of associated data\0 ",IDD_ASCIIZ}, ! 71: { EA_MVMT ,"Multi value multi type field\0 ",IDD_MULTILIST}, ! 72: { EA_MVST ,"Multi value single type field\0 ",IDD_MULTILIST}, ! 73: { EA_ASN1 ,"ASN.1 field\0 ",IDD_ASCIIZ}, ! 74: { 0 ,"Non conventional format\0 ",IDD_ASCIIZ} ! 75: }; ! 76: ! 77: /*************************************************************/ ! 78: ! 79: /* ! 80: * Function name: main() ! 81: * ! 82: * Parameters: argc, argv. If the user places a file name on the command ! 83: * line, its EAs will be retrieved by default, otherwise ! 84: * the user will be prompted to select a file. ! 85: * ! 86: * Returns: Always returns 0 ! 87: * ! 88: * Purpose: Parses the command line, sets up the PM environment, creates ! 89: * a global memory heap, calls the main dialog proc, then ! 90: * cleans up and exits. ! 91: * ! 92: * Usage/Warnings: ! 93: * ! 94: * Calls: ParseFileName, MainDlgProc (thru PM) ! 95: */ ! 96: ! 97: int main(int argc, char *argv[]) ! 98: { ! 99: HAB hab; ! 100: HMQ hmq; ! 101: ! 102: if(argc > 1) /* If a command line file, get EAs from it */ ! 103: if(ParseFileName(szFileName,argv[1]) != FILE_VALID) /* Bad file name */ ! 104: *szFileName=0; ! 105: else ! 106: COMMAND_LINE_FILE = TRUE; ! 107: ! 108: /* Note: The following 3 setup calls aren't currently checked for errors */ ! 109: hab = WinInitialize(0); ! 110: hmq = WinCreateMsgQueue(hab, 0); ! 111: ! 112: WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, ! 113: MainDlgProc,NULL,IDD_MAIN,NULL); ! 114: ! 115: WinDestroyMsgQueue(hmq); ! 116: WinTerminate(hab); ! 117: return 0; ! 118: } ! 119: ! 120: ! 121: /* ! 122: * Function name: MainDlgProc() ! 123: * ! 124: * Parameters: hwnd, msg, mp1, mp2. Standard PM Dialog Proc params. ! 125: * No user data is expected in the WM_INITDLG. ! 126: * ! 127: * Returns: Always returns 0, Exits with WinDismissDlg set to TRUE ! 128: * ! 129: * Purpose: Handles all the messages associated with the main window ! 130: * and calls the appropriate handling procedures. The initialize ! 131: * routine sets up the program icon and posts a load file message ! 132: * to itself. ! 133: * ! 134: * Usage/Warnings: Called only by main() ! 135: * ! 136: * Calls: OpenFile(), AddEA(), DeleteCurEA, WriteEAs, ShowEAType, EditEA ! 137: */ ! 138: ! 139: MRESULT EXPENTRY MainDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) ! 140: { ! 141: HPOINTER hpointer; ! 142: USHORT usRet; ! 143: ! 144: switch(msg) ! 145: { ! 146: case WM_INITDLG: ! 147: hpointer = WinLoadPointer(HWND_DESKTOP, /* Set Nead Icon */ ! 148: (HMODULE) NULL,IDR_EAD); ! 149: WinPostMsg(hwnd,WM_SETICON,hpointer,0L); ! 150: ! 151: /* Get EAs from file on Command line, or prompt for file name */ ! 152: WinPostMsg(hwnd,WM_USER,NULL,NULL); ! 153: return 0L; ! 154: ! 155: case WM_USER: /* Posted by WM_INITDLG allows main window to open 1st */ ! 156: OpenFile(hwnd, COMMAND_LINE_FILE ? ARGFILE : NULL); ! 157: return 0L; ! 158: ! 159: case WM_COMMAND: ! 160: switch(LOUSHORT(mp1)) ! 161: { ! 162: case IDD_NEWFILE: /* Select another file to view/edit EAs */ ! 163: OpenFile(hwnd,0); ! 164: return 0L; ! 165: ! 166: case IDD_ADD: /* Add an EA to current list in memory */ ! 167: AddEA(hwnd); ! 168: return 0L; ! 169: ! 170: case IDD_DELETE: /* Delete an EA from memory */ ! 171: DeleteCurEA(hwnd); ! 172: return 0L; ! 173: ! 174: case IDD_WRITE: /* Write EA's out to disk */ ! 175: WriteEAs(); ! 176: return 0L; ! 177: ! 178: case IDD_EDIT: /* Edit the hilited EA */ ! 179: EditEA(hwnd); ! 180: return 0L; ! 181: ! 182: case IDD_COPY: /* Copy and Paste aren't */ ! 183: case IDD_PASTE: /* currently implemented */ ! 184: return 0L; ! 185: ! 186: case IDD_QUIT: ! 187: if(FILE_CHANGED) /* Give user a chance to save changes */ ! 188: { ! 189: usRet=WinMessageBox(HWND_DESKTOP,hwnd, ! 190: "The current file has been changed. Do you \ ! 191: wish to save the changes before proceeding?", ! 192: "Warning",NULL,MB_YESNOCANCEL | MB_ICONQUESTION); ! 193: switch(usRet) ! 194: { ! 195: case MBID_YES: /* They want to save the EAs */ ! 196: WriteEAs(); ! 197: break; ! 198: case MBID_CANCEL: /* They don't really want to quit */ ! 199: return 0L; ! 200: } ! 201: } ! 202: WinDismissDlg(hwnd,TRUE); ! 203: return 0L; ! 204: } ! 205: ! 206: case WM_CONTROL: ! 207: switch(SHORT1FROMMP(mp1)) ! 208: { ! 209: case IDD_LBOX: ! 210: switch(SHORT2FROMMP(mp1)) ! 211: { ! 212: case LN_SELECT: /* A new item has been hi-lited */ ! 213: ShowEAType(hwnd); /* Display appropriate EA Type */ ! 214: return 0L; ! 215: ! 216: case LN_ENTER: /* Edit the selected EA */ ! 217: EditEA(hwnd); ! 218: return 0L; ! 219: } ! 220: } ! 221: } ! 222: return WinDefDlgProc(hwnd, msg, mp1, mp2); ! 223: } ! 224: ! 225: ! 226: /* ! 227: * Function name: AddEAProc() ! 228: * ! 229: * Parameters: hwnd, msg, mp1, mp2. Standard PM Dialog Proc params. ! 230: * If user data is passed in, it indicates it is a m-m ! 231: * add and the EA Name is in ->Point and the user should ! 232: * not be allowed to edit it. ! 233: * ! 234: * Returns: Exits with WinDismissDlg set to TRUE if the user selects OK, ! 235: * FALSE if the user selects CANCEL. ! 236: * ! 237: * Purpose: Handles the screen that allows the user to enter a new EA Name ! 238: * and select the EA type. It checks to make sure the name is ! 239: * unique and is not NULL before returning. The user pointer is ! 240: * used to determine whether the name is allowed to change or not. ! 241: * If it points to a PassData structure, the Point member gives the ! 242: * static EA Name. ! 243: * ! 244: * Usage/Warnings: Called by both the add EA routine and the m-m EA add ! 245: * routine. This routine places the user typed name in ! 246: * global szEAName, and the EA type in global usRetEAType. ! 247: * ! 248: * Calls: EAExists() ! 249: */ ! 250: ! 251: MRESULT EXPENTRY AddEAProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) ! 252: { ! 253: static CHAR bPDat = 0; /* flag indicating if the pPDat struct is valid */ ! 254: PASSDATA FAR *pPDat; /* struct used to pass in default EA name */ ! 255: ! 256: switch(msg) ! 257: { ! 258: case WM_INITDLG: ! 259: bPDat = 0; ! 260: WinSendDlgItemMsg(hwnd, IDD_EANAME,EM_SETTEXTLIMIT, ! 261: MPFROM2SHORT(MAXEANAME,0),NULL); ! 262: WinSendDlgItemMsg(hwnd, EA_LPASCII,BM_CLICK,0L,0L); ! 263: ! 264: pPDat=PVOIDFROMMP(mp2); ! 265: if(pPDat) ! 266: { ! 267: bPDat = 1; ! 268: WinSetDlgItemText(hwnd, IDD_EANAME,pPDat->Point); ! 269: WinSetDlgItemText(hwnd, IDD_TITLE, ! 270: "Add a Multi-type field to the EA"); ! 271: WinEnableWindow(WinWindowFromID(hwnd,IDD_EANAME), ! 272: FALSE); /* Disable EA Name field */ ! 273: WinSetFocus(HWND_DESKTOP,WinWindowFromID(hwnd,DID_OK)); ! 274: ! 275: return (MRESULT)TRUE; /* We don't want default focus setting */ ! 276: } ! 277: return 0L; ! 278: ! 279: case WM_COMMAND: ! 280: switch(LOUSHORT(mp1)) ! 281: { ! 282: case DID_OK: ! 283: if(bPDat == 0) /* It is a new EA (not multi-type) */ ! 284: { ! 285: WinQueryDlgItemText(hwnd, IDD_EANAME, MAXEANAME+1, szEAName); ! 286: ! 287: if(!strlen(szEAName)) /* Don't allow a Null EA Name */ ! 288: { ! 289: WinAlarm(HWND_DESKTOP,WA_ERROR); ! 290: WinMessageBox(HWND_DESKTOP, hwnd, ! 291: "Cannot create a NULL EA name.", ! 292: NULL, 0, MB_OK); ! 293: return 0L; ! 294: } ! 295: ! 296: if(EAExists(szEAName)) /* Don't allow duplicate EA Name */ ! 297: { ! 298: WinAlarm(HWND_DESKTOP,WA_ERROR); ! 299: WinMessageBox(HWND_DESKTOP, hwnd, ! 300: "EA name already exists. Can't create that name.", ! 301: NULL, 0, MB_OK); ! 302: return 0L; ! 303: } ! 304: } ! 305: usRetEAType = (USHORT) WinSendDlgItemMsg(hwnd, EA_ASCIIZ, ! 306: BM_QUERYCHECKINDEX, 0L, 0L); ! 307: WinDismissDlg(hwnd, TRUE); ! 308: return 0L; ! 309: ! 310: case DID_CANCEL: ! 311: WinDismissDlg(hwnd, FALSE); ! 312: return 0L; ! 313: } ! 314: break; ! 315: } ! 316: return WinDefDlgProc(hwnd, msg, mp1, mp2); ! 317: } ! 318: ! 319: ! 320: /* ! 321: * Function name: AddEAProc() ! 322: * ! 323: * Parameters: hwnd, msg, mp1, mp2. Standard PM Dialog Proc params. ! 324: * The user pointer passes in a PassData struct. The Point ! 325: * member points to the default EA Name and the usIndex ! 326: * member determines whether or not the user can modify the ! 327: * EA Name. The fFlag member determines the status of the ! 328: * Need/nice bit. TRUE indicates the Need bit is set. The ! 329: * default Value is passed in global szAscii. ! 330: * ! 331: * Returns: Exits with WinDismissDlg set to TRUE if the user selects OK, ! 332: * FALSE if the user selects CANCEL. Global szEAName contains the ! 333: * modified EA Value. the fFlag member of the passed in data will ! 334: * be updated to reflect the current state of the Need bit. ! 335: * ! 336: * Purpose: This proc handles the editing of EA Names and their associated ! 337: * ASCII strings. ! 338: * ! 339: * Usage/Warnings: A PassData struct must be passed in when called. ! 340: * Note that the Value buffer is dynamically allocated and ! 341: * it is the responsibility of the calling procedure to ! 342: * deallocate the buffer (szScratch) when finished with it. ! 343: * Note also that memory allocations are NOT fully error ! 344: * trapped. ! 345: * ! 346: * Calls: EAExists() ! 347: */ ! 348: ! 349: ! 350: MRESULT EXPENTRY AsciiEditProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) ! 351: { ! 352: static PASSDATA FAR *pPDat; ! 353: ! 354: switch(msg) ! 355: { ! 356: case WM_INITDLG: ! 357: WinSendDlgItemMsg(hwnd, IDD_EANAME,EM_SETTEXTLIMIT, ! 358: MPFROM2SHORT(MAXEANAME,0),NULL); ! 359: WinSendDlgItemMsg(hwnd, IDD_EAVALUE,EM_SETTEXTLIMIT, ! 360: MPFROM2SHORT(MAXEAVALUE,0),NULL); ! 361: pPDat=PVOIDFROMMP(mp2); ! 362: ! 363: WinSetDlgItemText(hwnd, IDD_EANAME,pPDat->Point); ! 364: WinSetDlgItemText(hwnd, IDD_EATYPE,ConvTable[usRetEAType].szFormat); ! 365: WinSendDlgItemMsg(hwnd, IDD_NEEDBIT, BM_SETCHECK, ! 366: MPFROM2SHORT(pPDat->fFlag,0),NULL); ! 367: ! 368: if(szAscii) /* Set default EA Value if global var is != NULL */ ! 369: WinSetDlgItemText(hwnd, IDD_EAVALUE,szAscii); ! 370: ! 371: if(pPDat->usIndex) /* Disable EANAME if passed in a non-zero value */ ! 372: { ! 373: WinEnableWindow(WinWindowFromID(hwnd,IDD_EANAME),FALSE); ! 374: WinEnableWindow(WinWindowFromID(hwnd,IDD_NEEDBIT),FALSE); ! 375: WinSetFocus(HWND_DESKTOP,WinWindowFromID(hwnd,IDD_EAVALUE)); ! 376: return (MRESULT)TRUE; /* We don't want default focus setting */ ! 377: } ! 378: return 0L; ! 379: ! 380: case WM_COMMAND: ! 381: switch(LOUSHORT(mp1)) ! 382: { ! 383: case DID_OK: ! 384: pPDat->fFlag = (BYTE) WinSendDlgItemMsg(hwnd, IDD_NEEDBIT, ! 385: BM_QUERYCHECK, ! 386: 0L, 0L); ! 387: WinQueryDlgItemText(hwnd, IDD_EANAME, MAXEANAME+1, szEAName); ! 388: ! 389: if(!strlen(szEAName)) /* They nulled out the name */ ! 390: { ! 391: WinAlarm(HWND_DESKTOP,WA_ERROR); ! 392: WinMessageBox(HWND_DESKTOP, hwnd, ! 393: "Cannot create a NULL EA name.", ! 394: NULL, 0, MB_OK); ! 395: return 0L; ! 396: } ! 397: ! 398: GetMem(&szScratch, MAXEAVALUE+1); /* Allocate buffer for value */ ! 399: WinQueryDlgItemText(hwnd, IDD_EAVALUE, MAXEAVALUE+1, szScratch); ! 400: ! 401: if(!strlen(szScratch)) /* They nulled out the value */ ! 402: { ! 403: FreeMem(szScratch); /* Free the value buffer */ ! 404: WinAlarm(HWND_DESKTOP,WA_ERROR); ! 405: WinMessageBox(HWND_DESKTOP, hwnd, ! 406: "An EA can't have a NULL value.", ! 407: NULL, 0, MB_OK); ! 408: return 0L; ! 409: } ! 410: ! 411: if(stricmp(szEAName,pPDat->Point)) /* changed the EA name */ ! 412: { ! 413: if(EAExists(szEAName)) /* Can't have duplicate EA names */ ! 414: { ! 415: WinAlarm(HWND_DESKTOP,WA_ERROR); ! 416: WinMessageBox(HWND_DESKTOP, hwnd, ! 417: "EA name already exists. Can't create that name.", ! 418: NULL, 0, MB_OK); ! 419: ! 420: FreeMem(szScratch); /* Free value buffer */ ! 421: return 0L; ! 422: } ! 423: } ! 424: ! 425: DosSetMem(szScratch, strlen(szScratch)+1, fPERM|PAG_COMMIT); ! 426: ! 427: WinDismissDlg(hwnd, TRUE); ! 428: return 0L; ! 429: ! 430: case DID_CANCEL: ! 431: WinDismissDlg(hwnd, FALSE); ! 432: return 0L; ! 433: } ! 434: break; ! 435: } ! 436: return WinDefDlgProc(hwnd, msg, mp1, mp2); ! 437: } ! 438: ! 439: ! 440: /* ! 441: * Function name: IconDlgProc() ! 442: * ! 443: * Parameters: hwnd, msg, mp1, mp2. Standard PM Dialog Proc params. ! 444: * No user data is expected. ! 445: * ! 446: * Returns: Currently just calls WinDefDlgProc. ! 447: * ! 448: * Purpose: This proc is unimplemented, but is intedned to handle displaying ! 449: * and editing icons/bitmaps. ! 450: * ! 451: * Usage/Warnings: ! 452: * ! 453: * Calls: ! 454: */ ! 455: ! 456: MRESULT EXPENTRY IconDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) ! 457: { ! 458: switch(msg) ! 459: { ! 460: case WM_INITDLG: ! 461: return 0L; ! 462: ! 463: case WM_COMMAND: ! 464: switch(LOUSHORT(mp1)) ! 465: { ! 466: case DID_OK: ! 467: WinDismissDlg(hwnd, TRUE); ! 468: return 0L; ! 469: } ! 470: } ! 471: return WinDefDlgProc(hwnd, msg, mp1, mp2); ! 472: } ! 473: ! 474: ! 475: /* ! 476: * Function name: MultiTypeProc() ! 477: * ! 478: * Parameters: hwnd, msg, mp1, mp2. Standard PM Dialog Proc params. ! 479: * Expects a user pointer to a PassData structure with Point ! 480: * member pointing to the current pFEA structure. The Multi ! 481: * member fields of the PassData struct should also be ! 482: * filled in to indicate the location and size of the current ! 483: * m-m field. ! 484: * ! 485: * Returns: Always returns TRUE thru WinDismissDlg when DONE is clicked. ! 486: * ! 487: * Purpose: This proc handles the multi-type EA stuff. Allows the fields ! 488: * in a given m-m to be edited. ! 489: * ! 490: * Usage/Warnings: NOTE that this procedure is fully reentrant/recursive ! 491: * in that it calls EditEAValue() which can call ! 492: * MultiTypeProc. Since PassData information is placed ! 493: * in static variables, the ReEnter structure is used to ! 494: * hold a dynamic linked list of values passed into the ! 495: * proc and thus keeps the static data set to the proper ! 496: * values. ! 497: * ! 498: * Calls: MultiTypeIndex(), EAValueString(), EditEAValue(), MultiAdd() ! 499: */ ! 500: ! 501: MRESULT EXPENTRY MultiTypeProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) ! 502: { ! 503: static HOLDFEA *pFEA; /* Points to the current EA */ ! 504: static PASSDATA FAR *pPDat; /* Points to the passed Data struct */ ! 505: static REENTER *CurEntry; /* Points to most recent data frame */ ! 506: REENTER *ReEntHold; /* Temp used to setup the frame */ ! 507: PASSDATA PDat; /* Used for call to EditEAValue */ ! 508: USHORT *pusPtr,cnt; /* Utility vars */ ! 509: SHORT sOffset; ! 510: CHAR *pInsert,*pValue,*pDelete; ! 511: CHAR szCodePage[LENUSHORTBUF]; ! 512: BYTE fNeed; /* Holds state of need checkbox */ ! 513: ! 514: switch(msg) ! 515: { ! 516: case WM_INITDLG: ! 517: pPDat = PVOIDFROMMP(mp2); /* Set up static vars */ ! 518: pFEA = (HOLDFEA *) pPDat->Point; ! 519: ! 520: GetMem(&ReEntHold, sizeof(REENTER)); /* Allows for recusive calls */ ! 521: ReEntHold->pPDat = pPDat; ! 522: ReEntHold->pFEA = pFEA; ! 523: ReEntHold->next = CurEntry; ! 524: CurEntry = ReEntHold; ! 525: ! 526: WinSendDlgItemMsg(hwnd, IDD_NEEDBIT, BM_SETCHECK, /* Need bit setup */ ! 527: MPFROM2SHORT((pFEA->fEA&0x80)? TRUE : FALSE,0), ! 528: NULL); ! 529: ! 530: WinSetDlgItemText(hwnd,IDD_EATYPE,""); /* Setup the codepage */ ! 531: WinSetDlgItemText(hwnd,IDD_EANAME,pFEA->szName); ! 532: WinSendDlgItemMsg(hwnd, IDD_CODEPAGE,EM_SETTEXTLIMIT, ! 533: MPFROM2SHORT(LENUSHORTBUF-1,0),NULL); ! 534: ! 535: pusPtr= (USHORT *) ((CHAR *) pFEA->aValue+pPDat->usMultiOffset); ! 536: pusPtr++; /* Skip the EA_Type field and point to codepage */ ! 537: sprintf(szCodePage,"%u",*pusPtr); ! 538: WinSetDlgItemText(hwnd, IDD_CODEPAGE,szCodePage); ! 539: ! 540: pusPtr++; /* Skip codepage and point to the field count */ ! 541: ! 542: for(cnt=0;cnt< *pusPtr;cnt++) /* Add each field to the L-Box */ ! 543: { ! 544: pInsert = MultiTypeIndex(pFEA->aValue+pPDat->usMultiOffset,cnt); ! 545: pValue = EAValueString(pInsert); /* Ptr to asciiz string */ ! 546: ! 547: WinSendDlgItemMsg(hwnd, IDD_LBOX, LM_INSERTITEM, ! 548: MPFROM2SHORT(LIT_END,0), ! 549: MPFROMP(pValue)); ! 550: FreeMem(pValue); /* Free asciiz string */ ! 551: } ! 552: return 0L; ! 553: ! 554: case WM_CONTROL: ! 555: switch(SHORT1FROMMP(mp1)) ! 556: { ! 557: case IDD_LBOX: ! 558: switch(SHORT2FROMMP(mp1)) ! 559: { ! 560: case LN_SELECT: /* Display proper EA type for selection */ ! 561: sOffset = (SHORT) WinSendDlgItemMsg(hwnd, IDD_LBOX, ! 562: LM_QUERYSELECTION,0,0); ! 563: if(sOffset<0) ! 564: break; ! 565: ! 566: pValue = MultiTypeIndex(pFEA->aValue+pPDat->usMultiOffset, ! 567: sOffset); ! 568: pusPtr = (USHORT *) pValue; ! 569: ! 570: WinSetDlgItemText(hwnd,IDD_EATYPE, ! 571: ConvTable[LookupEAType(*pusPtr)].szFormat); ! 572: break; ! 573: ! 574: case LN_ENTER: /* Setup and edit a m-m field */ ! 575: sOffset = (SHORT) WinSendDlgItemMsg(hwnd, IDD_LBOX, ! 576: LM_QUERYSELECTION,0,0); ! 577: if(sOffset<0) ! 578: return 0L; ! 579: ! 580: PDat.Point = (CHAR *) pFEA; /* Pass curr data */ ! 581: PDat.cbMulti = pPDat->cbMulti; ! 582: PDat.usMultiOffset = pPDat->usMultiOffset; ! 583: PDat.usIndex = (USHORT) sOffset; ! 584: ! 585: if(EditEAValue(hwnd,&PDat)) /* They didn't cancel */ ! 586: { ! 587: pInsert=MultiTypeIndex(pFEA->aValue ! 588: + pPDat->usMultiOffset, ! 589: sOffset); ! 590: pValue =EAValueString(pInsert); ! 591: ! 592: WinSendDlgItemMsg(hwnd, IDD_LBOX, LM_SETITEMTEXT, ! 593: MPFROMSHORT(sOffset), ! 594: MPFROMP(pValue)); ! 595: FreeMem(pValue); /* Free asciiz str */ ! 596: } ! 597: return 0L; ! 598: } ! 599: } ! 600: ! 601: case WM_COMMAND: ! 602: switch(LOUSHORT(mp1)) ! 603: { ! 604: case IDD_ADD: /* Add an item for a m-m */ ! 605: MultiAdd(hwnd, pFEA,pPDat); ! 606: return 0L; ! 607: ! 608: case IDD_EDIT: /* Setup and edit a m-m field */ ! 609: sOffset = (SHORT) WinSendDlgItemMsg(hwnd, IDD_LBOX, ! 610: LM_QUERYSELECTION,0,0); ! 611: if(sOffset<0) ! 612: return 0L; ! 613: ! 614: PDat.Point = (CHAR *) pFEA; /* Pass curr data */ ! 615: PDat.cbMulti = pPDat->cbMulti; ! 616: PDat.usMultiOffset = pPDat->usMultiOffset; ! 617: PDat.usIndex = (USHORT) sOffset; ! 618: ! 619: if(EditEAValue(hwnd,&PDat)) /* They didn't cancel */ ! 620: { ! 621: pInsert=MultiTypeIndex(pFEA->aValue + pPDat->usMultiOffset, ! 622: sOffset); ! 623: pValue =EAValueString(pInsert); ! 624: ! 625: WinSendDlgItemMsg(hwnd, IDD_LBOX, LM_SETITEMTEXT, ! 626: MPFROMSHORT(sOffset), ! 627: MPFROMP(pValue)); ! 628: FreeMem(pValue); /* Free asciiz str */ ! 629: } ! 630: return 0L; ! 631: ! 632: case IDD_DELETE: /* Delete hi-lited item */ ! 633: sOffset = (USHORT) WinSendDlgItemMsg(hwnd, IDD_LBOX, ! 634: LM_QUERYSELECTION,0,0); ! 635: if(sOffset<0) /* No item is currently selected */ ! 636: return 0L; ! 637: ! 638: WinSendDlgItemMsg(hwnd, IDD_LBOX, LM_DELETEITEM, ! 639: MPFROMSHORT(sOffset),0L); ! 640: ! 641: /* Get pointers to start of selected field and the following ! 642: field, then move the rest of the EA back, resize the ! 643: buffer, and change the EA Value counter */ ! 644: ! 645: pDelete = MultiTypeIndex(pFEA->aValue+pPDat->usMultiOffset, ! 646: sOffset); ! 647: pValue = MultiTypeIndex(pFEA->aValue+pPDat->usMultiOffset, ! 648: sOffset+1); ! 649: memmove(pDelete,pValue,pFEA->cbValue-(pValue-pFEA->aValue)); ! 650: DosSetMem(pFEA->aValue, pFEA->cbValue-(pValue-pDelete), fPERM|PAG_COMMIT); ! 651: pFEA->cbValue -= pValue-pDelete; ! 652: ! 653: /* Decrement the field count in the m-m */ ! 654: pusPtr = (USHORT *) ((CHAR *) pFEA->aValue + ! 655: pPDat->usMultiOffset); ! 656: pusPtr+=2; /* Point to the field count */ ! 657: *pusPtr -= 1; /* Decrement the field cnt */ ! 658: ! 659: FILE_CHANGED = TRUE; ! 660: return 0L; ! 661: ! 662: case DID_DONE: ! 663: /* Handle the possible change of the need checkbox */ ! 664: fNeed = (BYTE) WinSendDlgItemMsg(hwnd, IDD_NEEDBIT, ! 665: BM_QUERYCHECK, ! 666: 0L, 0L); ! 667: if(fNeed) ! 668: fNeed = 0x80; ! 669: if(fNeed != (pFEA->fEA & 0x80)) /* Need changed */ ! 670: { ! 671: pFEA->fEA = (pFEA->fEA & 0x7F) | fNeed; ! 672: FILE_CHANGED = TRUE; ! 673: } ! 674: ! 675: /* Handle the possible change of the codepage */ ! 676: WinQueryDlgItemText(hwnd, IDD_CODEPAGE, ! 677: LENUSHORTBUF, szCodePage); ! 678: sscanf(szCodePage,"%u",&cnt); ! 679: pusPtr= (USHORT *) ((CHAR *) pFEA->aValue+pPDat->usMultiOffset); ! 680: pusPtr++; /* Skip the EA_Type field and point to codepage */ ! 681: if(*pusPtr != cnt) /* They changed the codepage value */ ! 682: { ! 683: *pusPtr = cnt; ! 684: FILE_CHANGED = TRUE; ! 685: } ! 686: ! 687: ReEntHold = CurEntry->next; /* Finish recursion safety */ ! 688: FreeMem(CurEntry); ! 689: CurEntry = ReEntHold; ! 690: if(CurEntry) ! 691: { ! 692: pPDat = CurEntry->pPDat; ! 693: pFEA = CurEntry->pFEA; ! 694: } ! 695: WinDismissDlg(hwnd, TRUE); ! 696: return 0L; ! 697: } ! 698: } ! 699: return WinDefDlgProc(hwnd, msg, mp1, mp2); ! 700: } ! 701: ! 702: ! 703: /* ! 704: * Function name: ShowEAType() ! 705: * ! 706: * Parameters: hwnd which is the current window handle. ! 707: * ! 708: * Returns: VOID ! 709: * ! 710: * Purpose: This routine handles the display of the current EA type by ! 711: * setting the text in the appropriate dialog field. ! 712: * ! 713: * Usage/Warnings: Routine should be bullet proof as it does its own ! 714: * error checking. It assumes that hwnd points to the ! 715: * correct window with the name listbox in it. ! 716: * ! 717: * Calls: GetCurFEA(), LookupEAType() ! 718: */ ! 719: ! 720: VOID ShowEAType(HWND hwnd) ! 721: { ! 722: USHORT usEAType; /* Holds the offset of EAType into ConvTable */ ! 723: HOLDFEA *pFEA; ! 724: ! 725: pFEA = GetCurFEA(hwnd, pHoldFEA); /* Points to the selected EA */ ! 726: if(!pFEA) /* Kill line if nothing is selected */ ! 727: { ! 728: WinSetDlgItemText(hwnd,IDD_EATYPE,""); ! 729: return; ! 730: } ! 731: usEAType = LookupEAType((USHORT) *pFEA->aValue); ! 732: ! 733: WinSetDlgItemText(hwnd,IDD_EATYPE,ConvTable[usEAType].szFormat); ! 734: } ! 735: ! 736: ! 737: ! 738: /* ! 739: * Function name: EditEA() ! 740: * ! 741: * Parameters: hwnd which is the current window handle. ! 742: * ! 743: * Returns: TRUE iff the edit was successful. ! 744: * ! 745: * Purpose: This routine handles the editing of an EA when it is selected ! 746: * from the listbox. It get the item selected, sets up the PassData ! 747: * structure then calls EditEAValue to do the actual edit. ! 748: * ! 749: * Usage/Warnings: Routine should be bullet proof as it does its own ! 750: * error checking. It assumes that hwnd points to the ! 751: * correct window with the name listbox in it. ! 752: * ! 753: * Calls: EditEAValue() ! 754: */ ! 755: ! 756: BOOL EditEA(HWND hwnd) ! 757: { ! 758: HOLDFEA *pFEA=pHoldFEA; /* Pointer for selected EA */ ! 759: LONG offset,lCnt; /* Both used to reference offset of selected EA */ ! 760: PASSDATA PData; ! 761: ! 762: if(!FILE_ISOPEN) ! 763: return(FALSE); ! 764: ! 765: offset = lCnt = (LONG) WinSendDlgItemMsg(hwnd, IDD_LBOX, ! 766: LM_QUERYSELECTION,0,0); ! 767: ! 768: if(offset<0) /* Nothing was selected */ ! 769: return(FALSE); ! 770: ! 771: while(lCnt--) /* Get to the right EA */ ! 772: pFEA = pFEA->next; ! 773: ! 774: PData.Point = (CHAR *) pFEA; /* Set the pass data struct */ ! 775: PData.usMultiOffset = 0; ! 776: PData.cbMulti = 0; ! 777: ! 778: if(EditEAValue(hwnd,&PData)) /* It worked */ ! 779: { ! 780: WinSendDlgItemMsg(hwnd, IDD_LBOX,LM_SETITEMTEXT, ! 781: MPFROMSHORT((SHORT) offset),MPFROMP(pFEA->szName)); ! 782: return(TRUE); ! 783: } ! 784: return(FALSE); ! 785: } ! 786: ! 787: ! 788: /* This routine returns a pointer to the EA currently highlighted in the ! 789: list box. */ ! 790: ! 791: /* ! 792: * Function name: GetCurFEA() ! 793: * ! 794: * Parameters: hwnd which is the current window handle. ! 795: * pFEA which points to the base FEA in the linked list. ! 796: * ! 797: * Returns: The current EA as determined by querying the l-box selector, ! 798: * returns NULL if there is an error or nothing is selected. ! 799: * ! 800: * Purpose: This routine returns a pointer to the EA currently highlighted ! 801: * in the list box. ! 802: * ! 803: * Usage/Warnings: Routine should be bullet proof as it does its own ! 804: * error checking. It assumes that hwnd points to the ! 805: * correct window with the name listbox in it. ! 806: * ! 807: * Calls: EditEAValue() ! 808: */ ! 809: ! 810: HOLDFEA *GetCurFEA(HWND hwnd, HOLDFEA *pFEA) ! 811: { ! 812: LONG lOffset; ! 813: ! 814: lOffset = (LONG) WinSendDlgItemMsg(hwnd, IDD_LBOX, ! 815: LM_QUERYSELECTION,0,0); ! 816: ! 817: if(lOffset<0) /* Nothing is highlighted */ ! 818: return(NULL); ! 819: ! 820: while(lOffset--) ! 821: { ! 822: pFEA = pFEA->next; ! 823: } ! 824: ! 825: return(pFEA); ! 826: } ! 827: ! 828: ! 829: void ! 830: GetMem (ppv, cb) ! 831: PPVOID ppv; ! 832: ULONG cb; ! 833: { ! 834: BOOL f; ! 835: ! 836: f = DosAllocMem(ppv, cb, fPERM|PAG_COMMIT); ! 837: if (f) { ! 838: WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, ! 839: "Sorry, Not enough memory", NULL, 0, MB_OK); ! 840: *ppv = NULL; ! 841: return; ! 842: } ! 843: return; ! 844: } ! 845: ! 846: void ! 847: ResizeMem (ppv, cbOld, cbNew) ! 848: PPVOID ppv; ! 849: ULONG cbOld; ! 850: ULONG cbNew; ! 851: { ! 852: BOOL f; ! 853: PVOID pvNew; ! 854: ! 855: f = DosAllocMem(&pvNew, cbNew, fPERM|PAG_COMMIT); ! 856: if (f) { ! 857: WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, ! 858: "Sorry, Not enough memory", NULL, 0, MB_OK); ! 859: *ppv = NULL; ! 860: return; ! 861: } ! 862: memcpy(*ppv, pvNew, cbOld); ! 863: f = DosFreeMem(*ppv); ! 864: return; ! 865: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.