|
|
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.