Annotation of mstools/samples/sdktools/windiff/complist.c, revision 1.1

1.1     ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
        !            12: /****************************** Module Header *******************************
        !            13: * Module Name: COMPLIST.C
        !            14: *
        !            15: * Supports a list of compitems, where each compitem represents
        !            16: * a pair of matching files, or an unmatched file.
        !            17: *
        !            18: * Functions:
        !            19: *
        !            20: * complist_filedialog()
        !            21: * complist_dirdialog()
        !            22: * complist_args()
        !            23: * complist_getitems()
        !            24: * complist_delete()
        !            25: * complist_savelist()
        !            26: * complist_copyfiles()
        !            27: * complist_dodlg_savelist()
        !            28: * complist_dodlg_copyfiles()
        !            29: * complist_match()
        !            30: * complist_new()
        !            31: * complist_dodlg_dir()
        !            32: *
        !            33: * Comments:
        !            34: *
        !            35: * We build lists of filenames from two pathnames (using the
        !            36: * scandir module) and then traverse the two lists comparing names.
        !            37: * Where the names match, we create a CompItem from the matching
        !            38: * names. Where there is an unmatched name, we create a compitem for it.
        !            39: *
        !            40: * We may also be asked to create a complist for two individual files:
        !            41: * here we create a single compitem for them as a matched pair even if
        !            42: * the names don't match.
        !            43: *
        !            44: ****************************************************************************/
        !            45: 
        !            46: #include <windows.h>
        !            47: #include <stdlib.h>
        !            48: #include <string.h>
        !            49: #include <dos.h>
        !            50: #include <direct.h>
        !            51: 
        !            52: #include "gutils.h"
        !            53: #include "state.h"
        !            54: #include "windiff.h"
        !            55: #include "wdiffrc.h"
        !            56: #include "list.h"
        !            57: #include "line.h"
        !            58: #include "scandir.h"
        !            59: #include "file.h"
        !            60: #include "section.h"
        !            61: #include "compitem.h"
        !            62: #include "complist.h"
        !            63: #include "view.h"
        !            64: 
        !            65: 
        !            66: extern BOOL bAbort;             /* defined in windiff.c  Read only here */
        !            67: 
        !            68: /*
        !            69:  * The COMPLIST handle is typedef-ed to be a pointer to one
        !            70:  * of these struct complist
        !            71:  */
        !            72: struct complist {
        !            73:         DIRLIST left;           /* left list of files */
        !            74:         DIRLIST right;          /* right list of files */
        !            75:         LIST items;             /* list of COMPITEMs */
        !            76: };
        !            77: 
        !            78: /* ---- module-wide data -------------------------------------*/
        !            79: 
        !            80: /* data for communicating between the SaveList dlg and complist_savelist() */
        !            81: 
        !            82: char dlg_file[256];                /* filename to save to */
        !            83: 
        !            84: /* checkbox options */
        !            85: BOOL dlg_identical, dlg_differ, dlg_left, dlg_right;
        !            86: 
        !            87: /* data for Directory and SaveList */
        !            88: char dialog_leftname[256];
        !            89: char dialog_rightname[256];
        !            90: 
        !            91: /*
        !            92:  * data used by dodlg_copyfiles
        !            93:  */
        !            94: UINT dlg_options;
        !            95: char dlg_root[256];
        !            96: 
        !            97: /*------------------------timing for performance measurements-----------------*/
        !            98: 
        !            99: static DWORD TickCount;         /* time operation started, then time taken*/
        !           100: 
        !           101: 
        !           102: int FAR PASCAL complist_dodlg_savelist(HWND hDlg, UINT message,
        !           103:         UINT wParam, long lParam);
        !           104: int FAR PASCAL complist_dodlg_copyfiles(HWND hDlg, UINT message,
        !           105:         UINT wParam, long lParam);
        !           106: BOOL complist_match(COMPLIST cl, VIEW view, BOOL fDeep, BOOL fExact);
        !           107: COMPLIST complist_new(void);
        !           108: int FAR PASCAL complist_dodlg_dir(HWND hDlg, unsigned message,
        !           109:         WORD wParam, LONG lParam);
        !           110: 
        !           111: 
        !           112: 
        !           113: /***************************************************************************
        !           114:  * Function: complist_filedialog
        !           115:  *
        !           116:  * Purpose:
        !           117:  *
        !           118:  * Builds a complist by putting up two dialogs to allow the user to
        !           119:  * select two files. This will build a Complist with one CompItem (even
        !           120:  * if the names don't match).
        !           121:  *
        !           122:  ***************************************************************************/
        !           123: COMPLIST
        !           124: complist_filedialog(VIEW view)
        !           125: {
        !           126:         COMPLIST cl;
        !           127:         OFSTRUCT os1, os2;
        !           128:         char fname[256], FileExt[256], FileOpenSpec[256];
        !           129: 
        !           130:         /* ask for the filenames */
        !           131:         lstrcpy(FileExt, ".c");
        !           132:         lstrcpy(FileOpenSpec, "*.*");
        !           133:         lstrcpy(fname,"");
        !           134: 
        !           135:         if (!complist_open("Select First File", FileExt, FileOpenSpec,
        !           136:                         &os1, fname) )
        !           137:                 return(NULL);
        !           138: 
        !           139:         lstrcpy(FileExt, ".c");
        !           140:         lstrcpy(FileOpenSpec, "*.*");
        !           141:         lstrcpy(fname,"");
        !           142: 
        !           143:         if (!complist_open("Select Second File", FileExt, FileOpenSpec,
        !           144:                         &os2, fname) )
        !           145:                 return(NULL);
        !           146: 
        !           147:         /* alloc a new structure */
        !           148:         cl = complist_new();
        !           149: 
        !           150:         cl->left = dir_buildlist(os1.szPathName, TRUE);
        !           151:         cl->right = dir_buildlist(os2.szPathName, TRUE);
        !           152: 
        !           153: 
        !           154:         /* register with the view (must be done after the list is non-null) */
        !           155:         view_setcomplist(view, cl);
        !           156: 
        !           157:         complist_match(cl, view, FALSE, TRUE);
        !           158: 
        !           159:         return(cl);
        !           160: }/* complist_filedialog */
        !           161: 
        !           162: /***************************************************************************
        !           163:  * Function: complist_dirdialog
        !           164:  *
        !           165:  * Purpose:
        !           166:  *
        !           167:  * Builds a new complist by querying the user for two directory
        !           168:  * names and scanning those in parallel.
        !           169:  *
        !           170:  * Names that match in the same directory will be paired - unmatched
        !           171:  * names will go in a compitem on their own.
        !           172:  *
        !           173:  ***************************************************************************/
        !           174: COMPLIST
        !           175: complist_dirdialog(VIEW view)
        !           176: {
        !           177:         DLGPROC lpProc;
        !           178:         BOOL fOK;
        !           179: 
        !           180:         /* put up a dialog for the two pathnames */
        !           181:         lpProc = (DLGPROC)MakeProcInstance((WNDPROC)complist_dodlg_dir, hInst);
        !           182:         windiff_UI(TRUE);
        !           183:         fOK = DialogBox(hInst, "Directory", hwndClient, lpProc);
        !           184:         windiff_UI(FALSE);
        !           185:         FreeProcInstance(lpProc);
        !           186: 
        !           187:         if (!fOK) {
        !           188:                 return(NULL);
        !           189:         }
        !           190: 
        !           191:         return complist_args( dialog_leftname, dialog_rightname
        !           192:                             , view, FALSE );
        !           193: } /* complist_dirdialog */
        !           194: 
        !           195: 
        !           196: /***************************************************************************
        !           197:  * Function: complist_args
        !           198:  *
        !           199:  * Purpose:
        !           200:  *
        !           201:  * Given two pathname strings, scan the directories and traverse them
        !           202:  * in parallel comparing matching names.
        !           203:  *
        !           204:  ***************************************************************************/
        !           205: COMPLIST
        !           206: complist_args(LPSTR p1, LPSTR p2, VIEW view, BOOL fDeep)
        !           207: {
        !           208:         COMPLIST cl;
        !           209:         char msg[256];
        !           210: 
        !           211: 
        !           212:         /* alloc a new complist */
        !           213:         cl = complist_new();
        !           214: 
        !           215:         cl->left = dir_buildlist(p1, TRUE);
        !           216:         /* check that we could find the paths, and report if not */
        !           217:         if (cl->left == NULL) {
        !           218:                 wsprintf((LPTSTR)msg, "Couldn't find %s", p1);
        !           219:                 MessageBox(NULL, msg, "Error", MB_OK | MB_ICONSTOP);
        !           220:                 return(NULL);
        !           221:         }
        !           222: 
        !           223:         cl->right = dir_buildlist(p2, TRUE);
        !           224:         if (cl->right == NULL) {
        !           225:                 wsprintf((LPTSTR)msg, "Couldn't find %s", p2);
        !           226:                 MessageBox(NULL, msg, "Error", MB_OK | MB_ICONSTOP);
        !           227:                 return(NULL);
        !           228:         }
        !           229: 
        !           230:         /* register with the view (must be done after building lists) */
        !           231:         view_setcomplist(view, cl);
        !           232: 
        !           233:         complist_match(cl, view, fDeep, TRUE);
        !           234: 
        !           235:         return(cl);
        !           236: } /* complist_args */
        !           237: 
        !           238: /***************************************************************************
        !           239:  * Function: complist_getitems
        !           240:  *
        !           241:  * Purpose:
        !           242:  *
        !           243:  * Gets the handle to the list of COMPITEMs. The list continues to be
        !           244:  * owned by the COMPLIST, so don't delete except by calling complist_delete.
        !           245:  *
        !           246:  ***************************************************************************/
        !           247: LIST
        !           248: complist_getitems(COMPLIST cl)
        !           249: {
        !           250:         if (cl == NULL) {
        !           251:                 return(NULL);
        !           252:         }
        !           253: 
        !           254:         return(cl->items);
        !           255: }
        !           256: 
        !           257: /***************************************************************************
        !           258:  * Function: complist_delete
        !           259:  *
        !           260:  * Purpose:
        !           261:  *
        !           262:  * Deletes a complist and all associated CompItems and DIRLISTs. Note this
        !           263:  * does not delete any VIEW - the VIEW owns the COMPLIST and not the other
        !           264:  * way around.
        !           265:  *
        !           266:  **************************************************************************/
        !           267: void
        !           268: complist_delete(COMPLIST cl)
        !           269: {
        !           270:         COMPITEM item;
        !           271: 
        !           272:         if (cl == NULL) {
        !           273:                 return;
        !           274:         }
        !           275: 
        !           276:         /* delete the two directory scan lists */
        !           277:         dir_delete(cl->left);
        !           278:         dir_delete(cl->right);
        !           279: 
        !           280:         /* delete the compitems in the list */
        !           281:         List_TRAVERSE(cl->items, item) {
        !           282:                         compitem_delete(item);
        !           283:         }
        !           284: 
        !           285:         /* delete the list itself */
        !           286:         List_Destroy(&cl->items);
        !           287: 
        !           288:         gmem_free(hHeap, (LPSTR) cl, sizeof(struct complist));
        !           289: 
        !           290: }
        !           291: 
        !           292: /***************************************************************************
        !           293:  * Function: complist_savelist
        !           294:  *
        !           295:  * Purpose:
        !           296:  *
        !           297:  * Writes out to a text file the list of compitems as relative filenames
        !           298:  * one per line.
        !           299:  *
        !           300:  * If savename is non-null, use this as the filename for output; otherwise,
        !           301:  * query the user via a dialog for the filename and include options.
        !           302:  *
        !           303:  **************************************************************************/
        !           304: void
        !           305: complist_savelist(COMPLIST cl, LPSTR savename, UINT options)
        !           306: {
        !           307:         DLGPROC lpProc;
        !           308:         static BOOL done_init = FALSE;
        !           309:         BOOL bOK;
        !           310:         int fh, state;
        !           311:         OFSTRUCT os;
        !           312:         char msg[256];
        !           313:         HCURSOR hcurs;
        !           314:         COMPITEM ci;
        !           315:         LPSTR pstr, lhead, rhead;
        !           316:         int nFiles = 0;
        !           317: 
        !           318:         if (!done_init) {
        !           319:                 /* init the options once round - but keep the same options
        !           320:                  * for the rest of the session.
        !           321:                  */
        !           322: 
        !           323:                 /* first init default options */
        !           324:                 dlg_identical = FALSE;
        !           325:                 dlg_differ = TRUE;
        !           326:                 dlg_left = TRUE;
        !           327:                 dlg_right = FALSE;
        !           328: 
        !           329:                 dlg_file[0] = '\0';
        !           330: 
        !           331:                 done_init = TRUE;
        !           332:         }
        !           333: 
        !           334:         if (cl == NULL) {
        !           335:                 return;
        !           336:         }
        !           337: 
        !           338:         if (savename == NULL) {
        !           339: 
        !           340:                 /* store the left and right rootnames so that dodlg_savelist
        !           341:                  * can display them in the dialog.
        !           342:                  */
        !           343:                 pstr = dir_getroot_list(cl->left);
        !           344:                 lstrcpy(dialog_leftname, pstr);
        !           345:                 dir_freeroot_list(cl->left, pstr);
        !           346: 
        !           347:                 pstr = dir_getroot_list(cl->right);
        !           348:                 lstrcpy(dialog_rightname, pstr);
        !           349:                 dir_freeroot_list(cl->right, pstr);
        !           350: 
        !           351:                 lpProc = (DLGPROC)MakeProcInstance((WNDPROC)complist_dodlg_savelist, hInst);
        !           352:                 windiff_UI(TRUE);
        !           353:                 bOK = DialogBox(hInst, "SaveList", hwndClient, lpProc);
        !           354:                 windiff_UI(FALSE);
        !           355:                 FreeProcInstance(lpProc);
        !           356: 
        !           357:                 if (!bOK) {
        !           358:                         /* user cancelled from dialog box */
        !           359:                         return;
        !           360:                 }
        !           361:                 savename = dlg_file;
        !           362: 
        !           363:         } else {
        !           364:                 dlg_identical = (options & INCLUDE_SAME);
        !           365:                 dlg_differ = (options & INCLUDE_DIFFER);
        !           366:                 dlg_left = (options & INCLUDE_LEFTONLY);
        !           367:                 dlg_right = (options & INCLUDE_RIGHTONLY);
        !           368:         }
        !           369: 
        !           370: 
        !           371:         /* try to open the file */
        !           372:         fh = OpenFile(savename, &os, OF_CREATE|OF_READWRITE|OF_SHARE_DENY_WRITE);
        !           373:         if (fh < 0) {
        !           374:                 wsprintf((LPTSTR)msg, "Cannot open %s", savename);
        !           375:                 windiff_UI(TRUE);
        !           376:                 MessageBox(NULL, msg, "Windiff", MB_ICONSTOP|MB_OK);
        !           377:                 windiff_UI(FALSE);
        !           378:                 return;
        !           379:         }
        !           380: 
        !           381:         hcurs = SetCursor(LoadCursor(NULL, IDC_WAIT));
        !           382: 
        !           383:         /* write out the header line */
        !           384:         lhead = dir_getroot_list(cl->left);
        !           385:         rhead = dir_getroot_list(cl->right);
        !           386:         wsprintf((LPTSTR)msg, "-- %s : %s -- includes %s%s%s%s files\n",
        !           387:                 lhead, rhead,
        !           388:                 (LPSTR) (dlg_identical ? "identical," : ""),
        !           389:                 (LPSTR) (dlg_left ? "left-only," : ""),
        !           390:                 (LPSTR) (dlg_right ? "right-only," : ""),
        !           391:                 (LPSTR) (dlg_differ ? "differing" : "") );
        !           392:         _lwrite(fh, msg, lstrlen(msg));
        !           393:         dir_freeroot_list(cl->left, lhead);
        !           394:         dir_freeroot_list(cl->right, rhead);
        !           395: 
        !           396: 
        !           397:         /* traverse the list of compitems looking for the
        !           398:          * ones we are supposed to include
        !           399:          */
        !           400:         List_TRAVERSE(cl->items, ci) {
        !           401: 
        !           402:                 /* check if files of this type are to be listed */
        !           403:                 state = compitem_getstate(ci);
        !           404: 
        !           405:                 if ((state == STATE_SAME) && (!dlg_identical)) {
        !           406:                         continue;
        !           407:                 } else if ((state == STATE_DIFFER) && (!dlg_differ)) {
        !           408:                         continue;
        !           409:                 } else if ((state == STATE_FILELEFTONLY) && (!dlg_left)) {
        !           410:                         continue;
        !           411:                 } else if ((state == STATE_FILERIGHTONLY) && (!dlg_right)) {
        !           412:                         continue;
        !           413:                 }
        !           414: 
        !           415:                 nFiles++;
        !           416: 
        !           417:                 /* output the list line */
        !           418:                 wsprintf((LPTSTR)msg, "%s", compitem_gettext_tag(ci));
        !           419:                 _lwrite(fh, msg, lstrlen(msg));
        !           420: 
        !           421:                 wsprintf((LPTSTR)msg, "\n");
        !           422:                 _lwrite(fh, msg, strlen(msg));
        !           423:         }
        !           424: 
        !           425:         /* write tail line */
        !           426:         wsprintf((LPTSTR)msg, "-- %d files listed\n", nFiles);
        !           427:         _lwrite(fh, msg, lstrlen(msg));
        !           428: 
        !           429:         /* - close file and we are finished */
        !           430:         _lclose(fh);
        !           431: 
        !           432:         SetCursor(hcurs);
        !           433: } /* complist_savelist */
        !           434: 
        !           435: /***************************************************************************
        !           436:  * Function: complist_copyfiles
        !           437:  *
        !           438:  * Purpose:
        !           439:  *
        !           440:  * To copy files to a new directory newroot. if newroot is NULL, query the user
        !           441:  * via a dialog to get the new dir name and options.
        !           442:  *
        !           443:  * Options are either COPY_FROMLEFT or COPY_FROMRIGHT (indicating which
        !           444:  * tree is to be the source of the files, plus any or all of
        !           445:  * INCLUDE_SAME, INCLUDE_DIFFER and INCLUDE_LEFT (INCLUDE_LEFT
        !           446:  * and INCLUDE_RIGHT are treated the same here since the COPY_FROM* option
        !           447:  * indicates which side to copy from).
        !           448:  *
        !           449:  ***************************************************************************/
        !           450: void
        !           451: complist_copyfiles(COMPLIST cl, LPSTR newroot, UINT options)
        !           452: {
        !           453:         int nFiles = 0;
        !           454:         int nFails = 0;
        !           455:         static BOOL done_init = FALSE;
        !           456:         LPSTR pstr;
        !           457:         char buffer[64];
        !           458:         DIRITEM diritem;
        !           459:         DLGPROC lpProc;
        !           460:         BOOL bOK;
        !           461:         COMPITEM ci;
        !           462:         int state;
        !           463: 
        !           464:         if (!done_init) {
        !           465:                 /*
        !           466:                  * one-time initialisation of dialog defaults
        !           467:                  */
        !           468:                 dlg_options = COPY_FROMLEFT|INCLUDE_LEFTONLY|INCLUDE_DIFFER;
        !           469:                 dlg_root[0] = '\0';
        !           470:                 done_init = TRUE;
        !           471:         }
        !           472: 
        !           473:         if (cl == NULL) {
        !           474:                 return;
        !           475:         }
        !           476: 
        !           477: 
        !           478:         if (newroot == NULL) {
        !           479:                 /*
        !           480:                  * put up dialog to query rootname and options
        !           481:                  */
        !           482: 
        !           483:                 /* store the left and right rootnames so that the dlg proc
        !           484:                  * can display them in the dialog.
        !           485:                  */
        !           486:                 pstr = dir_getroot_list(cl->left);
        !           487:                 lstrcpy(dialog_leftname, pstr);
        !           488:                 dir_freeroot_list(cl->left, pstr);
        !           489: 
        !           490:                 pstr = dir_getroot_list(cl->right);
        !           491:                 lstrcpy(dialog_rightname, pstr);
        !           492:                 dir_freeroot_list(cl->right, pstr);
        !           493: 
        !           494:                 do {
        !           495:                         lpProc = (DLGPROC)MakeProcInstance((WNDPROC)complist_dodlg_copyfiles, hInst);
        !           496:                         windiff_UI(TRUE);
        !           497:                         bOK = DialogBox(hInst, "CopyFiles", hwndClient, lpProc);
        !           498:                         windiff_UI(FALSE);
        !           499:                         FreeProcInstance(lpProc);
        !           500: 
        !           501:                         if (!bOK) {
        !           502:                                 /* user cancelled from dialog box */
        !           503:                                 return;
        !           504:                         }
        !           505:                         if (lstrlen(dlg_root) == 0) {
        !           506:                                 windiff_UI(TRUE);
        !           507:                                 MessageBox(NULL, "Please enter the directory name",
        !           508:                                                 "Windiff", MB_ICONSTOP|MB_OK);
        !           509:                                 windiff_UI(FALSE);
        !           510:                         }
        !           511:                 } while (lstrlen(dlg_root) == 0);
        !           512: 
        !           513:         } else {
        !           514:                 dlg_options = options;
        !           515:                 lstrcpy(dlg_root, newroot);
        !           516:         }
        !           517: 
        !           518:         TickCount = GetTickCount();
        !           519: 
        !           520:         if (dlg_options & COPY_FROMLEFT) {
        !           521:                 if (!dir_startcopy(cl->left))
        !           522:                         return;
        !           523:         } else {
        !           524:                 if (!dir_startcopy(cl->right))
        !           525:                         return;
        !           526:         }
        !           527: 
        !           528:         /*
        !           529:          * traverse the list of compitems copying files as necessary
        !           530:          */
        !           531:         List_TRAVERSE(cl->items, ci) {
        !           532: 
        !           533:                 if (bAbort){
        !           534:                         break;  /* fall into end_copy processing */
        !           535:                 }
        !           536:                 /* check if files of this type are to be copied */
        !           537:                 state = compitem_getstate(ci);
        !           538: 
        !           539:                 if ((state == STATE_SAME) && !(dlg_options & INCLUDE_SAME)) {
        !           540:                         continue;
        !           541:                 } else if ((state == STATE_DIFFER) && !(dlg_options & INCLUDE_DIFFER)) {
        !           542:                         continue;
        !           543:                 } else if (state == STATE_FILELEFTONLY) {
        !           544:                         if (dlg_options & COPY_FROMRIGHT) {
        !           545:                                 continue;
        !           546:                         }
        !           547:                         if ((dlg_options & (INCLUDE_LEFTONLY | INCLUDE_RIGHTONLY)) == 0) {
        !           548:                                 continue;
        !           549:                         }
        !           550:                 } else if (state == STATE_FILERIGHTONLY) {
        !           551:                         if (dlg_options & COPY_FROMLEFT) {
        !           552:                                 continue;
        !           553:                         }
        !           554:                         if ((dlg_options & (INCLUDE_LEFTONLY | INCLUDE_RIGHTONLY)) == 0) {
        !           555:                                 continue;
        !           556:                         }
        !           557:                 }
        !           558: 
        !           559:                 if (dlg_options & COPY_FROMLEFT) {
        !           560:                         diritem = file_getdiritem(compitem_getleftfile(ci));
        !           561:                 } else {
        !           562:                         diritem = file_getdiritem(compitem_getrightfile(ci));
        !           563:                 }
        !           564: 
        !           565:                 /*
        !           566:                  * copy the file to the new root directory
        !           567:                  */
        !           568:                 if (dir_copy(diritem, dlg_root) == FALSE) {
        !           569:                         nFails++;
        !           570:                         pstr = dir_getrelname(diritem);
        !           571:                         wsprintf((LPTSTR)buffer, "failed to copy %s", pstr);
        !           572:                         dir_freerelname(diritem, pstr);
        !           573: 
        !           574:                         if (MessageBox(NULL, buffer, "Error", MB_OKCANCEL | MB_ICONSTOP) == IDCANCEL)
        !           575:                             /* user pressed cancel - abort current operation*/
        !           576:                             /* fall through to end-copy processing */
        !           577:                             break;
        !           578: 
        !           579:                 } else {
        !           580:                         nFiles++;
        !           581:                 }
        !           582: 
        !           583:                 wsprintf((LPTSTR)buffer, "%4d files requested. Copying...", nFiles);
        !           584:                 SetStatus(buffer);
        !           585: 
        !           586: 
        !           587:                 /*
        !           588:                  * allow user interface to continue
        !           589:                  */
        !           590:                 if (Poll()) {
        !           591:                         /* abort requested */
        !           592:                         TickCount = GetTickCount()-TickCount;
        !           593:                         windiff_UI(TRUE);
        !           594:                         MessageBox(hwndClient, "Copy Aborted",
        !           595:                                 "WinDiff", MB_OK|MB_ICONINFORMATION);
        !           596:                         windiff_UI(FALSE);
        !           597:                         break;
        !           598:                 }
        !           599: 
        !           600:         } /* traverse */
        !           601:         if (dlg_options & COPY_FROMLEFT) {
        !           602:                 nFails = dir_endcopy(cl->left);
        !           603:         } else {
        !           604:                 nFails = dir_endcopy(cl->right);
        !           605:         }
        !           606:         TickCount = GetTickCount()-TickCount;
        !           607: 
        !           608:         if (nFails<0) {
        !           609:                 wsprintf((LPTSTR)buffer, "Copy Complete: %d files failed", -nFails);
        !           610:         } else {
        !           611:                 wsprintf((LPTSTR)buffer, "Copy Complete %d files copied", nFails);
        !           612:         }
        !           613:         windiff_UI(TRUE);
        !           614:         MessageBox(hwndClient, buffer, "WinDiff", MB_OK|MB_ICONINFORMATION);
        !           615:         windiff_UI(FALSE);
        !           616: 
        !           617:         buffer[0] = '\0';
        !           618:         SetStatus(buffer);
        !           619: } /* complist_copyfiles */
        !           620: 
        !           621: 
        !           622: /***************************************************************************
        !           623:  * Function: complist_match
        !           624:  *
        !           625:  * Purpose:
        !           626:  *
        !           627:  * Matches up two lists of filenames
        !           628:  *
        !           629:  * Commentsz:
        !           630:  *
        !           631:  * We can find out from the DIRLIST handle whether the original list
        !           632:  * was a file or a directory name.
        !           633:  * If the user typed:
        !           634:  *      two file names  - match these two item even if the names differ
        !           635:  *
        !           636:  *      two dirs        - match only those items whose names match
        !           637:  *
        !           638:  *      one file and one dir
        !           639:  *                      - try to find a file of that name in the dir.
        !           640:  *
        !           641:  * This function returns TRUE if the complist_match was ok, or FALSE if it was
        !           642:  * aborted in some way.
        !           643:  *
        !           644:  ***************************************************************************/
        !           645: BOOL
        !           646: complist_match(COMPLIST cl, VIEW view, BOOL fDeep, BOOL fExact)
        !           647: {
        !           648:         LPSTR lname;
        !           649:         LPSTR rname;
        !           650:         DIRITEM leftitem, rightitem;
        !           651:         int cmpvalue;
        !           652: 
        !           653:         TickCount = GetTickCount();
        !           654: 
        !           655:         if (dir_isfile(cl->left) ) {
        !           656: 
        !           657:                 if (dir_isfile(cl->right)) {
        !           658:                         /* two files */
        !           659: 
        !           660:                         /* there should be one item in each list - make
        !           661:                          * a compitem by matching these two and append it to the
        !           662:                          * list
        !           663:                          */
        !           664:                         compitem_new(dir_firstitem(cl->left),
        !           665:                                        dir_firstitem(cl->right), cl->items, fExact);
        !           666: 
        !           667:                         view_newitem(view);
        !           668: 
        !           669:                         TickCount = GetTickCount() - TickCount;
        !           670:                         return TRUE;
        !           671:                 }
        !           672:                 /* left is file, right is dir */
        !           673:                 leftitem = dir_firstitem(cl->left);
        !           674:                 rightitem = dir_firstitem(cl->right);
        !           675:                 lname = dir_getrelname(leftitem);
        !           676:                 while (rightitem != NULL) {
        !           677:                         rname = dir_getrelname(rightitem);
        !           678:                         cmpvalue = lstrcmpi(lname, rname);
        !           679:                         dir_freerelname(rightitem, rname);
        !           680: 
        !           681:                         if (cmpvalue == 0) {
        !           682:                                 /* this is the match */
        !           683:                                 compitem_new(leftitem, rightitem, cl->items, fExact);
        !           684:                                 view_newitem(view);
        !           685: 
        !           686:                                 dir_freerelname(leftitem, lname);
        !           687: 
        !           688:                                 TickCount = GetTickCount() - TickCount;
        !           689:                                 return(TRUE);
        !           690:                         }
        !           691: 
        !           692:                         rightitem = dir_nextitem(cl->right, rightitem, fDeep);
        !           693:                 }
        !           694:                 /* not found */
        !           695:                 dir_freerelname(leftitem, lname);
        !           696:                 compitem_new(leftitem, NULL, cl->items, fExact);
        !           697:                 view_newitem(view);
        !           698:                 TickCount = GetTickCount() - TickCount;
        !           699:                 return(TRUE);
        !           700: 
        !           701:         } else if (dir_isfile(cl->right)) {
        !           702: 
        !           703:                 /* left is dir, right is file */
        !           704: 
        !           705:                 /* loop through the left dir, looking for
        !           706:                  * a file that has the same name as rightitem
        !           707:                  */
        !           708: 
        !           709:                 leftitem = dir_firstitem(cl->left);
        !           710:                 rightitem = dir_firstitem(cl->right);
        !           711:                 rname = dir_getrelname(rightitem);
        !           712:                 while (leftitem != NULL) {
        !           713:                         lname = dir_getrelname(leftitem);
        !           714:                         cmpvalue = lstrcmpi(lname, rname);
        !           715:                         dir_freerelname(leftitem, lname);
        !           716: 
        !           717:                         if (cmpvalue == 0) {
        !           718:                                 /* this is the match */
        !           719:                                 compitem_new(leftitem, rightitem, cl->items, fExact);
        !           720:                                 view_newitem(view);
        !           721: 
        !           722:                                 dir_freerelname(rightitem, rname);
        !           723: 
        !           724:                                 TickCount = GetTickCount() - TickCount;
        !           725:                                 return(TRUE);
        !           726:                         }
        !           727: 
        !           728:                         leftitem = dir_nextitem(cl->left, leftitem, fDeep);
        !           729:                 }
        !           730:                 /* not found */
        !           731:                 dir_freerelname(rightitem, rname);
        !           732:                 compitem_new(NULL, rightitem, cl->items, fExact);
        !           733:                 view_newitem(view);
        !           734:                 TickCount = GetTickCount() - TickCount;
        !           735:                 return(TRUE);
        !           736:         }
        !           737: 
        !           738:         /* two directories */
        !           739: 
        !           740:         /* traverse the two lists in parallel comparing the relative names*/
        !           741: 
        !           742:         leftitem = dir_firstitem(cl->left);
        !           743:         rightitem = dir_firstitem(cl->right);
        !           744:         while ((leftitem != NULL) && (rightitem != NULL)) {
        !           745: 
        !           746:                 lname = dir_getrelname(leftitem);
        !           747:                 rname = dir_getrelname(rightitem);
        !           748:                 cmpvalue = utils_CompPath(lname, rname);
        !           749:                 dir_freerelname(leftitem, lname);
        !           750:                 dir_freerelname(rightitem, rname);
        !           751: 
        !           752:                 if (cmpvalue == 0) {
        !           753:                         compitem_new(leftitem, rightitem, cl->items, fExact);
        !           754:                         if (view_newitem(view)) {
        !           755:                                 TickCount = GetTickCount() - TickCount;
        !           756:                                 return(FALSE);
        !           757:                         }
        !           758:                         leftitem = dir_nextitem(cl->left, leftitem, fDeep);
        !           759:                         rightitem = dir_nextitem(cl->right, rightitem, fDeep);
        !           760: 
        !           761:                 } else if (cmpvalue < 0) {
        !           762:                         compitem_new(leftitem, NULL, cl->items, fExact);
        !           763:                         if (view_newitem(view)) {
        !           764:                                 TickCount = GetTickCount() - TickCount;
        !           765:                                 return(FALSE);
        !           766:                         }
        !           767:                         leftitem = dir_nextitem(cl->left, leftitem, fDeep);
        !           768:                 }  else {
        !           769:                         compitem_new(NULL, rightitem, cl->items, fExact);
        !           770:                         if (view_newitem(view)) {
        !           771:                                 TickCount = GetTickCount() - TickCount;
        !           772:                                 return(FALSE);
        !           773:                         }
        !           774:                         rightitem = dir_nextitem(cl->right, rightitem, fDeep);
        !           775:                 }
        !           776:         }
        !           777: 
        !           778: 
        !           779:         /* any left over are unmatched */
        !           780:         while (leftitem != NULL) {
        !           781:                 compitem_new(leftitem, NULL, cl->items, fExact);
        !           782:                 if (view_newitem(view)) {
        !           783:                         TickCount = GetTickCount() - TickCount;
        !           784:                         return(FALSE);
        !           785:                 }
        !           786:                 leftitem = dir_nextitem(cl->left, leftitem, fDeep);
        !           787:         }
        !           788:         while (rightitem != NULL) {
        !           789:                 compitem_new(NULL, rightitem, cl->items, fExact);
        !           790:                 if (view_newitem(view)) {
        !           791:                         TickCount = GetTickCount() - TickCount;
        !           792:                         return(FALSE);
        !           793:                 }
        !           794:                 rightitem = dir_nextitem(cl->right, rightitem, fDeep);
        !           795:         }
        !           796:         TickCount = GetTickCount() - TickCount;
        !           797:         return(TRUE);
        !           798: } /* complist_match */
        !           799: 
        !           800: /* return time last operation took in milliseconds */
        !           801: DWORD complist_querytime(void)
        !           802: {       return TickCount;
        !           803: }
        !           804: 
        !           805: 
        !           806: /***************************************************************************
        !           807:  * Function: complist_dodlg_savelist
        !           808:  *
        !           809:  * Purpose:
        !           810:  *
        !           811:  * Dialog to query about filename and types of files. Init dlg fields from
        !           812:  * the dlg_* variables, and save state to the dlg_* variables on dialog
        !           813:  * close. return TRUE for OK, or FALSE for cancel (from the dialogbox()
        !           814:  * using EndDialog).
        !           815:  *
        !           816:  **************************************************************************/
        !           817: int FAR PASCAL
        !           818: complist_dodlg_savelist(HWND hDlg, UINT message, UINT wParam, long lParam)
        !           819: {
        !           820:         static char buffer[256];
        !           821: 
        !           822:         switch(message) {
        !           823: 
        !           824: 
        !           825:         case WM_INITDIALOG:
        !           826:                 SendDlgItemMessage(hDlg, IDD_IDENTICAL, BM_SETCHECK,
        !           827:                         dlg_identical ? 1 : 0, 0);
        !           828:                 SendDlgItemMessage(hDlg, IDD_DIFFER, BM_SETCHECK,
        !           829:                         dlg_differ ? 1 : 0, 0);
        !           830:                 SendDlgItemMessage(hDlg, IDD_LEFT, BM_SETCHECK,
        !           831:                         dlg_left ? 1 : 0, 0);
        !           832:                 SendDlgItemMessage(hDlg, IDD_RIGHT, BM_SETCHECK,
        !           833:                         dlg_right ? 1 : 0, 0);
        !           834: 
        !           835:                 SetDlgItemText(hDlg, IDD_FILE, dlg_file);
        !           836: 
        !           837:                 /* convert 'left tree' into the right name */
        !           838:                 wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_leftname);
        !           839:                 SendDlgItemMessage(hDlg, IDD_LEFT, WM_SETTEXT, 0, (DWORD) (LPSTR) buffer);
        !           840: 
        !           841:                 /* convert 'right tree' msg into correct path */
        !           842:                 wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_rightname);
        !           843:                 SendDlgItemMessage(hDlg, IDD_RIGHT, WM_SETTEXT, 0, (DWORD) (LPSTR) buffer);
        !           844: 
        !           845: 
        !           846:                 return(TRUE);
        !           847: 
        !           848:         case WM_COMMAND:
        !           849:                 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
        !           850: 
        !           851:                 case IDOK:
        !           852:                         dlg_identical = (SendDlgItemMessage(hDlg, IDD_IDENTICAL,
        !           853:                                         BM_GETCHECK, 0, 0) == 1);
        !           854:                         dlg_differ = (SendDlgItemMessage(hDlg, IDD_DIFFER,
        !           855:                                         BM_GETCHECK, 0, 0) == 1);
        !           856:                         dlg_left = (SendDlgItemMessage(hDlg, IDD_LEFT,
        !           857:                                         BM_GETCHECK, 0, 0) == 1);
        !           858:                         dlg_right = (SendDlgItemMessage(hDlg, IDD_RIGHT,
        !           859:                                         BM_GETCHECK, 0, 0) == 1);
        !           860:                         GetDlgItemText(hDlg, IDD_FILE, dlg_file, sizeof(dlg_file));
        !           861: 
        !           862:                         EndDialog(hDlg, TRUE);
        !           863:                         break;
        !           864: 
        !           865:                 case IDCANCEL:
        !           866:                         EndDialog(hDlg, FALSE);
        !           867:                         break;
        !           868:                 }
        !           869:         }
        !           870:         return(FALSE);
        !           871: } /* complist_dodlg_savelist */
        !           872: 
        !           873: /***************************************************************************
        !           874:  * Function: complist_dodlg_copyfiles
        !           875:  *
        !           876:  * Purpose:
        !           877:  *
        !           878:  * dialog to get directory name and inclusion options. Init dlg fields from
        !           879:  * the dlg_* variables, and save state to the dlg_* variables on dialog
        !           880:  * close. return TRUE for OK, or FALSE for cancel (from the dialogbox()
        !           881:  * using EndDialog).
        !           882:  * 
        !           883:  **************************************************************************/
        !           884: int FAR PASCAL
        !           885: complist_dodlg_copyfiles(HWND hDlg, UINT message, UINT wParam, long lParam)
        !           886: {
        !           887:         static char buffer[256];
        !           888: 
        !           889:         switch(message) {
        !           890: 
        !           891: 
        !           892:         case WM_INITDIALOG:
        !           893:                 /*
        !           894:                  * set checkboxes and directory field to defaults
        !           895:                  */
        !           896:                 CheckDlgButton(hDlg, IDD_IDENTICAL,
        !           897:                         (dlg_options & INCLUDE_SAME) ? 1 : 0);
        !           898: 
        !           899:                 CheckDlgButton(hDlg, IDD_DIFFER,
        !           900:                         (dlg_options & INCLUDE_DIFFER) ? 1 : 0);
        !           901: 
        !           902:                 CheckDlgButton(hDlg, IDD_LEFT,
        !           903:                         (dlg_options & (INCLUDE_LEFTONLY|INCLUDE_RIGHTONLY)) ? 1 : 0);
        !           904: 
        !           905:                 SetDlgItemText(hDlg, IDD_DIR1, dlg_root);
        !           906: 
        !           907:                 /*
        !           908:                  * set 'copy from' buttons to have the full pathname
        !           909:                  */
        !           910:                 SetDlgItemText(hDlg, IDD_FROMLEFT, dialog_leftname);
        !           911:                 SetDlgItemText(hDlg, IDD_FROMRIGHT, dialog_rightname);
        !           912: 
        !           913:                 /*
        !           914:                  * set default radio button for copy from, and set
        !           915:                  * the text on the 'files only in...' checkbox to
        !           916:                  * indicate which path is being selected
        !           917:                  */
        !           918:                 if (dlg_options & COPY_FROMLEFT) {
        !           919:                         CheckRadioButton(hDlg, IDD_FROMLEFT, IDD_FROMRIGHT,
        !           920:                                         IDD_FROMLEFT);
        !           921: 
        !           922:                         wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_leftname);
        !           923:                         SetDlgItemText(hDlg, IDD_LEFT, buffer);
        !           924:                 } else {
        !           925:                         CheckRadioButton(hDlg, IDD_FROMLEFT, IDD_FROMRIGHT,
        !           926:                                         IDD_FROMRIGHT);
        !           927: 
        !           928:                         wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_rightname);
        !           929:                         SetDlgItemText(hDlg, IDD_LEFT, buffer);
        !           930:                 }
        !           931: 
        !           932:                 return(TRUE);
        !           933: 
        !           934:         case WM_COMMAND:
        !           935:                 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
        !           936: 
        !           937:                 case IDD_FROMLEFT:
        !           938:                         wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_leftname);
        !           939:                         SetDlgItemText(hDlg, IDD_LEFT, buffer);
        !           940: 
        !           941:                         dlg_options &= ~(COPY_FROMRIGHT);
        !           942:                         dlg_options |= COPY_FROMLEFT;
        !           943:                         break;
        !           944: 
        !           945:                 case IDD_FROMRIGHT:
        !           946:                         wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_rightname);
        !           947:                         SetDlgItemText(hDlg, IDD_LEFT, buffer);
        !           948: 
        !           949:                         dlg_options &= ~(COPY_FROMLEFT);
        !           950:                         dlg_options |= COPY_FROMRIGHT;
        !           951:                         break;
        !           952: 
        !           953:                 case IDOK:
        !           954:                         if (SendDlgItemMessage(hDlg, IDD_IDENTICAL,
        !           955:                             BM_GETCHECK, 0, 0) == 1) {
        !           956:                                 dlg_options |= INCLUDE_SAME;
        !           957:                         } else {
        !           958:                                 dlg_options &= ~INCLUDE_SAME;
        !           959:                         }
        !           960:                         if (SendDlgItemMessage(hDlg, IDD_DIFFER,
        !           961:                             BM_GETCHECK, 0, 0) == 1) {
        !           962:                                 dlg_options |= INCLUDE_DIFFER;
        !           963:                         } else {
        !           964:                                 dlg_options &= ~INCLUDE_DIFFER;
        !           965:                         }
        !           966:                         if (SendDlgItemMessage(hDlg, IDD_LEFT,
        !           967:                             BM_GETCHECK, 0, 0) == 1) {
        !           968:                                 dlg_options |= INCLUDE_LEFTONLY;
        !           969:                         } else {
        !           970:                                 dlg_options &= ~INCLUDE_LEFTONLY;
        !           971:                         }
        !           972:                         GetDlgItemText(hDlg, IDD_DIR1, dlg_root, sizeof(dlg_root));
        !           973: 
        !           974:                         EndDialog(hDlg, TRUE);
        !           975:                         break;
        !           976: 
        !           977:                 case IDCANCEL:
        !           978:                         EndDialog(hDlg, FALSE);
        !           979:                         break;
        !           980:                 }
        !           981:         }
        !           982:         return(FALSE);
        !           983: } /* complist_dodlg_copyfiles */
        !           984: 
        !           985: /***************************************************************************
        !           986:  * Function: complist_new
        !           987:  *
        !           988:  * Purpose:
        !           989:  *
        !           990:  * Allocates a new complist and initialise it 
        !           991:  *
        !           992:  **************************************************************************/
        !           993: COMPLIST
        !           994: complist_new(void)
        !           995: {
        !           996:         COMPLIST cl;
        !           997: 
        !           998:         cl = (COMPLIST) gmem_get(hHeap, sizeof(struct complist));
        !           999:         cl->left = NULL;
        !          1000:         cl->right = NULL;
        !          1001:         cl->items = List_Create();
        !          1002: 
        !          1003:         return(cl);
        !          1004: } /* complist_new */
        !          1005: 
        !          1006: /***************************************************************************
        !          1007:  * Function: complist_dodlg_dir
        !          1008:  *
        !          1009:  * Purpose:
        !          1010:  *
        !          1011:  * Dialog box function to ask for two directory names.
        !          1012:  * no listing of files etc - just two edit fields  in which the
        !          1013:  * user can type a file or a directory name.
        !          1014:  *
        !          1015:  * Initialises the names from win.ini, and stores them to win.ini first.
        !          1016:  *
        !          1017:  **************************************************************************/
        !          1018: int FAR PASCAL
        !          1019: complist_dodlg_dir(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
        !          1020: {
        !          1021:         static char path[256];
        !          1022:         static char buffer[256];
        !          1023: 
        !          1024:         switch (message) {
        !          1025: 
        !          1026:         case WM_INITDIALOG:
        !          1027: 
        !          1028:                 /* fill the edit fields with the current
        !          1029:                  * directory as a good starting point
        !          1030:                  */
        !          1031:                 _getcwd(path, sizeof(path));
        !          1032:                 AnsiLowerBuff(path, strlen(path));
        !          1033:                 GetProfileString(APPNAME, "NameLeft", path, buffer, 256);
        !          1034:                 SetDlgItemText(hDlg, IDD_DIR1, buffer);
        !          1035:                 GetProfileString(APPNAME, "NameRight", path, buffer, 256);
        !          1036:                 SetDlgItemText(hDlg, IDD_DIR2, buffer);
        !          1037:                 return(TRUE);
        !          1038: 
        !          1039:         case WM_COMMAND:
        !          1040:                 switch (LOWORD(wParam)) {
        !          1041:                 case IDCANCEL:
        !          1042:                         EndDialog(hDlg, FALSE);
        !          1043:                         return(TRUE);
        !          1044: 
        !          1045:                 case IDOK:
        !          1046:                         /* fetch the text from the dialog, and remember
        !          1047:                          * it in win.ini
        !          1048:                          */
        !          1049: 
        !          1050:                         GetDlgItemText(hDlg, IDD_DIR1,
        !          1051:                                 dialog_leftname, sizeof(dialog_leftname));
        !          1052:                         WriteProfileString(APPNAME, "NameLeft", dialog_leftname);
        !          1053: 
        !          1054:                         GetDlgItemText(hDlg, IDD_DIR2,
        !          1055:                                 dialog_rightname, sizeof(dialog_rightname));
        !          1056: 
        !          1057:                         EndDialog(hDlg, TRUE);
        !          1058:                         return(TRUE);
        !          1059:                 }
        !          1060:                 break;
        !          1061:         }
        !          1062:         return(FALSE);
        !          1063: } /* complist_dodlg_dir */
        !          1064: 
        !          1065: /***************************************************************************
        !          1066:  * Function: complist_open
        !          1067:  *
        !          1068:  * Purpose:
        !          1069:  *      
        !          1070:  * Puts up dialog asking the user to select an existing file to open.
        !          1071:  *
        !          1072:  * Parameters:
        !          1073:  *
        !          1074:  *      prompt - message to user indicating purpose of file
        !          1075:  *               (to be displayed somewhere in dialog box.
        !          1076:  *
        !          1077:  *      ext    - default file extension if user enters file without
        !          1078:  *               extension.
        !          1079:  *
        !          1080:  *      spec   - default file spec (eg *.*)
        !          1081:  *
        !          1082:  *      osp    - OFSTRUCT representing file, if successfully open.
        !          1083:  *
        !          1084:  *      fn     - buffer where filename (just final element) is returned.
        !          1085:  *
        !          1086:  * Returns:
        !          1087:  *
        !          1088:  * TRUE - if file selected and exists (tested with OF_EXIST).
        !          1089:  *
        !          1090:  * FALSE - if dialog cancelled. If user selects a file that we cannot
        !          1091:  *           open, we complain and restart the dialog.
        !          1092:  *
        !          1093:  * Comments:
        !          1094:  *
        !          1095:  *           if TRUE is returned, the file will have been successfully opened,
        !          1096:  *           for reading and then closed again.
        !          1097:  *
        !          1098:  **************************************************************************/
        !          1099: 
        !          1100: BOOL FAR PASCAL
        !          1101: complist_open(LPSTR prompt, LPSTR ext, LPSTR spec, OFSTRUCT FAR *osp, LPSTR fn)
        !          1102: {
        !          1103:     OPENFILENAME ofn;
        !          1104:     char achFilters[256];
        !          1105:     char achPath[256];
        !          1106:     LPSTR chp;
        !          1107:     int fh;
        !          1108: 
        !          1109:     /* build filter-pair buffer to contain one pair - the spec filter,
        !          1110:      * twice (one of the pair should be the filter, the second should be
        !          1111:      * the title of the filter - we don't have a title so we use the
        !          1112:      * filter both times. remember double null at end of list of strings.
        !          1113:      */
        !          1114:     lstrcpy(achFilters, spec);             // filter + null
        !          1115:     chp = &achFilters[lstrlen(achFilters)+1];      //2nd string just after null
        !          1116:     lstrcpy(chp, spec);                    // filter name (+null)
        !          1117:     chp[lstrlen(chp)+1] = '\0';            // double null at end of list
        !          1118:     /*
        !          1119:      * initialise arguments to dialog proc
        !          1120:      */
        !          1121:     ofn.lStructSize = sizeof(OPENFILENAME);
        !          1122:     ofn.hwndOwner = NULL;
        !          1123:     ofn.hInstance = NULL;
        !          1124:     ofn.lpstrFilter = achFilters;
        !          1125:     ofn.lpstrCustomFilter = (LPSTR)NULL;
        !          1126:     ofn.nMaxCustFilter = 0L;
        !          1127:     ofn.nFilterIndex = 1L;              // first filter pair in list
        !          1128:     achPath[0] = '\0';
        !          1129:     ofn.lpstrFile = achPath;            // we need to get the full path to open
        !          1130:     ofn.nMaxFile = sizeof(achPath);
        !          1131:     ofn.lpstrFileTitle = fn;            // return final elem of name here
        !          1132:     ofn.nMaxFileTitle = sizeof(fn);
        !          1133:     ofn.lpstrInitialDir = NULL;
        !          1134:     ofn.lpstrTitle = prompt;            // dialog title is good place for prompt text
        !          1135:     ofn.Flags = OFN_FILEMUSTEXIST |
        !          1136:                 OFN_HIDEREADONLY |
        !          1137:                 OFN_PATHMUSTEXIST;
        !          1138:     ofn.lpstrDefExt = ext;
        !          1139:     ofn.nFileOffset = 0;
        !          1140:     ofn.nFileExtension = 0;
        !          1141:     ofn.lCustData = 0;
        !          1142: 
        !          1143:     /*
        !          1144:      * loop until the user cancels, or selects a file that we can open
        !          1145:      */
        !          1146:     do {
        !          1147:         if (!GetOpenFileName(&ofn)) {
        !          1148:             return(FALSE);
        !          1149:         }
        !          1150: 
        !          1151:         fh = OpenFile(achPath, osp, OF_READ);
        !          1152:         
        !          1153:         if (fh == HFILE_ERROR) {
        !          1154:             if (MessageBox(NULL, "File Could Not Be Opened", "File Open",
        !          1155:                             MB_OKCANCEL|MB_ICONSTOP) == IDCANCEL) {
        !          1156:                 return(FALSE);
        !          1157:             }
        !          1158:         }
        !          1159:     } while (fh == HFILE_ERROR);
        !          1160: 
        !          1161:     _lclose(fh);
        !          1162: 
        !          1163:     return(TRUE);
        !          1164: }
        !          1165: 
        !          1166: /***************************************************************************
        !          1167:  * Function: complist_getroot_left
        !          1168:  *
        !          1169:  * Purpose:
        !          1170:  *
        !          1171:  * Gets the root names of the left tree used to build this complist.
        !          1172:  *
        !          1173:  **************************************************************************/
        !          1174: LPSTR
        !          1175: complist_getroot_left(COMPLIST cl)
        !          1176: {
        !          1177:         return( dir_getroot_list(cl->left));
        !          1178: }
        !          1179: 
        !          1180: /***************************************************************************
        !          1181:  * Function: complist_getroot_right
        !          1182:  *
        !          1183:  * Purpose:
        !          1184:  *
        !          1185:  * Gets the root names of the right tree used to build this complist.
        !          1186:  *
        !          1187:  **************************************************************************/
        !          1188: LPSTR
        !          1189: complist_getroot_right(COMPLIST cl)
        !          1190: {
        !          1191:         return( dir_getroot_list(cl->right));
        !          1192: }
        !          1193: /***************************************************************************
        !          1194:  * Function: complist_freeroot_*
        !          1195:  *
        !          1196:  * Purpose:
        !          1197:  *
        !          1198:  * Frees up memory allocated in a call to complist_getroot*() 
        !          1199:  *
        !          1200:  **************************************************************************/
        !          1201: void
        !          1202: complist_freeroot_left(COMPLIST cl, LPSTR path)
        !          1203: {
        !          1204:         dir_freeroot_list(cl->left, path);
        !          1205: }
        !          1206: 
        !          1207: void
        !          1208: complist_freeroot_right(COMPLIST cl, LPSTR path)
        !          1209: {
        !          1210:         dir_freeroot_list(cl->right, path);
        !          1211: }
        !          1212: 
        !          1213: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.