source: trunk/dll/comp.c @ 751

Last change on this file since 751 was 751, checked in by Steven Levine, 13 years ago

Sync rest of code with CNRITEM mods
Sync code with ARCITEM mods
Get compare dialog working
Still some issues with status display
Still some issues with directory sizes tree display
Heap check diagnostic code mostly enabled

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 86.4 KB
Line 
1
2/***********************************************************************
3
4  $Id: comp.c 751 2007-08-02 23:05:48Z stevenhl $
5
6  Compare directories
7
8  Copyright (c) 1993-02 M. Kimes
9  Copyright (c) 2003, 2007 Steven H. Levine
10
11  16 Oct 02 MK Baseline
12  04 Nov 03 SHL Force window refresh after subdir toggle
13  01 Aug 04 SHL Rework lstrip/rstrip usage
14  24 May 05 SHL Rework Win_Error usage
15  24 May 05 SHL Rework for CNRITEM.szSubject
16  25 May 05 SHL Rework with ULONGLONG
17  06 Jun 05 SHL Drop unused
18  12 Jul 06 SHL Renames and comments
19  13 Jul 06 SHL Use Runtime_Error
20  26 Jul 06 SHL Drop unreachable CN_... code
21  29 Jul 06 SHL Use xfgets_bstripcr
22  15 Aug 06 SHL Turn off hide not selected on dir change
23  19 Oct 06 SHL Correct . and .. detect
24  03 Nov 06 SHL Count thread usage
25  22 Mar 07 GKY Use QWL_USER
26  29 Jul 07 SHL Use Win_Error to report container errors
27  01 Aug 07 SHL Rework to sync with CNRITEM mods
28  01 Aug 07 SHL Rework to remove vast amount of duplicate code
29
30***********************************************************************/
31
32#define INCL_DOS
33#define INCL_WIN
34#define INCL_GPI
35#define INCL_LONGLONG
36#include <os2.h>
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <ctype.h>
42#include <share.h>
43#include <io.h>
44#include <process.h>                    // _beginthread
45
46#include "fm3dll.h"
47#include "fm3dlg.h"
48#include "fm3str.h"
49
50#pragma alloc_text(COMPAREDIR,FillCnrsThread,FillDirList,CompNames)
51#pragma alloc_text(COMPAREDIR1,CompareDlgProc)
52#pragma alloc_text(COMPAREDIR2,SelectCnrsThread,ActionCnrThread)
53#pragma alloc_text(COMPAREFILE,CFileDlgProc,CompareFilesThread)
54#pragma alloc_text(SNAPSHOT,SnapShot,StartSnap)
55
56typedef struct
57{
58  CHAR filename[CCHMAXPATH];
59  CHAR dirname[CCHMAXPATH];
60  BOOL recurse;
61}
62SNAPSTUFF;
63
64static PSZ pszSrcFile = __FILE__;
65
66//=== SnapShot() Write directory tree to file and recurse if requested ===
67
68static VOID SnapShot(char *path, FILE * fp, BOOL recurse)
69{
70  FILEFINDBUF4 *fb;
71  char *mask, *enddir;
72  HDIR hdir = HDIR_CREATE;
73  ULONG nm = 1L;
74
75  fb = xmalloc(sizeof(FILEFINDBUF4), pszSrcFile, __LINE__);
76  if (fb) {
77    mask = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
78    if (mask) {
79      sprintf(mask,
80              "%s%s*",
81              path, (path[strlen(path) - 1] != '\\') ? "\\" : NullStr);
82      enddir = strrchr(mask, '\\');
83      enddir++;
84      if (!DosFindFirst(mask,
85                        &hdir,
86                        FILE_NORMAL | FILE_DIRECTORY |
87                        FILE_ARCHIVED | FILE_READONLY | FILE_HIDDEN |
88                        FILE_SYSTEM,
89                        fb, sizeof(FILEFINDBUF4), &nm, FIL_QUERYEASIZE)) {
90        do {
91          strcpy(enddir, fb->achName);
92          if (!(fb->attrFile & FILE_DIRECTORY))
93            fprintf(fp,
94                    "\"%s\",%u,%lu,%04u/%02u/%02u,%02u:%02u:%02u,%lu,%lu,N\n",
95                    mask,
96                    enddir - mask,
97                    fb->cbFile,
98                    (fb->fdateLastWrite.year + 1980),
99                    fb->fdateLastWrite.month,
100                    fb->fdateLastWrite.day,
101                    fb->ftimeLastWrite.hours,
102                    fb->ftimeLastWrite.minutes,
103                    fb->ftimeLastWrite.twosecs,
104                    fb->attrFile, (fb->cbList > 4L) ? (fb->cbList / 2L) : 0L);
105          // Skip . and ..
106          else if (recurse &&
107                   (fb->achName[0] != '.' ||
108                    (fb->achName[1] &&
109                     (fb->achName[1] != '.' || fb->achName[2])))) {
110            SnapShot(mask, fp, recurse);
111          }
112          nm = 1L;
113        } while (!DosFindNext(hdir, fb, sizeof(FILEFINDBUF4), &nm));
114        DosFindClose(hdir);
115      }
116      free(mask);
117    }
118    free(fb);
119  }
120}
121
122//=== StartSnap() Write directory tree to snapshot file ===
123
124static VOID StartSnap(VOID * dummy)
125{
126  SNAPSTUFF *sf = (SNAPSTUFF *) dummy;
127  FILE *fp;
128  CHAR *p;
129
130  if (sf) {
131    if (*sf->dirname && *sf->filename) {
132      priority_normal();
133      p = sf->dirname;
134      while (*p) {
135        if (*p == '/')
136          *p = '\\';
137        p++;
138      }
139      if (*(p - 1) != '\\') {
140        *p = '\\';
141        p++;
142      }
143      fp = xfopen(sf->filename, "w", pszSrcFile, __LINE__);
144      if (fp) {
145        fprintf(fp, "\"%s\"\n", sf->dirname);
146        SnapShot(sf->dirname, fp, sf->recurse);
147        fclose(fp);
148      }
149    }
150    free(sf);
151  }
152}
153
154//=== CompareFilesThread() Compare files and update container select flags ===
155
156static VOID CompareFilesThread(VOID * args)
157{
158  FCOMPARE fc;
159  HAB hab2;
160  HMQ hmq2;
161  FILE *fp1, *fp2;
162  ULONG len1, len2, offset = 0L;
163  LONG numread1, numread2;
164  CHAR s[1024], ss[1024], *p1, *p2;
165
166  if (args) {
167    fc = *(FCOMPARE *) args;
168    hab2 = WinInitialize(0);
169    if (hab2) {
170      hmq2 = WinCreateMsgQueue(hab2, 0);
171      if (hmq2) {
172        WinCancelShutdown(hmq2, TRUE);
173        IncrThreadUsage();
174        if (!IsFile(fc.file1) || IsRoot(fc.file1)) {
175          p1 = strrchr(fc.file2, '\\');
176          if (p1) {
177            if (fc.file1[strlen(fc.file1) - 1] == '\\')
178              p1++;
179            strcat(fc.file1, p1);
180          }
181        }
182        else if (!IsFile(fc.file2) || IsRoot(fc.file2)) {
183          p1 = strrchr(fc.file1, '\\');
184          if (p1) {
185            if (fc.file2[strlen(fc.file2) - 1] == '\\')
186              p1++;
187            strcat(fc.file2, p1);
188          }
189        }
190        sprintf(s, GetPString(IDS_COMPCOMPARETEXT), fc.file1);
191        AddToListboxBottom(fc.hwndList, s);
192        sprintf(s, GetPString(IDS_COMPTOTEXT), fc.file2);
193        AddToListboxBottom(fc.hwndList, s);
194        fp1 = _fsopen(fc.file1, "rb", SH_DENYNO);
195        if (!fp1) {
196          sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file1);
197          AddToListboxBottom(fc.hwndList, s);
198          WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
199        }
200        else {
201          fp2 = _fsopen(fc.file2, "rb", SH_DENYNO);
202          if (!fp2) {
203            sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file2);
204            AddToListboxBottom(fc.hwndList, s);
205            WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
206          }
207          else {
208            len1 = filelength(fileno(fp1));
209            len2 = filelength(fileno(fp2));
210            if (len1 != len2) {
211              strcpy(s, GetPString(IDS_COMPDIFSIZESTEXT));
212              AddToListboxBottom(fc.hwndList, s);
213              sprintf(s, GetPString(IDS_COMPVSBYTESTEXT), len1, len2);
214              AddToListboxBottom(fc.hwndList, s);
215              WinSetWindowText(fc.hwndHelp,
216                               GetPString(IDS_COMPDONTMATCHTEXT));
217            }
218            else {
219              WinSetWindowText(fc.hwndHelp,
220                               GetPString(IDS_COMPCOMPARINGTEXT));
221              while (WinIsWindow(hab2, fc.hwndList)) {
222                numread1 = fread(s, 1, 1024, fp1);
223                numread2 = fread(ss, 1, 1024, fp2);
224                if (numread1 != numread2 || feof(fp1) != feof(fp2)) {
225                  sprintf(s, GetPString(IDS_COMPREADERRORTEXT),
226                          offset, offset);
227                  AddToListboxBottom(fc.hwndList, s);
228                  WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
229                  break;
230                }
231                else if (!numread1 && feof(fp1) && feof(fp2)) {
232                  AddToListboxBottom(fc.hwndList,
233                                     GetPString(IDS_COMPFILESMATCHTEXT));
234                  if (!stricmp(fc.file1, fc.file2))
235                    AddToListboxBottom(fc.hwndList,
236                                       GetPString(IDS_COMPWONDERWHYTEXT));
237                  WinSetWindowText(fc.hwndHelp,
238                                   GetPString(IDS_COMPCOMPLETETEXT));
239                  break;
240                }
241                else if (numread1 <= 0 || numread2 <= 0) {
242                  if (offset == len1)
243                    break;
244                  else {
245                    sprintf(s, GetPString(IDS_COMPMATCHREADERRORTEXT),
246                            offset, offset);
247                    WinSetWindowText(fc.hwndHelp,
248                                     GetPString(IDS_COMPODDERRORTEXT));
249                    AddToListboxBottom(fc.hwndList, s);
250                    break;
251                  }
252                }
253                else if (memcmp(s, ss, numread1)) {
254                  p1 = s;
255                  p2 = ss;
256                  while (p1 < s + numread1) {
257                    if (*p1 != *p2) {
258                      sprintf(s, GetPString(IDS_COMPMISMATCHERRORTEXT),
259                              offset + (p1 - s), offset + (p1 - s));
260                      AddToListboxBottom(fc.hwndList, s);
261                      WinSetWindowText(fc.hwndHelp,
262                                       GetPString(IDS_COMPDONTMATCHTEXT));
263                      break;
264                    }
265                    p1++;
266                    p2++;
267                  }
268                  break;
269                }
270                offset += numread1;
271              }
272            }
273            fclose(fp2);
274          }
275          fclose(fp1);
276        }
277        DecrThreadUsage();
278        WinDestroyMsgQueue(hmq2);
279      }
280      WinTerminate(hab2);
281    }
282  }
283}
284
285//=== CFileDlgProc() Select directories to compare dialog procedure ===
286
287MRESULT EXPENTRY CFileDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
288{
289  FCOMPARE *fc;
290
291  switch (msg) {
292  case WM_INITDLG:
293    if (!mp2)
294      WinDismissDlg(hwnd, 0);
295    else {
296      WinSetWindowPtr(hwnd, QWL_USER, mp2);
297      fc = (FCOMPARE *) mp2;
298      fc->hwndReport = hwnd;
299      fc->hwndList = WinWindowFromID(hwnd, FCMP_LISTBOX);
300      fc->hwndHelp = WinWindowFromID(hwnd, FCMP_HELP);
301      if (!*fc->file1 || !fc->file2) {
302        WinDismissDlg(hwnd, 0);
303        break;
304      }
305      MakeFullName(fc->file1);
306      MakeFullName(fc->file2);
307      if (!stricmp(fc->file1, fc->file2)) {
308        saymsg(MB_CANCEL, hwnd,
309               GetPString(IDS_COMPSILLYALERTTEXT),
310               GetPString(IDS_COMPTOITSELFTEXT));
311        WinDismissDlg(hwnd, 0);
312        break;
313      }
314      if (_beginthread(CompareFilesThread, NULL, 65536, (PVOID) fc) == -1) {
315        Runtime_Error(pszSrcFile, __LINE__,
316                      GetPString(IDS_COULDNTSTARTTHREADTEXT));
317        WinDismissDlg(hwnd, 0);
318      }
319    }
320    break;
321
322  case WM_ADJUSTWINDOWPOS:
323    PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
324    break;
325
326  case UM_SETDIR:
327    PaintRecessedWindow(WinWindowFromID(hwnd, FCMP_HELP),
328                        (HPS) 0, FALSE, TRUE);
329    return 0;
330
331  case WM_COMMAND:
332    switch (SHORT1FROMMP(mp1)) {
333    case DID_OK:
334      WinDismissDlg(hwnd, 0);
335      break;
336    case DID_CANCEL:
337      WinDismissDlg(hwnd, 1);
338      break;
339    }
340    return 0;
341
342  case WM_DESTROY:
343    DosSleep(100);
344    break;
345  }
346  return WinDefDlgProc(hwnd, msg, mp1, mp2);
347}
348
349//=== ActionCnrThread() Do requested action on container contents ===
350
351static VOID ActionCnrThread(VOID *args)
352{
353  COMPARE *cmp = (COMPARE *)args;
354  HAB hab;
355  HMQ hmq;
356  HWND hwndCnrS, hwndCnrD;
357  PCNRITEM pci, pciD, pciNextS, pciNextD;
358  CHAR newname[CCHMAXPATH], dirname[CCHMAXPATH], *p;
359  APIRET rc;
360
361  if (!cmp) {
362    Runtime_Error(pszSrcFile, __LINE__, "no data");
363    return;
364  }
365
366  DosError(FERR_DISABLEHARDERR);
367
368  hab = WinInitialize(0);
369  if (hab) {
370    hmq = WinCreateMsgQueue(hab, 0);
371    if (hmq) {
372      WinCancelShutdown(hmq, TRUE);
373      IncrThreadUsage();
374      priority_normal();
375      switch (cmp->action) {
376      case COMP_DELETELEFT:
377        hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
378        hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
379        cmp->action = IDM_DELETE;
380        break;
381      case COMP_DELETERIGHT:
382        hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
383        hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
384        cmp->action = IDM_DELETE;
385        break;
386      case COMP_MOVELEFT:
387        cmp->action = IDM_MOVE;
388        hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
389        hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
390        break;
391      case COMP_MOVERIGHT:
392        cmp->action = IDM_MOVE;
393        hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
394        hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
395        break;
396      case COMP_COPYLEFT:
397        cmp->action = IDM_COPY;
398        hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
399        hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
400        break;
401      case COMP_COPYRIGHT:
402        cmp->action = IDM_COPY;
403        hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
404        hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
405        break;
406      default:
407        Runtime_Error(pszSrcFile, __LINE__, "bad case %u", cmp->action);
408        goto Abort;
409      }
410
411      pci = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
412                       MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
413      pciD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
414                        MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
415
416      while (pci && (INT)pci != -1 && pciD && (INT)pciD != -1) {
417
418        pciNextS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pci),
419                          MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
420        pciNextD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
421                           MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
422
423        if (*pci->pszFileName && pci->rc.flRecordAttr & CRA_SELECTED) {
424
425          // Source name not blank
426          switch (cmp->action) {
427          case IDM_DELETE:
428            if (!unlinkf("%s", pci->pszFileName)) {
429              WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pci),
430                         MPFROM2SHORT(FALSE, CRA_SELECTED));
431
432              if (!*pciD->pszFileName) {
433                // Other side is blank - remove from both sides
434                RemoveCnrItems(hwndCnrS, pci, 1, CMA_FREE | CMA_INVALIDATE);
435                if (pciD->rc.flRecordAttr & CRA_SELECTED)
436                  WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
437                             MPFROM2SHORT(FALSE, CRA_SELECTED));
438                RemoveCnrItems(hwndCnrD, pciD, 1, CMA_FREE | CMA_INVALIDATE);
439              }
440              else {
441                // Other side is not blank - update just this side
442                FreeCnrItemData(pci);
443                pci->pszFileName = NullStr;
444                pci->pszDisplayName = pci->pszFileName;
445                pci->rc.pszIcon = pci->pszFileName;
446                pci->pszLongname = NullStr;
447                pci->pszSubject = NullStr;
448                pci->flags = 0;
449                WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pci),
450                           MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
451              }
452              if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
453                cmp->cmp->totalleft--;
454              else
455                cmp->cmp->totalright--;
456              DosSleep(1);
457            }
458            break;
459
460          case IDM_MOVE:
461            if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
462              // 02 Aug 07 SHL fixme to replace this kind of stuff with _makepath or equivalent
463              sprintf(newname, "%s%s%s",
464                      cmp->leftdir,
465                      cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\' ?
466                        NullStr : "\\",
467                        pci->pszDisplayName);
468            else
469              sprintf(newname, "%s%s%s",
470                      cmp->rightdir,
471                      cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\' ?
472                        NullStr : "\\",
473                      pci->pszDisplayName);
474            // Make directory if required
475            strcpy(dirname, newname);
476            p = strrchr(dirname, '\\');
477            if (p) {
478              if (p > dirname + 2)
479                p++;
480              *p = 0;
481              if (IsFile(dirname) == -1)
482                MassMkdir(hwndMain, dirname);
483            }
484            rc = docopyf(MOVE, pci->pszFileName, "%s", newname);
485            if (!rc && stricmp(pci->pszFileName, newname)) {
486              WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pci),
487                         MPFROM2SHORT(FALSE, CRA_SELECTED));
488              if (pciD->rc.flRecordAttr & CRA_SELECTED)
489                WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
490                           MPFROM2SHORT(FALSE, CRA_SELECTED));
491              FreeCnrItemData(pciD);
492              pciD->pszFileName = xstrdup(newname, pszSrcFile, __LINE__);
493              if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
494                pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
495                if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
496                  pciD->pszDisplayName++;
497              }
498              else {
499                pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
500                if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
501                  pciD->pszDisplayName++;
502              }
503              // 02 Aug 07 SHL fixme to know Longname transfer is correct?
504              pciD->pszLongname = pci->pszLongname;
505              if (pciD->pszSubject != NullStr) {
506                xfree(pciD->pszSubject);
507                pciD->pszSubject = NullStr;
508              }
509              pciD->attrFile = pci->attrFile;
510              pciD->pszDispAttr = pci->pszDispAttr;
511              pciD->flags = 0;
512              pciD->date = pci->date;
513              pciD->time = pci->time;
514              pciD->ladate = pci->ladate;
515              pciD->latime = pci->latime;
516              pciD->crdate = pci->crdate;
517              pciD->crtime = pci->crtime;
518              pciD->cbFile = pci->cbFile;
519              pciD->easize = pci->easize;
520
521              if (pci->pszFileName != NullStr) {
522                xfree(pci->pszFileName);
523                pci->pszFileName = NullStr;
524                pci->pszDisplayName = pci->pszFileName;
525                pci->rc.pszIcon = pci->pszFileName;
526              }
527              if (pci->pszSubject != NullStr) {
528                xfree(pci->pszSubject);
529                pci->pszSubject = NullStr;
530              }
531              pci->flags = 0;
532
533              WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pci),
534                         MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
535              WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
536                         MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
537            }
538            else if (rc) {
539              rc = Dos_Error(MB_ENTERCANCEL,
540                             rc,
541                             HWND_DESKTOP,
542                             pszSrcFile,
543                             __LINE__,
544                             GetPString(IDS_COMPMOVEFAILEDTEXT),
545                             pci->pszFileName, newname);
546              if (rc == MBID_CANCEL)    // Cause loop to break
547                pciNextS = NULL;
548            }
549            break;
550
551          case IDM_COPY:
552            if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
553              sprintf(newname, "%s%s%s",
554                      cmp->leftdir,
555                      cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\' ?
556                        NullStr : "\\",
557                      pci->pszDisplayName);
558            else
559              sprintf(newname, "%s%s%s",
560                      cmp->rightdir,
561                      cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\' ?
562                        NullStr : "\\",
563                      pci->pszDisplayName);
564            // Make directory if required
565            strcpy(dirname, newname);
566            p = strrchr(dirname, '\\');
567            if (p) {
568              if (p > dirname + 2)
569                p++;
570              *p = 0;
571              if (IsFile(dirname) == -1)
572                MassMkdir(hwndMain, dirname);
573            }
574            rc = docopyf(COPY, pci->pszFileName, "%s", newname);
575            if (rc) {
576              rc = Dos_Error(MB_ENTERCANCEL,
577                             rc,
578                             HWND_DESKTOP,
579                             pszSrcFile,
580                             __LINE__,
581                             GetPString(IDS_COMPCOPYFAILEDTEXT),
582                             pci->pszFileName, newname);
583              if (rc == MBID_CANCEL)
584                pciNextS = NULL;                // Cause loop to break
585            }
586            else {
587              WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pci),
588                         MPFROM2SHORT(FALSE, CRA_SELECTED));
589              if (pciD->rc.flRecordAttr & CRA_SELECTED)
590                WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
591                           MPFROM2SHORT(FALSE, CRA_SELECTED));
592              FreeCnrItemData(pciD);
593              pciD->pszFileName = xstrdup(newname, pszSrcFile, __LINE__);
594              pciD->pszLongname = NullStr;
595              pciD->pszSubject = NullStr;
596              if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
597                pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
598                if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
599                  pciD->pszDisplayName++;
600              }
601              else {
602                pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
603                if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
604                  pciD->pszDisplayName++;
605              }
606              pciD->attrFile = pci->attrFile;
607              pciD->pszDispAttr = pci->pszDispAttr;
608              pciD->flags = CNRITEM_EXISTS;
609              pciD->date = pci->date;
610              pciD->time = pci->time;
611              pciD->ladate = pci->ladate;
612              pciD->latime = pci->latime;
613              pciD->crdate = pci->crdate;
614              pciD->crtime = pci->crtime;
615              pciD->cbFile = pci->cbFile;
616              pciD->easize = pci->easize;
617
618              // 02 Aug 07 SHL fixme to know why subject cleared?
619              if (pci->pszSubject != NullStr) {
620                xfree(pci->pszSubject);
621                pci->pszSubject = NullStr;
622              }
623              // 02 Aug 07 SHL fixme to know why - should already be set?
624              pci->flags = CNRITEM_EXISTS;
625
626              WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pci),
627                         MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
628              WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
629                         MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
630            }
631            break;
632
633          default:
634            break;
635          } // switch
636
637        } // if have name
638
639        pci = pciNextS;
640        pciD = pciNextD;
641
642      } // while
643    Abort:
644      WinDestroyMsgQueue(hmq);
645    }
646    DecrThreadUsage();
647    WinTerminate(hab);
648  }
649  PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID);
650  PostMsg(cmp->hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DESELECTALL, 0), MPVOID);
651  free(cmp);
652}
653
654//=== SelectCnrsThread() Update container selection flags thread ===
655
656static VOID SelectCnrsThread(VOID * args)
657{
658  COMPARE *cmp = (COMPARE *) args;
659  HAB hab;
660  HMQ hmq;
661
662  if (!cmp)
663    return;
664
665  DosError(FERR_DISABLEHARDERR);
666
667  hab = WinInitialize(0);
668  if (hab) {
669    hmq = WinCreateMsgQueue(hab, 0);
670    if (hmq) {
671      WinCancelShutdown(hmq, TRUE);
672      IncrThreadUsage();
673      priority_normal();
674      switch (cmp->action) {
675      case IDM_INVERT:
676        InvertAll(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
677        InvertAll(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
678        break;
679
680      case IDM_DESELECTALL:
681        Deselect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
682        Deselect(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
683        break;
684
685      default:
686        SpecialSelect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR),
687                      WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR),
688                      cmp->action, cmp->reset);
689        break;
690      }
691      if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID))
692        WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID);
693      WinDestroyMsgQueue(hmq);
694    }
695    DecrThreadUsage();
696    WinTerminate(hab);
697  }
698  free(cmp);
699}
700
701/**
702 * Build FILELIST given pathname
703 */
704
705static VOID FillDirList(CHAR *str, INT skiplen, BOOL recurse,
706                        FILELIST ***list, INT *numfiles, INT *numalloc)
707{
708
709  BYTE *fb;
710  CHAR *enddir;
711  ULONG x;
712  CHAR *maskstr;
713  FILEFINDBUF4 *ffb4, *pffb;
714  HDIR hDir;
715  ULONG nm, fl = 0, ulM = 64;
716  APIRET rc;
717
718  if (!str || !*str) {
719    Runtime_Error(pszSrcFile, __LINE__, "no data");
720    return;
721  }
722
723  if (!recurse)
724    ulM = 128;
725  maskstr = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
726  if (!maskstr)
727    return;
728  ffb4 = xmalloc(sizeof(FILEFINDBUF4) * ulM, pszSrcFile, __LINE__);
729  if (!ffb4) {
730    free(maskstr);
731    return;
732  }
733  x = strlen(str);
734  memcpy(maskstr, str, x + 1);
735  enddir = maskstr + x;
736  if (*(enddir - 1) != '\\') {
737    *enddir = '\\';
738    enddir++;
739    *enddir = 0;
740  }
741  *enddir = '*';
742  *(enddir + 1) = 0;
743  hDir = HDIR_CREATE;
744  nm = ulM;
745  if (recurse)
746    fl = FILE_DIRECTORY;
747  DosError(FERR_DISABLEHARDERR);
748  rc = DosFindFirst(maskstr, &hDir,
749                    (FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
750                     FILE_SYSTEM | FILE_HIDDEN) | fl,
751                    ffb4, sizeof(FILEFINDBUF4) * nm, &nm, FIL_QUERYEASIZE);
752  if (!rc) {
753    while (!rc) {
754      fb = (BYTE *) ffb4;
755      x = 0;
756      while (x < nm) {
757        pffb = (FILEFINDBUF4 *) fb;
758        if (pffb->attrFile & FILE_DIRECTORY) {
759          // Skip . and ..
760          if (recurse &&
761              (pffb->achName[0] != '.' ||
762               (pffb->achName[1] &&
763                (pffb->achName[1] != '.' || pffb->achName[2])))) {
764            if (fForceUpper)
765              strupr(pffb->achName);
766            else if (fForceLower)
767              strlwr(pffb->achName);
768            memcpy(enddir, pffb->achName, pffb->cchName + 1);
769            FillDirList(maskstr, skiplen, recurse, list, numfiles, numalloc);
770          }
771        }
772        else {
773          if (fForceUpper)
774            strupr(pffb->achName);
775          else if (fForceLower)
776            strlwr(pffb->achName);
777          memcpy(enddir, pffb->achName, pffb->cchName + 1);
778          if (AddToFileList
779              (maskstr + skiplen, pffb, list, numfiles, numalloc))
780            goto Abort;
781        }
782        fb += pffb->oNextEntryOffset;
783        x++;
784      }
785      nm = ulM;
786      DosError(FERR_DISABLEHARDERR);
787      rc = DosFindNext(hDir, ffb4, sizeof(FILEFINDBUF4) * nm, &nm);
788    }
789  Abort:
790    DosFindClose(hDir);
791    DosSleep(1);
792  }
793  free(maskstr);
794  free(ffb4);
795}
796
797//=== CompNames() Compare names for qsort ===
798
799static int CompNames(const void *n1, const void *n2)
800{
801  FILELIST *fl1 = *(FILELIST **) n1;
802  FILELIST *fl2 = *(FILELIST **) n2;
803
804  return stricmp(fl1->fname, fl2->fname);
805}
806
807//=== FillCnrsThread() Fill left and right containers ===
808
809static VOID FillCnrsThread(VOID *args)
810{
811  COMPARE *cmp = (COMPARE *) args;
812  HAB hab;
813  HMQ hmq;
814  BOOL notified = FALSE;
815
816  HWND hwndLeft, hwndRight;
817  CHAR szBuf[CCHMAXPATH];
818  CNRINFO cnri;
819
820  if (!cmp) {
821    Runtime_Error(pszSrcFile, __LINE__, "no data");
822    _endthread();
823  }
824
825  DosError(FERR_DISABLEHARDERR);
826
827  hab = WinInitialize(0);
828  if (!hab)
829    Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__, "WinInitialize");
830  else {
831    hmq = WinCreateMsgQueue(hab, 0);
832    if (!hmq)
833      Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__,
834                "WinCreateMsgQueue");
835    else {
836      INT x;
837      INT l;
838      INT r;
839      ULONG cntr;
840      FILELIST **filesl = NULL;
841      FILELIST **filesr = NULL;
842      INT numfilesl = 0;
843      INT numfilesr = 0;
844      INT numallocl = 0;
845      INT numallocr = 0;
846      INT lenl;                         // Directory prefix length
847      INT lenr;
848      UINT recsNeeded;
849      PCNRITEM pcilFirst;
850      PCNRITEM pcirFirst;
851      PCNRITEM pcil;
852      PCNRITEM pcir;
853      RECORDINSERT ri;
854      CHAR *pch;
855
856      WinCancelShutdown(hmq, TRUE);
857      IncrThreadUsage();
858      hwndLeft = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
859      hwndRight = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
860      lenl = strlen(cmp->leftdir);
861      if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
862        lenl++;
863      lenr = strlen(cmp->rightdir);
864      if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
865        lenr++;
866      priority_normal();
867      // Clear containers
868      RemoveCnrItems(hwndRight, NULL, 0, CMA_FREE | CMA_INVALIDATE);
869      RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
870      cmp->cmp->totalleft = cmp->cmp->totalright = 0;
871
872      // Build list of all files in left directory
873      if (fForceLower)
874        strlwr(cmp->leftdir);
875      else if (fForceUpper)
876        strupr(cmp->leftdir);
877      FillDirList(cmp->leftdir, lenl, cmp->includesubdirs,
878                  &filesl, &numfilesl, &numallocl);
879
880      if (filesl)
881        qsort(filesl, numfilesl, sizeof(CHAR *), CompNames);
882
883      // Build list of all files in right directory
884      if (!*cmp->rightlist) {
885        if (fForceLower)
886          strlwr(cmp->rightdir);
887        else if (fForceUpper)
888          strupr(cmp->rightdir);
889        FillDirList(cmp->rightdir, lenr, cmp->includesubdirs,
890                    &filesr, &numfilesr, &numallocr);
891      }
892      else {
893        // Use snapshot file
894        FILE *fp;
895        FILEFINDBUF4 fb4;
896        CHAR str[CCHMAXPATH * 2], *p;
897
898        memset(&fb4, 0, sizeof(fb4));
899        fp = fopen(cmp->rightlist, "r");
900        if (!fp)
901          Runtime_Error(pszSrcFile, __LINE__, "can not open %s (%d)",
902                        cmp->rightlist, errno);
903        else {
904          while (!feof(fp)) {
905            // First get name of directory
906            if (!xfgets_bstripcr(str, sizeof(str), fp, pszSrcFile, __LINE__))
907              break;                    // EOF
908            p = str;
909            if (*p == '\"') {
910              // Quoted
911              p++;
912              if (*p && *p != '\"') {
913                p = strchr(p, '\"');
914                if (p) {
915                  *p = 0;
916                  if (*(str + 1)) {
917                    strcpy(cmp->rightdir, str + 1);
918                    if (fForceUpper)
919                      strupr(cmp->rightdir);
920                    else if (fForceLower)
921                      strlwr(cmp->rightdir);
922                    p = cmp->rightdir + (strlen(cmp->rightdir) - 1);
923                    if (p - cmp->rightdir > 3 && *p == '\\')
924                      *p = 0;           // Chop trailing slash
925                    break;
926                  }
927                }
928              }
929            }
930          } // while !EOF
931
932          memset(&cnri, 0, sizeof(cnri));
933          cnri.cb = sizeof(cnri);
934          cnri.pszCnrTitle = cmp->rightdir;
935          if (!WinSendMsg(hwndRight, CM_SETCNRINFO,
936                     MPFROMP(&cnri), MPFROMLONG(CMA_CNRTITLE))) {
937            Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_SETCNRINFO");
938          }
939
940          if (*cmp->rightdir) {
941            lenr = strlen(cmp->rightdir) +
942              (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\');
943            while (!feof(fp)) {
944              if (!xfgets_bstripcr
945                  (str, sizeof(str), fp, pszSrcFile, __LINE__))
946                break;
947              p = str;
948              if (*p == '\"') {
949                p++;
950                if (*p && *p != '\"') {
951                  p = strchr(p, '\"');
952                  if (p) {
953                    *p = 0;
954                    p++;
955                    if (*p == ',') {
956                      p++;
957                      if (!cmp->includesubdirs && atol(p) > lenr)
958                        continue;
959                      p = strchr(p, ',');
960                      if (p) {
961                        p++;
962                        fb4.cbFile = atol(p);
963                        p = strchr(p, ',');
964                        if (p) {
965                          p++;
966                          fb4.fdateLastWrite.year = atol(p) - 1980;
967                          p = strchr(p, '/');
968                          if (p) {
969                            p++;
970                            fb4.fdateLastWrite.month = atol(p);
971                            p = strchr(p, '/');
972                            if (p) {
973                              p++;
974                              fb4.fdateLastWrite.day = atol(p);
975                              p = strchr(p, ',');
976                              if (p) {
977                                p++;
978                                fb4.ftimeLastWrite.hours = atol(p);
979                                p = strchr(p, ':');
980                                if (p) {
981                                  p++;
982                                  fb4.ftimeLastWrite.minutes = atol(p);
983                                  p = strchr(p, ':');
984                                  if (p) {
985                                    p++;
986                                    fb4.ftimeLastWrite.twosecs = atol(p);
987                                    p = strchr(p, ',');
988                                    if (p) {
989                                      p++;
990                                      fb4.attrFile = atol(p);
991                                      p = strchr(p, ',');
992                                      if (p) {
993                                        p++;
994                                        fb4.cbList = atol(p) * 2;
995                                        if (fForceUpper)
996                                          strupr(str + 1);
997                                        else if (fForceLower)
998                                          strlwr(str + 1);
999                                        if (AddToFileList((str + 1) + lenr,
1000                                                          &fb4,
1001                                                          &filesr,
1002                                                          &numfilesr,
1003                                                          &numallocr))
1004                                          break;
1005                                      }
1006                                    }
1007                                  }
1008                                }
1009                              }
1010                            }
1011                          }
1012                        }
1013                      }
1014                    }
1015                  }
1016                }
1017              }
1018            } // while
1019          } // if have rightdir
1020          fclose(fp);
1021        }
1022      } // if snapshot file
1023
1024      if (filesr)
1025        qsort(filesr, numfilesr, sizeof(CHAR *), CompNames);
1026
1027      // We now have two lists of files, both sorted.
1028      // Count total number of container entries required on each side
1029      l = r = 0;
1030      recsNeeded = 0;
1031      while ((filesl && filesl[l]) || (filesr && filesr[r])) {
1032
1033        if (filesl && filesl[l]) {
1034          if (filesr && filesr[r])
1035            x = stricmp(filesl[l]->fname, filesr[r]->fname);
1036          else
1037            x = -1;                     // Left side list longer
1038        }
1039        else
1040          x = +1;                       // Right side list longer
1041
1042        if (x <= 0)
1043          l++;                          // On left side
1044        if (x >= 0)
1045          r++;                          // On right side
1046
1047        recsNeeded++;                   // Keep count of how many entries req'd
1048
1049      } // while
1050
1051      WinSendMsg(cmp->hwnd, UM_CONTAINERHWND, MPVOID, MPVOID);
1052
1053      // Now insert records into the containers
1054      cntr = 0;
1055      l = r = 0;
1056      if (recsNeeded) {
1057        pcilFirst = WinSendMsg(hwndLeft,
1058                               CM_ALLOCRECORD,
1059                               MPFROMLONG(EXTRA_RECORD_BYTES),
1060                               MPFROMLONG(recsNeeded));
1061        if (!pcilFirst) {
1062          Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_ALLOCRECORD %u failed",
1063                    recsNeeded);
1064          recsNeeded = 0;
1065        }
1066      }
1067      if (recsNeeded) {
1068        pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
1069                               MPFROMLONG(EXTRA_RECORD_BYTES),
1070                               MPFROMLONG(recsNeeded));
1071        if (!pcirFirst) {
1072          Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_ALLOCRECORD %u failed",
1073                    recsNeeded);
1074          recsNeeded = 0;
1075          FreeCnrItemList(hwndLeft, pcilFirst);
1076        }
1077      }
1078
1079      if (recsNeeded) {
1080
1081        pcil = pcilFirst;
1082        pcir = pcirFirst;
1083        while ((filesl && filesl[l]) || (filesr && filesr[r])) {
1084          pcir->hwndCnr = hwndRight;
1085          pcir->rc.hptrIcon = (HPOINTER) 0;
1086          pcil->hwndCnr = hwndLeft;
1087          pcil->rc.hptrIcon = (HPOINTER) 0;
1088
1089          if (filesl && filesl[l]) {
1090            if (filesr && filesr[r])
1091              x = stricmp(filesl[l]->fname, filesr[r]->fname);
1092            else
1093              x = -1;                   // Left side list longer
1094          }
1095          else
1096            x = +1;                     // Right side list longer
1097
1098          if (x <= 0) {
1099            // File appears on left side
1100            sprintf(szBuf, "%s%s%s", cmp->leftdir,
1101                    (cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\') ?
1102                    NullStr : "\\", filesl[l]->fname);
1103            pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
1104            pcil->pszDisplayName = pcil->pszFileName + lenl;
1105            pcil->attrFile = filesl[l]->attrFile;
1106            pcil->pszDispAttr = FileAttrToString(pcil->attrFile);
1107            pcil->cbFile = filesl[l]->cbFile;
1108            pcil->easize = filesl[l]->easize;
1109            pcil->date.day = filesl[l]->date.day;
1110            pcil->date.month = filesl[l]->date.month;
1111            pcil->date.year = filesl[l]->date.year + 1980;
1112            pcil->time.seconds = filesl[l]->time.twosecs * 2;
1113            pcil->time.minutes = filesl[l]->time.minutes;
1114            pcil->time.hours = filesl[l]->time.hours;
1115            pcil->ladate.day = filesl[l]->ladate.day;
1116            pcil->ladate.month = filesl[l]->ladate.month;
1117            pcil->ladate.year = filesl[l]->ladate.year + 1980;
1118            pcil->latime.seconds = filesl[l]->latime.twosecs * 2;
1119            pcil->latime.minutes = filesl[l]->latime.minutes;
1120            pcil->latime.hours = filesl[l]->latime.hours;
1121            pcil->crdate.day = filesl[l]->crdate.day;
1122            pcil->crdate.month = filesl[l]->crdate.month;
1123            pcil->crdate.year = filesl[l]->crdate.year + 1980;
1124            pcil->crtime.seconds = filesl[l]->crtime.twosecs * 2;
1125            pcil->crtime.minutes = filesl[l]->crtime.minutes;
1126            pcil->crtime.hours = filesl[l]->crtime.hours;
1127            if (*cmp->dcd.mask.szMask) {
1128              if (!Filter((PMINIRECORDCORE) pcil, (PVOID)&cmp->dcd.mask)) {
1129                pcil->rc.flRecordAttr |= CRA_FILTERED;
1130                pcir->rc.flRecordAttr |= CRA_FILTERED;
1131              }
1132            }
1133            pcil->flags |= CNRITEM_EXISTS;
1134          } // if on left
1135
1136          if (x >= 0) {
1137            // File appears on right side
1138            sprintf(szBuf, "%s%s%s", cmp->rightdir,
1139                    (cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\') ?
1140                    NullStr : "\\", filesr[r]->fname);
1141            pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);   // 31 Jul 07 SHL
1142            pcir->pszDisplayName = pcir->pszFileName + lenr;
1143            pcir->attrFile = filesr[r]->attrFile;
1144            // pcir->rc.hptrIcon = hptrFile;
1145            pcir->pszDispAttr = FileAttrToString(pcir->attrFile);
1146            pcir->cbFile = filesr[r]->cbFile;
1147            pcir->easize = filesr[r]->easize;
1148            pcir->date.day = filesr[r]->date.day;
1149            pcir->date.month = filesr[r]->date.month;
1150            pcir->date.year = filesr[r]->date.year + 1980;
1151            pcir->time.seconds = filesr[r]->time.twosecs * 2;
1152            pcir->time.minutes = filesr[r]->time.minutes;
1153            pcir->time.hours = filesr[r]->time.hours;
1154            pcir->ladate.day = filesr[r]->ladate.day;
1155            pcir->ladate.month = filesr[r]->ladate.month;
1156            pcir->ladate.year = filesr[r]->ladate.year + 1980;
1157            pcir->latime.seconds = filesr[r]->latime.twosecs * 2;
1158            pcir->latime.minutes = filesr[r]->latime.minutes;
1159            pcir->latime.hours = filesr[r]->latime.hours;
1160            pcir->crdate.day = filesr[r]->crdate.day;
1161            pcir->crdate.month = filesr[r]->crdate.month;
1162            pcir->crdate.year = filesr[r]->crdate.year + 1980;
1163            pcir->crtime.seconds = filesr[r]->crtime.twosecs * 2;
1164            pcir->crtime.minutes = filesr[r]->crtime.minutes;
1165            pcir->crtime.hours = filesr[r]->crtime.hours;
1166            if (~pcil->rc.flRecordAttr & CRA_FILTERED &&
1167                *cmp->dcd.mask.szMask) {
1168              if (!Filter((PMINIRECORDCORE)pcir, (PVOID)&cmp->dcd.mask)) {
1169                pcil->rc.flRecordAttr |= CRA_FILTERED;
1170                pcir->rc.flRecordAttr |= CRA_FILTERED;
1171              }
1172            }
1173            pcir->flags |= CNRITEM_EXISTS;
1174          } // if on right
1175
1176          if (x == 0) {
1177            // File appears on both sides
1178            pch = szBuf;
1179            // Subject field holds status messages
1180            *pch = 0;
1181            if (pcil->cbFile + pcil->easize > pcir->cbFile + pcir->easize) {
1182              pcil->flags |= CNRITEM_LARGER;
1183              pcir->flags |= CNRITEM_SMALLER;
1184              strcpy(pch, GetPString(IDS_LARGERTEXT));
1185              pch += 6;
1186            }
1187            else if (pcil->cbFile + pcil->easize <
1188                     pcir->cbFile + pcir->easize) {
1189              pcil->flags |= CNRITEM_SMALLER;
1190              pcir->flags |= CNRITEM_LARGER;
1191              strcpy(pch, GetPString(IDS_SMALLERTEXT));
1192              pch += 7;
1193            }
1194            if ((pcil->date.year > pcir->date.year) ? TRUE :
1195                (pcil->date.year < pcir->date.year) ? FALSE :
1196                (pcil->date.month > pcir->date.month) ? TRUE :
1197                (pcil->date.month < pcir->date.month) ? FALSE :
1198                (pcil->date.day > pcir->date.day) ? TRUE :
1199                (pcil->date.day < pcir->date.day) ? FALSE :
1200                (pcil->time.hours > pcir->time.hours) ? TRUE :
1201                (pcil->time.hours < pcir->time.hours) ? FALSE :
1202                (pcil->time.minutes > pcir->time.minutes) ? TRUE :
1203                (pcil->time.minutes < pcir->time.minutes) ? FALSE :
1204                (pcil->time.seconds > pcir->time.seconds) ? TRUE :
1205                (pcil->time.seconds < pcir->time.seconds) ? FALSE : FALSE) {
1206              pcil->flags |= CNRITEM_NEWER;
1207              pcir->flags |= CNRITEM_OLDER;
1208              if (pch != szBuf) {
1209                strcpy(pch, ", ");
1210                pch += 2;
1211              }
1212              strcpy(pch, GetPString(IDS_NEWERTEXT));
1213              pch += 5;
1214            }
1215            else if ((pcil->date.year < pcir->date.year) ? TRUE :
1216                     (pcil->date.year > pcir->date.year) ? FALSE :
1217                     (pcil->date.month < pcir->date.month) ? TRUE :
1218                     (pcil->date.month > pcir->date.month) ? FALSE :
1219                     (pcil->date.day < pcir->date.day) ? TRUE :
1220                     (pcil->date.day > pcir->date.day) ? FALSE :
1221                     (pcil->time.hours < pcir->time.hours) ? TRUE :
1222                     (pcil->time.hours > pcir->time.hours) ? FALSE :
1223                     (pcil->time.minutes < pcir->time.minutes) ? TRUE :
1224                     (pcil->time.minutes > pcir->time.minutes) ? FALSE :
1225                     (pcil->time.seconds < pcir->time.seconds) ? TRUE :
1226                     (pcil->time.seconds > pcir->time.seconds) ? FALSE :
1227                     FALSE) {
1228              pcil->flags |= CNRITEM_OLDER;
1229              pcir->flags |= CNRITEM_NEWER;
1230              if (pch != szBuf) {
1231                strcpy(pch, ", ");
1232                pch += 2;
1233              }
1234              strcpy(pch, GetPString(IDS_OLDERTEXT));
1235              pch += 5;
1236            }
1237            // fixme to know why not displayed - defect?
1238            pcil->pszSubject = *szBuf ?
1239                                 xstrdup(szBuf, pszSrcFile, __LINE__) :
1240                                 NullStr;
1241
1242          } // if on both sides
1243
1244          if (x <= 0) {
1245            free(filesl[l]);
1246            l++;
1247          }
1248
1249          if (x >= 0) {
1250            free(filesr[r]);
1251            r++;
1252          }
1253
1254#if 0 //============================ fixme to be gone =================
1255
1256          if (filesl && filesl[l] && filesr && filesr[r]) {
1257            // Got two names
1258            x = stricmp(filesl[l]->fname, filesr[r]->fname);
1259            if (!x) {
1260              // Names match - insert on both sides
1261              sprintf(szBuf, "%s%s%s", cmp->leftdir,
1262                      (cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\') ?
1263                      NullStr : "\\", filesl[l]->fname);
1264              // pcil->rc.hptrIcon = hptrFile;
1265              pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__); // 31 Jul 07 SHL
1266              pcil->pszDisplayName = pcil->pszFileName + lenl;
1267              pcil->attrFile = filesl[l]->attrFile;
1268              y = 0;
1269              for (x = 0; x < 6; x++) {
1270                if (attrstring[x])
1271                  pcil->szDispAttr[y++] =
1272                    (CHAR) ((pcil->
1273                             attrFile & (1 << x)) ? attrstring[x] : '-');
1274              }
1275              pcil->szDispAttr[5] = 0;
1276              pcil->cbFile = filesl[l]->cbFile;
1277              pcil->easize = filesl[l]->easize;
1278              pcil->date.day = filesl[l]->date.day;
1279              pcil->date.month = filesl[l]->date.month;
1280              pcil->date.year = filesl[l]->date.year + 1980;
1281              pcil->time.seconds = filesl[l]->time.twosecs * 2;
1282              pcil->time.minutes = filesl[l]->time.minutes;
1283              pcil->time.hours = filesl[l]->time.hours;
1284              pcil->ladate.day = filesl[l]->ladate.day;
1285              pcil->ladate.month = filesl[l]->ladate.month;
1286              pcil->ladate.year = filesl[l]->ladate.year + 1980;
1287              pcil->latime.seconds = filesl[l]->latime.twosecs * 2;
1288              pcil->latime.minutes = filesl[l]->latime.minutes;
1289              pcil->latime.hours = filesl[l]->latime.hours;
1290              pcil->crdate.day = filesl[l]->crdate.day;
1291              pcil->crdate.month = filesl[l]->crdate.month;
1292              pcil->crdate.year = filesl[l]->crdate.year + 1980;
1293              pcil->crtime.seconds = filesl[l]->crtime.twosecs * 2;
1294              pcil->crtime.minutes = filesl[l]->crtime.minutes;
1295              pcil->crtime.hours = filesl[l]->crtime.hours;
1296              if (*cmp->dcd.mask.szMask) {
1297                if (!Filter((PMINIRECORDCORE) pcil, (PVOID) & cmp->dcd.mask)) {
1298                  pcil->rc.flRecordAttr |= CRA_FILTERED;
1299                  pcir->rc.flRecordAttr |= CRA_FILTERED;
1300                }
1301              }
1302              sprintf(szBuf, "%s%s%s", cmp->rightdir,
1303                      (cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\') ?
1304                      NullStr : "\\", filesr[r]->fname);
1305              pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__); // 31 Jul 07 SHL
1306              pcir->pszDisplayName = pcir->pszFileName + lenr;
1307              pcir->attrFile = filesr[r]->attrFile;
1308              // pcir->rc.hptrIcon = hptrFile;
1309              y = 0;
1310              for (x = 0; x < 6; x++)
1311                if (attrstring[x])
1312                  pcir->szDispAttr[y++] =
1313                    (CHAR) ((pcir->
1314                             attrFile & (1 << x)) ? attrstring[x] : '-');
1315              pcir->szDispAttr[5] = 0;
1316              pcir->cbFile = filesr[r]->cbFile;
1317              pcir->easize = filesr[r]->easize;
1318              pcir->date.day = filesr[r]->date.day;
1319              pcir->date.month = filesr[r]->date.month;
1320              pcir->date.year = filesr[r]->date.year + 1980;
1321              pcir->time.seconds = filesr[r]->time.twosecs * 2;
1322              pcir->time.minutes = filesr[r]->time.minutes;
1323              pcir->time.hours = filesr[r]->time.hours;
1324              pcir->ladate.day = filesr[r]->ladate.day;
1325              pcir->ladate.month = filesr[r]->ladate.month;
1326              pcir->ladate.year = filesr[r]->ladate.year + 1980;
1327              pcir->latime.seconds = filesr[r]->latime.twosecs * 2;
1328              pcir->latime.minutes = filesr[r]->latime.minutes;
1329              pcir->latime.hours = filesr[r]->latime.hours;
1330              pcir->crdate.day = filesr[r]->crdate.day;
1331              pcir->crdate.month = filesr[r]->crdate.month;
1332              pcir->crdate.year = filesr[r]->crdate.year + 1980;
1333              pcir->crtime.seconds = filesr[r]->crtime.twosecs * 2;
1334              pcir->crtime.minutes = filesr[r]->crtime.minutes;
1335              pcir->crtime.hours = filesr[r]->crtime.hours;
1336              pcil->flags |= CNRITEM_EXISTS;
1337              pcir->flags |= CNRITEM_EXISTS;
1338              pch = szBuf;
1339              // Subject field holds status messages
1340              // pch = pcil->pszSubject;
1341              *pch = 0;
1342              if (pcil->cbFile + pcil->easize > pcir->cbFile + pcir->easize) {
1343                pcil->flags |= CNRITEM_LARGER;
1344                pcir->flags |= CNRITEM_SMALLER;
1345                strcpy(pch, GetPString(IDS_LARGERTEXT));
1346                pch += 6;
1347              }
1348              else if (pcil->cbFile + pcil->easize <
1349                       pcir->cbFile + pcir->easize) {
1350                pcil->flags |= CNRITEM_SMALLER;
1351                pcir->flags |= CNRITEM_LARGER;
1352                strcpy(pch, GetPString(IDS_SMALLERTEXT));
1353                pch += 7;
1354              }
1355              if ((pcil->date.year > pcir->date.year) ? TRUE :
1356                  (pcil->date.year < pcir->date.year) ? FALSE :
1357                  (pcil->date.month > pcir->date.month) ? TRUE :
1358                  (pcil->date.month < pcir->date.month) ? FALSE :
1359                  (pcil->date.day > pcir->date.day) ? TRUE :
1360                  (pcil->date.day < pcir->date.day) ? FALSE :
1361                  (pcil->time.hours > pcir->time.hours) ? TRUE :
1362                  (pcil->time.hours < pcir->time.hours) ? FALSE :
1363                  (pcil->time.minutes > pcir->time.minutes) ? TRUE :
1364                  (pcil->time.minutes < pcir->time.minutes) ? FALSE :
1365                  (pcil->time.seconds > pcir->time.seconds) ? TRUE :
1366                  (pcil->time.seconds < pcir->time.seconds) ? FALSE : FALSE) {
1367                pcil->flags |= CNRITEM_NEWER;
1368                pcir->flags |= CNRITEM_OLDER;
1369                if (pch != szBuf) {
1370                  strcpy(pch, ", ");
1371                  pch += 2;
1372                }
1373                strcpy(pch, GetPString(IDS_NEWERTEXT));
1374                pch += 5;
1375              }
1376              else if ((pcil->date.year < pcir->date.year) ? TRUE :
1377                       (pcil->date.year > pcir->date.year) ? FALSE :
1378                       (pcil->date.month < pcir->date.month) ? TRUE :
1379                       (pcil->date.month > pcir->date.month) ? FALSE :
1380                       (pcil->date.day < pcir->date.day) ? TRUE :
1381                       (pcil->date.day > pcir->date.day) ? FALSE :
1382                       (pcil->time.hours < pcir->time.hours) ? TRUE :
1383                       (pcil->time.hours > pcir->time.hours) ? FALSE :
1384                       (pcil->time.minutes < pcir->time.minutes) ? TRUE :
1385                       (pcil->time.minutes > pcir->time.minutes) ? FALSE :
1386                       (pcil->time.seconds < pcir->time.seconds) ? TRUE :
1387                       (pcil->time.seconds > pcir->time.seconds) ? FALSE :
1388                       FALSE) {
1389                pcil->flags |= CNRITEM_OLDER;
1390                pcir->flags |= CNRITEM_NEWER;
1391                if (pch != szBuf) {
1392                  strcpy(pch, ", ");
1393                  pch += 2;
1394                }
1395                strcpy(pch, GetPString(IDS_OLDERTEXT));
1396                pch += 5;
1397              }
1398              *pch = 0;
1399              pcil->pszSubject = *szBuf ? strdup(szBuf) : NullStr;
1400              r++;
1401              l++;
1402            }
1403            else if (x < 0) {
1404              // Left side name less than right side name
1405              // Insert name on left, leave blank filler on right
1406              sprintf(szBuf, "%s%s%s", cmp->leftdir,
1407                      cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\' ?
1408                        NullStr : "\\",
1409                      filesl[l]->fname);
1410              pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
1411              pcil->pszDisplayName = pcil->pszFileName + lenl;
1412              pcil->attrFile = filesl[l]->attrFile;
1413              // pcil->rc.hptrIcon = hptrFile;
1414              y = 0;
1415              for (x = 0; x < 6; x++)
1416                if (attrstring[x])
1417                  pcil->szDispAttr[y++] =
1418                    (CHAR) ((pcil->
1419                             attrFile & (1 << x)) ? attrstring[x] : '-');
1420              pcil->szDispAttr[5] = 0;
1421              pcil->cbFile = filesl[l]->cbFile;
1422              pcil->easize = filesl[l]->easize;
1423              pcil->date.day = filesl[l]->date.day;
1424              pcil->date.month = filesl[l]->date.month;
1425              pcil->date.year = filesl[l]->date.year + 1980;
1426              pcil->time.seconds = filesl[l]->time.twosecs * 2;
1427              pcil->time.minutes = filesl[l]->time.minutes;
1428              pcil->time.hours = filesl[l]->time.hours;
1429              pcil->ladate.day = filesl[l]->ladate.day;
1430              pcil->ladate.month = filesl[l]->ladate.month;
1431              pcil->ladate.year = filesl[l]->ladate.year + 1980;
1432              pcil->latime.seconds = filesl[l]->latime.twosecs * 2;
1433              pcil->latime.minutes = filesl[l]->latime.minutes;
1434              pcil->latime.hours = filesl[l]->latime.hours;
1435              pcil->crdate.day = filesl[l]->crdate.day;
1436              pcil->crdate.month = filesl[l]->crdate.month;
1437              pcil->crdate.year = filesl[l]->crdate.year + 1980;
1438              pcil->crtime.seconds = filesl[l]->crtime.twosecs * 2;
1439              pcil->crtime.minutes = filesl[l]->crtime.minutes;
1440              pcil->crtime.hours = filesl[l]->crtime.hours;
1441              if (*cmp->dcd.mask.szMask) {
1442                if (!Filter((PMINIRECORDCORE) pcil, (PVOID) & cmp->dcd.mask)) {
1443                  pcil->rc.flRecordAttr |= CRA_FILTERED;
1444                  pcir->rc.flRecordAttr |= CRA_FILTERED;
1445                }
1446              }
1447              free(filesl[l]);
1448              l++;
1449            }
1450            else {
1451              // Left side name larger than right side name
1452              // Insert name on right, leave blank filler on left
1453              sprintf(szBuf, "%s%s%s", cmp->rightdir,
1454                      cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\' ?
1455                        NullStr : "\\",
1456                      filesr[r]->fname);
1457              pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
1458              pcir->pszDisplayName = pcir->pszFileName + lenr;
1459              pcir->attrFile = filesr[r]->attrFile;
1460              // pcir->rc.hptrIcon = hptrFile;
1461              y = 0;
1462              for (x = 0; x < 6; x++) {
1463                if (attrstring[x])
1464                  pcir->szDispAttr[y++] =
1465                    (CHAR) ((pcir->
1466                             attrFile & (1 << x)) ? attrstring[x] : '-');
1467              }
1468              pcir->szDispAttr[5] = 0;
1469              pcir->cbFile = filesr[r]->cbFile;
1470              pcir->easize = filesr[r]->easize;
1471              pcir->date.day = filesr[r]->date.day;
1472              pcir->date.month = filesr[r]->date.month;
1473              pcir->date.year = filesr[r]->date.year + 1980;
1474              pcir->time.seconds = filesr[r]->time.twosecs * 2;
1475              pcir->time.minutes = filesr[r]->time.minutes;
1476              pcir->time.hours = filesr[r]->time.hours;
1477              pcir->ladate.day = filesr[r]->ladate.day;
1478              pcir->ladate.month = filesr[r]->ladate.month;
1479              pcir->ladate.year = filesr[r]->ladate.year + 1980;
1480              pcir->latime.seconds = filesr[r]->latime.twosecs * 2;
1481              pcir->latime.minutes = filesr[r]->latime.minutes;
1482              pcir->latime.hours = filesr[r]->latime.hours;
1483              pcir->crdate.day = filesr[r]->crdate.day;
1484              pcir->crdate.month = filesr[r]->crdate.month;
1485              pcir->crdate.year = filesr[r]->crdate.year + 1980;
1486              pcir->crtime.seconds = filesr[r]->crtime.twosecs * 2;
1487              pcir->crtime.minutes = filesr[r]->crtime.minutes;
1488              pcir->crtime.hours = filesr[r]->crtime.hours;
1489              if (*cmp->dcd.mask.szMask) {
1490                if (!Filter((PMINIRECORDCORE) pcir, (PVOID) & cmp->dcd.mask)) {
1491                  pcir->rc.flRecordAttr |= CRA_FILTERED;
1492                  pcil->rc.flRecordAttr |= CRA_FILTERED;
1493                }
1494              }
1495              free(filesr[r]);
1496              r++;
1497            }
1498          }
1499          else if (filesl && filesl[l]) {
1500            // Left side list longer than right side list
1501            // Insert name on left, leave blank filler on right
1502            sprintf(szBuf, "%s%s%s", cmp->leftdir,
1503                    cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\' ?
1504                      NullStr : "\\",
1505                    filesl[l]->fname);
1506            pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
1507            pcil->pszDisplayName = pcil->pszFileName + lenl;
1508            pcil->attrFile = filesl[l]->attrFile;
1509            // pcil->rc.hptrIcon = hptrFile;
1510            y = 0;
1511            for (x = 0; x < 6; x++)
1512              if (attrstring[x])
1513                pcil->szDispAttr[y++] = (CHAR) ((pcil->attrFile & (1 << x)) ?
1514                                                attrstring[x] : '-');
1515            pcil->szDispAttr[5] = 0;
1516            pcil->cbFile = filesl[l]->cbFile;
1517            pcil->easize = filesl[l]->easize;
1518            pcil->date.day = filesl[l]->date.day;
1519            pcil->date.month = filesl[l]->date.month;
1520            pcil->date.year = filesl[l]->date.year + 1980;
1521            pcil->time.seconds = filesl[l]->time.twosecs * 2;
1522            pcil->time.minutes = filesl[l]->time.minutes;
1523            pcil->time.hours = filesl[l]->time.hours;
1524            pcil->ladate.day = filesl[l]->ladate.day;
1525            pcil->ladate.month = filesl[l]->ladate.month;
1526            pcil->ladate.year = filesl[l]->ladate.year + 1980;
1527            pcil->latime.seconds = filesl[l]->latime.twosecs * 2;
1528            pcil->latime.minutes = filesl[l]->latime.minutes;
1529            pcil->latime.hours = filesl[l]->latime.hours;
1530            pcil->crdate.day = filesl[l]->crdate.day;
1531            pcil->crdate.month = filesl[l]->crdate.month;
1532            pcil->crdate.year = filesl[l]->crdate.year + 1980;
1533            pcil->crtime.seconds = filesl[l]->crtime.twosecs * 2;
1534            pcil->crtime.minutes = filesl[l]->crtime.minutes;
1535            pcil->crtime.hours = filesl[l]->crtime.hours;
1536            if (*cmp->dcd.mask.szMask) {
1537              if (!Filter((PMINIRECORDCORE) pcil, (PVOID) & cmp->dcd.mask)) {
1538                pcil->rc.flRecordAttr |= CRA_FILTERED;
1539                pcir->rc.flRecordAttr |= CRA_FILTERED;
1540              }
1541            }
1542            free(filesl[l]);
1543            l++;
1544          }
1545          else {
1546            // filesr && filesr[r]
1547            // Right side list longer than left side
1548            // Insert name on right, leave blank filler on left
1549            sprintf(szBuf, "%s%s%s", cmp->rightdir,
1550                    cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\' ?
1551                      NullStr : "\\",
1552                    filesr[r]->fname);
1553            pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
1554            pcir->pszDisplayName = pcir->pszFileName + lenr;
1555            pcir->attrFile = filesr[r]->attrFile;
1556            // pcir->rc.hptrIcon = hptrFile;
1557            y = 0;
1558            for (x = 0; x < 6; x++) {
1559              if (attrstring[x])
1560                pcir->szDispAttr[y++] = (CHAR) ((pcir->attrFile & (1 << x)) ?
1561                                                attrstring[x] : '-');
1562            }
1563            pcir->szDispAttr[5] = 0;
1564            pcir->cbFile = filesr[r]->cbFile;
1565            pcir->easize = filesr[r]->easize;
1566            pcir->date.day = filesr[r]->date.day;
1567            pcir->date.month = filesr[r]->date.month;
1568            pcir->date.year = filesr[r]->date.year + 1980;
1569            pcir->time.seconds = filesr[r]->time.twosecs * 2;
1570            pcir->time.minutes = filesr[r]->time.minutes;
1571            pcir->time.hours = filesr[r]->time.hours;
1572            pcir->ladate.day = filesr[r]->ladate.day;
1573            pcir->ladate.month = filesr[r]->ladate.month;
1574            pcir->ladate.year = filesr[r]->ladate.year + 1980;
1575            pcir->latime.seconds = filesr[r]->latime.twosecs * 2;
1576            pcir->latime.minutes = filesr[r]->latime.minutes;
1577            pcir->latime.hours = filesr[r]->latime.hours;
1578            pcir->crdate.day = filesr[r]->crdate.day;
1579            pcir->crdate.month = filesr[r]->crdate.month;
1580            pcir->crdate.year = filesr[r]->crdate.year + 1980;
1581            pcir->crtime.seconds = filesr[r]->crtime.twosecs * 2;
1582            pcir->crtime.minutes = filesr[r]->crtime.minutes;
1583            pcir->crtime.hours = filesr[r]->crtime.hours;
1584            if (*cmp->dcd.mask.szMask) {
1585              if (!Filter((PMINIRECORDCORE) pcir, (PVOID) & cmp->dcd.mask)) {
1586                pcir->rc.flRecordAttr |= CRA_FILTERED;
1587                pcil->rc.flRecordAttr |= CRA_FILTERED;
1588              }
1589            }
1590            free(filesr[r]);
1591            r++;
1592          }
1593
1594#endif //=========================== fixme to be gone =================
1595
1596          // Ensure empty buffers point somewhere
1597          if (!pcil->pszFileName) {
1598            pcil->pszFileName = NullStr;
1599            pcil->pszDisplayName = pcil->pszFileName;
1600          }
1601
1602          if (!pcir->pszFileName) {
1603            pcir->pszFileName = NullStr;
1604            pcir->pszDisplayName = pcir->pszFileName;
1605          }
1606
1607          pcil->rc.pszIcon = pcil->pszDisplayName;
1608          pcir->rc.pszIcon = pcir->pszDisplayName;
1609
1610          pcil->pszLongname = NullStr;
1611          pcir->pszLongname = NullStr;
1612
1613          if (!pcil->pszSubject)
1614            pcil->pszSubject = NullStr;
1615          if (!pcir->pszSubject)
1616            pcil->pszSubject = NullStr;
1617
1618          if (!pcil->pszDispAttr)
1619            pcil->pszDispAttr = NullStr;
1620          if (!pcir->pszDispAttr)
1621            pcil->pszDispAttr = NullStr;
1622
1623          // fixme to be time based - every 2 sec should be OK
1624          if (!(cntr % 500))
1625            DosSleep(1);
1626          else if (!(cntr % 50))
1627            DosSleep(1);
1628
1629          cntr++;
1630
1631          pcil = (PCNRITEM) pcil->rc.preccNextRecord;
1632          pcir = (PCNRITEM) pcir->rc.preccNextRecord;
1633
1634        } // while filling left or right
1635
1636        if (filesl)
1637          free(filesl);                 // Free header - have already freed elements
1638        filesl = NULL;
1639        if (filesr)
1640          free(filesr);
1641        filesr = NULL;
1642        // Insert 'em
1643        WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
1644
1645        memset(&ri, 0, sizeof(RECORDINSERT));
1646        ri.cb = sizeof(RECORDINSERT);
1647        ri.pRecordOrder = (PRECORDCORE) CMA_END;
1648        ri.pRecordParent = (PRECORDCORE) NULL;
1649        ri.zOrder = (ULONG) CMA_TOP;
1650        ri.cRecordsInsert = recsNeeded;
1651        ri.fInvalidateRecord = FALSE;
1652        if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
1653                        MPFROMP(pcilFirst), MPFROMP(&ri))) {
1654          Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
1655          FreeCnrItemList(hwndLeft, pcilFirst);
1656          numfilesl = 0;
1657        }
1658
1659        memset(&ri, 0, sizeof(RECORDINSERT));
1660        ri.cb = sizeof(RECORDINSERT);
1661        ri.pRecordOrder = (PRECORDCORE) CMA_END;
1662        ri.pRecordParent = (PRECORDCORE) NULL;
1663        ri.zOrder = (ULONG) CMA_TOP;
1664        ri.cRecordsInsert = recsNeeded;
1665        ri.fInvalidateRecord = FALSE;
1666
1667        if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
1668                        MPFROMP(pcirFirst), MPFROMP(&ri))) {
1669          Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
1670          RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
1671          FreeCnrItemList(hwndRight, pcirFirst);
1672          numfilesr = 0;
1673        }
1674
1675        cmp->cmp->totalleft = numfilesl;
1676        cmp->cmp->totalright = numfilesr;
1677
1678      } // if recsNeeded
1679
1680      Deselect(hwndLeft);
1681      Deselect(hwndRight);
1682
1683      if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID))
1684        WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
1685      notified = TRUE;
1686
1687      if (filesl)
1688        FreeList((CHAR **)filesl);      // Must have failed to create container
1689      if (filesr)
1690        FreeList((CHAR **)filesr);
1691
1692      WinDestroyMsgQueue(hmq);
1693    }
1694    DecrThreadUsage();
1695    WinTerminate(hab);
1696  }
1697  if (!notified)
1698    PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
1699  free(cmp);
1700  DosPostEventSem(CompactSem);
1701}
1702
1703#define hwndLeft  (WinWindowFromID(hwnd,COMP_LEFTDIR))
1704#define hwndRight (WinWindowFromID(hwnd,COMP_RIGHTDIR))
1705
1706//=== CompareDlgProc() Compare directories dialog procedure ===
1707
1708MRESULT EXPENTRY CompareDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1709{
1710  COMPARE *cmp;
1711
1712  static HPOINTER hptr = (HPOINTER) 0;
1713
1714  switch (msg) {
1715  case WM_INITDLG:
1716    cmp = (COMPARE *) mp2;
1717    if (!cmp) {
1718      Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
1719      WinDismissDlg(hwnd, 0);
1720    }
1721    else {
1722      if (!hptr)
1723        hptr = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, COMPARE_ICON);
1724      WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptr), MPVOID);
1725      cmp->hwnd = hwnd;
1726      WinSetWindowPtr(hwnd, QWL_USER, (PVOID) cmp);
1727      SetCnrCols(hwndLeft, TRUE);
1728      SetCnrCols(hwndRight, TRUE);
1729      WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
1730      WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
1731      PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
1732      {
1733        USHORT ids[] = { COMP_LEFTDIR, COMP_RIGHTDIR, COMP_TOTALLEFT,
1734                         COMP_TOTALRIGHT, COMP_SELLEFT, COMP_SELRIGHT,
1735                         0
1736                       };
1737        INT x;
1738
1739        for (x = 0; ids[x]; x++)
1740          SetPresParams(WinWindowFromID(hwnd, ids[x]),
1741                        &RGBGREY,
1742                        &RGBBLACK, &RGBBLACK, GetPString(IDS_8HELVTEXT));
1743      }
1744    }
1745    break;
1746
1747  case UM_STRETCH:
1748    {
1749      SWP swp, swpC;
1750      LONG titl, szbx, szby, sz;
1751      HWND hwndActive;
1752
1753      WinQueryWindowPos(hwnd, &swp);
1754      if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
1755        hwndActive = WinQueryFocus(HWND_DESKTOP);
1756        szbx = SysVal(SV_CXSIZEBORDER);
1757        szby = SysVal(SV_CYSIZEBORDER);
1758        titl = SysVal(SV_CYTITLEBAR);
1759        titl += 26;
1760        swp.cx -= (szbx * 2);
1761        sz = (swp.cx / 8);
1762        WinQueryWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), &swpC);
1763        WinSetWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), HWND_TOP,
1764                        szbx + 6,
1765                        swpC.y,
1766                        (swp.cx / 2) - (szbx + 6),
1767                        ((swp.cy - swpC.y) - titl) - szby,
1768                        SWP_MOVE | SWP_SIZE);
1769        WinSetWindowPos(WinWindowFromID(hwnd, COMP_RIGHTDIR), HWND_TOP,
1770                        (swp.cx / 2) + (szbx + 6),
1771                        swpC.y,
1772                        (swp.cx / 2) - (szbx + 6),
1773                        ((swp.cy - swpC.y) - titl) - szby,
1774                        SWP_MOVE | SWP_SIZE);
1775        WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFTHDR), HWND_TOP,
1776                        szbx + 6,
1777                        ((swp.cy - titl) - szby) + 4,
1778                        sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1779        WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFT), HWND_TOP,
1780                        sz + (szbx + 6),
1781                        ((swp.cy - titl) - szby) + 4,
1782                        sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1783        WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFTHDR), HWND_TOP,
1784                        (sz * 2) + (szbx + 6),
1785                        ((swp.cy - titl) - szby) + 4,
1786                        sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1787        WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFT), HWND_TOP,
1788                        (sz * 3) + (szbx + 6),
1789                        ((swp.cy - titl) - szby) + 4,
1790                        sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1791        WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHTHDR), HWND_TOP,
1792                        (sz * 4) + (szbx + 6),
1793                        ((swp.cy - titl) - szby) + 4,
1794                        sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1795        WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHT), HWND_TOP,
1796                        (sz * 5) + (szbx + 6),
1797                        ((swp.cy - titl) - szby) + 4,
1798                        sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1799        WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHTHDR), HWND_TOP,
1800                        (sz * 6) + (szbx + 6),
1801                        ((swp.cy - titl) - szby) + 4,
1802                        sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1803        WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHT), HWND_TOP,
1804                        (sz * 7) + (szbx + 6),
1805                        ((swp.cy - titl) - szby) + 4,
1806                        sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1807        PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALLEFT),
1808                            (HPS) 0, FALSE, FALSE);
1809        PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELLEFT),
1810                            (HPS) 0, FALSE, FALSE);
1811        PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALRIGHT),
1812                            (HPS) 0, FALSE, FALSE);
1813        PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELRIGHT),
1814                            (HPS) 0, FALSE, FALSE);
1815        PaintRecessedWindow(hwndLeft, (HPS) 0,
1816                            (hwndActive == hwndLeft), TRUE);
1817        PaintRecessedWindow(hwndRight, (HPS) 0,
1818                            (hwndActive == hwndRight), TRUE);
1819      }
1820    }
1821    return 0;
1822
1823  case WM_ADJUSTWINDOWPOS:
1824    PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
1825    break;
1826
1827  case UM_SETUP:
1828    {
1829      CNRINFO cnri;
1830      BOOL tempsubj;
1831
1832      cmp = INSTDATA(hwnd);
1833      if (cmp) {
1834        cmp->dcd.size = sizeof(DIRCNRDATA);
1835        cmp->dcd.type = DIR_FRAME;
1836        cmp->dcd.hwndFrame = hwnd;
1837        cmp->dcd.hwndClient = hwnd;
1838        cmp->dcd.mask.attrFile = (FILE_DIRECTORY | FILE_ARCHIVED |
1839                                  FILE_READONLY | FILE_SYSTEM | FILE_HIDDEN);
1840        LoadDetailsSwitches("DirCmp", &cmp->dcd);
1841        cmp->dcd.detailslongname = FALSE;
1842        cmp->dcd.detailsicon = FALSE;   // TRUE;
1843      }
1844      memset(&cnri, 0, sizeof(CNRINFO));
1845      cnri.cb = sizeof(CNRINFO);
1846      WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_QUERYCNRINFO,
1847                        MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1848      cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
1849      cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 68;
1850      WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
1851                        MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
1852      memset(&cnri, 0, sizeof(CNRINFO));
1853      cnri.cb = sizeof(CNRINFO);
1854      WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_QUERYCNRINFO,
1855                        MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1856      cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
1857      cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 54;
1858      WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
1859                        MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
1860      AdjustCnrColRO(hwndLeft, GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
1861      AdjustCnrColRO(hwndLeft, GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
1862      AdjustCnrColRO(hwndRight, GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
1863      AdjustCnrColRO(hwndRight, GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
1864      AdjustCnrColsForPref(hwndLeft, cmp->leftdir, &cmp->dcd, TRUE);
1865      tempsubj = cmp->dcd.detailssubject;
1866      cmp->dcd.detailssubject = FALSE;
1867      AdjustCnrColsForPref(hwndRight, cmp->rightdir, &cmp->dcd, TRUE);
1868      if (*cmp->rightlist) {
1869        AdjustCnrColVis(hwndRight, GetPString(IDS_LADATECOLTEXT), FALSE,
1870                        FALSE);
1871        AdjustCnrColVis(hwndRight, GetPString(IDS_LATIMECOLTEXT), FALSE,
1872                        FALSE);
1873        AdjustCnrColVis(hwndRight, GetPString(IDS_CRDATECOLTEXT), FALSE,
1874                        FALSE);
1875        AdjustCnrColVis(hwndRight, GetPString(IDS_CRTIMECOLTEXT), FALSE,
1876                        FALSE);
1877      }
1878      cmp->dcd.detailssubject = tempsubj;
1879    }
1880    return 0;
1881
1882  case WM_DRAWITEM:
1883    if (mp2) {
1884      POWNERITEM pown = (POWNERITEM)mp2;
1885      PCNRDRAWITEMINFO pcown;
1886      PCNRITEM pci;
1887
1888      pcown = (PCNRDRAWITEMINFO)pown->hItem;
1889      if (pcown) {
1890        pci = (PCNRITEM) pcown->pRecord;
1891        // 01 Aug 07 SHL if field null or blank, we draw
1892        // fixme to know why - probably to optimize and bypass draw?
1893        if (pci && (INT)pci != -1 && !*pci->pszFileName)
1894          return MRFROMLONG(TRUE);
1895      }
1896    }
1897    return 0;
1898
1899  case UM_CONTAINERHWND:
1900    WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDBLDLISTTEXT));
1901    return 0;
1902
1903  case UM_CONTAINERDIR:
1904    WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDFILLCNRTEXT));
1905    return 0;
1906
1907  case UM_CONTAINER_FILLED:
1908    cmp = INSTDATA(hwnd);
1909    if (!cmp) {
1910      Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL");
1911      WinDismissDlg(hwnd, 0);
1912    }
1913    else {
1914      CHAR s[81];
1915
1916      cmp->filling = FALSE;
1917      WinEnableWindow(hwndLeft, TRUE);
1918      WinEnableWindow(hwndRight, TRUE);
1919      WinEnableWindowUpdate(hwndLeft, TRUE);
1920      WinEnableWindowUpdate(hwndRight, TRUE);
1921      sprintf(s, " %d", cmp->totalleft);
1922      WinSetDlgItemText(hwnd, COMP_TOTALLEFT, s);
1923      sprintf(s, " %d", cmp->totalright);
1924      WinSetDlgItemText(hwnd, COMP_TOTALRIGHT, s);
1925      sprintf(s, " %d", cmp->selleft);
1926      WinSetDlgItemText(hwnd, COMP_SELLEFT, s);
1927      sprintf(s, " %d", cmp->selright);
1928      WinSetDlgItemText(hwnd, COMP_SELRIGHT, s);
1929      WinEnableWindow(WinWindowFromID(hwnd, DID_OK), TRUE);
1930      WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), TRUE);
1931      WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), TRUE);
1932      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), TRUE);
1933      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), TRUE);
1934      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), TRUE);
1935      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), TRUE);
1936      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), TRUE);
1937      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), TRUE);
1938      WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), TRUE);
1939      WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), TRUE);
1940      WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), TRUE);
1941      WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), TRUE);
1942      WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), TRUE);
1943      WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), TRUE);
1944      WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), TRUE);
1945      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), TRUE);
1946      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), TRUE);
1947      WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), TRUE);
1948      WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), TRUE);
1949      WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), TRUE);
1950      WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), TRUE);
1951      WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), TRUE);
1952      if (!*cmp->rightlist) {
1953        WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), TRUE);
1954        WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), TRUE);
1955        WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), TRUE);
1956        WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), TRUE);
1957        WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), TRUE);
1958      }
1959      WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), TRUE);
1960      if (*cmp->dcd.mask.szMask)
1961        WinSetDlgItemText(hwnd, COMP_NOTE,
1962                          GetPString(IDS_COMPREADYFILTEREDTEXT));
1963      else
1964        WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
1965    }
1966    break;
1967
1968  case WM_INITMENU:
1969    cmp = INSTDATA(hwnd);
1970    if (cmp) {
1971      switch (SHORT1FROMMP(mp1)) {
1972      case IDM_COMMANDSMENU:
1973        SetupCommandMenu(cmp->dcd.hwndLastMenu, hwnd);
1974        break;
1975      }
1976    }
1977    break;
1978
1979  case WM_MENUEND:
1980    cmp = INSTDATA(hwnd);
1981    if (cmp) {
1982      if ((HWND) mp2 == cmp->dcd.hwndLastMenu) {
1983        MarkAll(hwndLeft, TRUE, FALSE, TRUE);
1984        MarkAll(hwndRight, TRUE, FALSE, TRUE);
1985        WinDestroyWindow(cmp->dcd.hwndLastMenu);
1986        cmp->dcd.hwndLastMenu = (HWND) 0;
1987      }
1988    }
1989    break;
1990
1991  case WM_CONTROL:
1992    switch (SHORT1FROMMP(mp1)) {
1993    case COMP_INCLUDESUBDIRS:
1994      switch (SHORT2FROMMP(mp1)) {
1995      case BN_CLICKED:
1996        cmp = INSTDATA(hwnd);
1997        if (cmp)
1998          *cmp->rightlist = 0;
1999        PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2000        PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2001        break;
2002      }
2003      break;
2004    case COMP_HIDENOTSELECTED:
2005      switch (SHORT2FROMMP(mp1)) {
2006      case BN_CLICKED:
2007        WinSendMsg(hwnd, UM_HIDENOTSELECTED, MPVOID, MPVOID);
2008        break;
2009      }
2010      break;
2011
2012    case COMP_LEFTDIR:
2013    case COMP_RIGHTDIR:
2014      switch (SHORT2FROMMP(mp1)) {
2015      case CN_KILLFOCUS:
2016        PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
2017                            (HPS) 0, FALSE, TRUE);
2018        break;
2019
2020      case CN_SETFOCUS:
2021        PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
2022                            (HPS) 0, TRUE, TRUE);
2023        break;
2024
2025      case CN_ENTER:
2026        if (mp2) {
2027
2028          PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
2029          HWND hwndCnr = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
2030
2031          SetShiftState();
2032          if (pci) {
2033            if (pci->rc.flRecordAttr & CRA_INUSE || !pci || !*pci->pszFileName)
2034              break;
2035            WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
2036                       MPFROM2SHORT(TRUE, CRA_INUSE));
2037            if (pci->attrFile & FILE_DIRECTORY) {
2038              if ((shiftstate & (KC_CTRL | KC_SHIFT)) == (KC_CTRL | KC_SHIFT))
2039                OpenObject(pci->pszFileName, Settings, hwnd);
2040              else
2041                OpenObject(pci->pszFileName, Default, hwnd);
2042            }
2043            else
2044              DefaultViewKeys(hwnd, hwnd, HWND_DESKTOP, NULL,
2045                              pci->pszFileName);
2046            WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS,
2047                       MPFROMP(pci),
2048                       MPFROM2SHORT(FALSE, CRA_INUSE |
2049                                    ((fUnHilite) ? CRA_SELECTED : 0)));
2050          }
2051        }
2052        break;
2053
2054      case CN_CONTEXTMENU:
2055        cmp = INSTDATA(hwnd);
2056        if (cmp) {
2057
2058          PCNRITEM pci = (PCNRITEM) mp2;
2059          USHORT id = COMP_CNRMENU;
2060
2061          if (cmp->dcd.hwndLastMenu)
2062            WinDestroyWindow(cmp->dcd.hwndLastMenu);
2063          cmp->dcd.hwndLastMenu = (HWND) 0;
2064          cmp->hwndCalling = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
2065          if (pci) {
2066            if (!pci || !*pci->pszFileName || *cmp->rightlist)
2067              break;
2068            id = COMP_MENU;
2069            WinSendMsg(cmp->hwndCalling, CM_SETRECORDEMPHASIS,
2070                       MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
2071          }
2072          cmp->dcd.hwndLastMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
2073          if (cmp->dcd.hwndLastMenu) {
2074            if (id == COMP_CNRMENU) {
2075              if (SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
2076                WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2077                           MPFROM2SHORT(IDM_SHOWSUBJECT, FALSE), MPVOID);
2078              SetDetailsSwitches(cmp->dcd.hwndLastMenu, &cmp->dcd);
2079              if (SHORT1FROMMP(mp1) == COMP_LEFTDIR)
2080                WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2081                           MPFROM2SHORT(IDM_LOADLISTFILE, 0), MPVOID);
2082              else if (*cmp->rightlist)
2083                WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2084                           MPFROM2SHORT(IDM_SAVELISTFILE, 0), MPVOID);
2085            }
2086            PopupMenu(hwnd, hwnd, cmp->dcd.hwndLastMenu);
2087          }
2088        }
2089        break;
2090
2091      case CN_INITDRAG:
2092        cmp = INSTDATA(hwnd);
2093        if (*cmp->rightlist && SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
2094          break;
2095        DoFileDrag(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
2096                   (HWND) 0, mp2, NULL, NULL, TRUE);
2097        break;
2098
2099      case CN_BEGINEDIT:
2100      case CN_REALLOCPSZ:
2101        // fixme to be gone - field edits not allowed
2102        Runtime_Error(pszSrcFile, __LINE__,
2103                      "CN_BEGINEDIT/CN_REALLOCPSZ unexpected");
2104        break;
2105
2106      case CN_EMPHASIS:
2107        {
2108          PNOTIFYRECORDEMPHASIS pre = mp2;
2109          PCNRITEM pci;
2110
2111          if (pre->fEmphasisMask & CRA_SELECTED) {
2112            pci = (PCNRITEM) pre->pRecord;
2113            if (pci) {
2114              if (!pci || !*pci->pszFileName) {
2115                if (pci->rc.flRecordAttr & CRA_SELECTED)
2116                  WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1),
2117                                    CM_SETRECORDEMPHASIS,
2118                                    MPFROMP(pci),
2119                                    MPFROM2SHORT(FALSE, CRA_SELECTED));
2120              }
2121              else {
2122
2123                CHAR s[81];
2124
2125                cmp = INSTDATA(hwnd);
2126                if (pci->rc.flRecordAttr & CRA_SELECTED) {
2127                  if (SHORT1FROMMP(mp1) == COMP_LEFTDIR)
2128                    cmp->selleft++;
2129                  else
2130                    cmp->selright++;
2131                }
2132                else {
2133                  if (SHORT1FROMMP(mp1) == COMP_LEFTDIR) {
2134                    if (cmp->selleft)
2135                      cmp->selleft--;
2136                  }
2137                  else {
2138                    if (cmp->selright)
2139                      cmp->selright--;
2140                  }
2141                }
2142                if (SHORT1FROMMP(mp1) == COMP_LEFTDIR) {
2143                  if (WinIsWindowEnabled(hwndLeft) || !(cmp->selleft % 50)) {
2144                    sprintf(s, " %d", cmp->selleft);
2145                    WinSetDlgItemText(hwnd, COMP_SELLEFT, s);
2146                  }
2147                }
2148                else {
2149                  if (WinIsWindowEnabled(hwndRight) || !(cmp->selright % 50)) {
2150                    sprintf(s, " %d", cmp->selright);
2151                    WinSetDlgItemText(hwnd, COMP_SELRIGHT, s);
2152                  }
2153                }
2154              }
2155            }
2156          }
2157        }
2158        break;
2159
2160      case CN_SCROLL:
2161        cmp = INSTDATA(hwnd);
2162        if (!cmp->forcescroll) {
2163
2164          PNOTIFYSCROLL pns = mp2;
2165
2166          if (pns->fScroll & CMA_VERTICAL) {
2167            cmp->forcescroll = TRUE;
2168            WinSendDlgItemMsg(hwnd, (SHORT1FROMMP(mp1) == COMP_LEFTDIR) ?
2169                              COMP_RIGHTDIR : COMP_LEFTDIR,
2170                              CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL),
2171                              MPFROMLONG(pns->lScrollInc));
2172            cmp->forcescroll = FALSE;
2173          }
2174        }
2175        break;
2176      }
2177      break;                            // COMP_RIGHTDIR
2178    }
2179    return 0;                           // WM_CONTROL
2180
2181  case UM_SETDIR:
2182    cmp = INSTDATA(hwnd);
2183    if (cmp) {
2184
2185      COMPARE *forthread;
2186      CNRINFO cnri;
2187
2188      cmp->includesubdirs = WinQueryButtonCheckstate(hwnd,
2189                                                     COMP_INCLUDESUBDIRS);
2190      memset(&cnri, 0, sizeof(CNRINFO));
2191      cnri.cb = sizeof(CNRINFO);
2192      cnri.pszCnrTitle = cmp->leftdir;
2193      cnri.flWindowAttr = CV_DETAIL | CV_MINI |
2194                          CA_CONTAINERTITLE | CA_TITLESEPARATOR |
2195                          CA_DETAILSVIEWTITLES | CA_OWNERDRAW;
2196      WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2197                        MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
2198      cnri.pszCnrTitle = cmp->rightdir;
2199      WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2200                        MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
2201      WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 0);
2202      cmp->filling = TRUE;
2203      forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2204      if (!forthread)
2205        WinDismissDlg(hwnd, 0);
2206      else {
2207        *forthread = *cmp;
2208        forthread->cmp = cmp;
2209        if (_beginthread(FillCnrsThread, NULL, 122880, (PVOID) forthread) ==
2210            -1) {
2211          Runtime_Error(pszSrcFile, __LINE__,
2212                        GetPString(IDS_COULDNTSTARTTHREADTEXT));
2213          WinDismissDlg(hwnd, 0);
2214          free(forthread);
2215        }
2216        else {
2217          WinEnableWindowUpdate(hwndLeft, FALSE);
2218          WinEnableWindowUpdate(hwndRight, FALSE);
2219          cmp->selleft = cmp->selright = 0;
2220          WinSetDlgItemText(hwnd, COMP_SELLEFT, "0");
2221          WinSetDlgItemText(hwnd, COMP_SELRIGHT, "0");
2222          WinSetDlgItemText(hwnd, COMP_TOTALLEFT, "0");
2223          WinSetDlgItemText(hwnd, COMP_TOTALRIGHT, "0");
2224          WinSetDlgItemText(hwnd, COMP_NOTE,
2225                            GetPString(IDS_COMPHOLDREADDISKTEXT));
2226          WinEnableWindow(hwndRight, FALSE);
2227          WinEnableWindow(hwndLeft, FALSE);
2228          WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
2229          WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
2230          WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
2231          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
2232          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
2233          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
2234          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
2235          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
2236          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
2237          WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
2238          WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
2239          WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
2240          WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
2241          WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
2242          WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), FALSE);
2243          WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
2244          WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), FALSE);
2245          WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
2246          WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
2247          WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
2248          WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
2249          WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
2250          WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
2251          WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
2252          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT),
2253                          FALSE);
2254          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), FALSE);
2255          WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
2256          WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
2257          WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
2258        }
2259      }
2260    }
2261    return 0;
2262
2263  case UM_FILTER:
2264    cmp = INSTDATA(hwnd);
2265    if (cmp) {
2266      if (mp1) {
2267        DosEnterCritSec();
2268        SetMask((CHAR *) mp1, &cmp->dcd.mask);
2269        DosExitCritSec();
2270      }
2271      cmp->dcd.suspendview = 1;
2272      WinSendMsg(hwndLeft, CM_FILTER, MPFROMP(Filter),
2273                 MPFROMP(&cmp->dcd.mask));
2274      WinSendMsg(hwndRight, CM_FILTER, MPFROMP(Filter),
2275                 MPFROMP(&cmp->dcd.mask));
2276      cmp->dcd.suspendview = 0;
2277      if (*cmp->dcd.mask.szMask)
2278        WinSetDlgItemText(hwnd, COMP_NOTE,
2279                          GetPString(IDS_COMPREADYFILTEREDTEXT));
2280      else
2281        WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
2282    }
2283    return 0;
2284
2285  case UM_HIDENOTSELECTED:
2286    cmp = INSTDATA(hwnd);
2287    if (cmp) {
2288      USHORT wantHide = WinQueryButtonCheckstate(hwnd,
2289                                                 COMP_HIDENOTSELECTED);
2290
2291      cmp->dcd.suspendview = 1;
2292      if (wantHide) {
2293        BOOL needRefresh = FALSE;
2294        HWND hwndl = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
2295        HWND hwndr = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
2296        PCNRITEM pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPVOID,
2297                                   MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2298        PCNRITEM pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPVOID,
2299                                   MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2300
2301        while (pcil && (INT) pcil != -1 && pcir && (INT) pcir != -1) {
2302          if (~pcil->rc.flRecordAttr & CRA_SELECTED &&
2303              ~pcir->rc.flRecordAttr & CRA_SELECTED) {
2304            pcil->rc.flRecordAttr |= CRA_FILTERED;
2305            pcir->rc.flRecordAttr |= CRA_FILTERED;
2306            needRefresh = TRUE;
2307          }
2308          pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPFROMP(pcil),
2309                            MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2310          pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPFROMP(pcir),
2311                            MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2312        } // while
2313        if (needRefresh) {
2314          WinSendMsg(hwndl, CM_INVALIDATERECORD,
2315                     MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
2316          WinSendMsg(hwndr, CM_INVALIDATERECORD,
2317                     MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
2318        }
2319      }
2320      else {
2321        WinSendMsg(hwndLeft, CM_FILTER, MPFROMP(Filter),
2322                   MPFROMP(&cmp->dcd.mask));
2323        WinSendMsg(hwndRight, CM_FILTER, MPFROMP(Filter),
2324                   MPFROMP(&cmp->dcd.mask));
2325      }
2326      cmp->dcd.suspendview = 0;
2327      if (*cmp->dcd.mask.szMask)
2328        WinSetDlgItemText(hwnd, COMP_NOTE,
2329                          GetPString(IDS_COMPREADYFILTEREDTEXT));
2330      else
2331        WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
2332    }
2333    return 0;
2334
2335  case WM_COMMAND:
2336    switch (SHORT1FROMMP(mp1)) {
2337    case IDM_COMPARE:
2338      cmp = INSTDATA(hwnd);
2339      if (cmp) {
2340
2341        PCNRITEM pci;
2342        CHAR ofile[CCHMAXPATH];
2343
2344        pci = (PCNRITEM) WinSendMsg(cmp->hwndCalling,
2345                                    CM_QUERYRECORDEMPHASIS,
2346                                    MPFROMLONG(CMA_FIRST),
2347                                    MPFROMSHORT(CRA_CURSORED));
2348        // 01 Aug 07 SHL
2349        if (pci && *pci->pszFileName) {
2350          if (cmp->hwndCalling == hwndLeft)
2351            strcpy(ofile, cmp->rightdir);
2352          else
2353            strcpy(ofile, cmp->leftdir);
2354          if (ofile[strlen(ofile) - 1] != '\\')
2355            strcat(ofile, "\\");
2356          strcat(ofile, pci->pszDisplayName);
2357          if (*compare) {
2358            CHAR *fakelist[3];
2359            fakelist[0] = pci->pszFileName;
2360            fakelist[1] = ofile;
2361            fakelist[2] = NULL;
2362            ExecOnList(hwnd, compare,
2363                       WINDOWED | SEPARATEKEEP, NULL, fakelist, NULL);
2364          }
2365          else {
2366            FCOMPARE fc;
2367            memset(&fc, 0, sizeof(fc));
2368            fc.size = sizeof(fc);
2369            fc.hwndParent = hwnd;
2370            strcpy(fc.file1, pci->pszFileName);
2371            strcpy(fc.file2, ofile);
2372            WinDlgBox(HWND_DESKTOP, hwnd,
2373                      CFileDlgProc, FM3ModHandle, FCMP_FRAME, (PVOID) & fc);
2374          }
2375        }
2376      }
2377      break;
2378
2379    case COMP_FILTER:
2380    case IDM_FILTER:
2381      cmp = INSTDATA(hwnd);
2382      if (cmp) {
2383
2384        BOOL empty = FALSE;
2385        PCNRITEM pci;
2386        CHAR *p;
2387        BOOL temp;
2388
2389        if (!*cmp->dcd.mask.szMask) {
2390          empty = TRUE;
2391          temp = fSelectedAlways;
2392          fSelectedAlways = TRUE;
2393          pci = (PCNRITEM)CurrentRecord(hwnd);
2394          fSelectedAlways = temp;
2395          // 01 Aug 07 SHL
2396          if (pci && ~pci->attrFile & FILE_DIRECTORY) {
2397            p = strrchr(pci->pszFileName, '\\');
2398            if (p) {
2399              p++;
2400              strcpy(cmp->dcd.mask.szMask, p);
2401            }
2402          }
2403        }
2404        cmp->dcd.mask.fNoAttribs = TRUE;
2405        cmp->dcd.mask.attrFile = ALLATTRS;
2406        cmp->dcd.mask.antiattr = 0;
2407        if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
2408                      FM3ModHandle, MSK_FRAME, MPFROMP(&cmp->dcd.mask))) {
2409          cmp->dcd.mask.attrFile = ALLATTRS;
2410          cmp->dcd.mask.antiattr = 0;
2411          WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2412        }
2413        else if (empty) {
2414          *cmp->dcd.mask.szMask = 0;
2415          cmp->dcd.mask.attrFile = ALLATTRS;
2416          cmp->dcd.mask.antiattr = 0;
2417        }
2418      }
2419      break;
2420
2421    case IDM_SHOWSUBJECT:
2422    case IDM_SHOWEAS:
2423    case IDM_SHOWSIZE:
2424    case IDM_SHOWLWDATE:
2425    case IDM_SHOWLWTIME:
2426    case IDM_SHOWLADATE:
2427    case IDM_SHOWLATIME:
2428    case IDM_SHOWCRDATE:
2429    case IDM_SHOWCRTIME:
2430    case IDM_SHOWATTR:
2431      cmp = INSTDATA(hwnd);
2432      if (cmp) {
2433
2434        DIRCNRDATA dcd1;
2435        BOOL tempsubj;
2436
2437        dcd1 = cmp->dcd;
2438        AdjustDetailsSwitches(hwndLeft,
2439                              (HWND) 0, SHORT1FROMMP(mp1),
2440                              cmp->leftdir, "DirCmp", &cmp->dcd, TRUE);
2441        tempsubj = cmp->dcd.detailssubject;
2442        cmp->dcd = dcd1;
2443        cmp->dcd.detailssubject = FALSE;
2444        AdjustDetailsSwitches(hwndRight,
2445                              cmp->dcd.hwndLastMenu, SHORT1FROMMP(mp1),
2446                              cmp->rightdir, "DirCmp", &cmp->dcd, TRUE);
2447        cmp->dcd.detailssubject = tempsubj;
2448      }
2449      break;
2450
2451    case IDM_LOADLISTFILE:
2452      cmp = INSTDATA(hwnd);
2453      if (cmp) {
2454
2455        CHAR fullname[CCHMAXPATH];
2456
2457        strcpy(fullname, "*.PMD");
2458        if (insert_filename(HWND_DESKTOP, fullname, TRUE, FALSE) &&
2459            *fullname && !strchr(fullname, '*') && !strchr(fullname, '?')) {
2460          strcpy(cmp->rightlist, fullname);
2461          PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2462          PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2463        }
2464      }
2465      break;
2466
2467    case IDM_SAVELISTFILE:
2468      cmp = INSTDATA(hwnd);
2469      if (cmp) {
2470
2471        SNAPSTUFF *sf;
2472        CHAR fullname[CCHMAXPATH];
2473
2474        strcpy(fullname, "*.PMD");
2475        if (export_filename(HWND_DESKTOP, fullname, 1) && *fullname &&
2476            !strchr(fullname, '*') && !strchr(fullname, '?')) {
2477          sf = xmallocz(sizeof(SNAPSTUFF), pszSrcFile, __LINE__);
2478          if (sf) {
2479            strcpy(sf->filename, fullname);
2480            if (hwndLeft == cmp->hwndCalling)
2481              strcpy(sf->dirname, cmp->leftdir);
2482            else
2483              strcpy(sf->dirname, cmp->rightdir);
2484            sf->recurse = cmp->includesubdirs;
2485            if (_beginthread(StartSnap, NULL, 65536, (PVOID) sf) == -1) {
2486              Runtime_Error(pszSrcFile, __LINE__,
2487                            GetPString(IDS_COULDNTSTARTTHREADTEXT));
2488              free(sf);
2489            }
2490          }
2491        }
2492      }
2493      break;
2494
2495    case COMP_SETDIRS:
2496      cmp = INSTDATA(hwnd);
2497      if (cmp) {
2498
2499        WALK2 wa;
2500
2501        memset(&wa, 0, sizeof(wa));
2502        wa.size = sizeof(wa);
2503        strcpy(wa.szCurrentPath1, cmp->leftdir);
2504        strcpy(wa.szCurrentPath2, cmp->rightdir);
2505        if (WinDlgBox(HWND_DESKTOP, hwnd, WalkTwoCmpDlgProc,
2506                      FM3ModHandle, WALK2_FRAME,
2507                      MPFROMP(&wa)) &&
2508            !IsFile(wa.szCurrentPath1) && !IsFile(wa.szCurrentPath2)) {
2509          strcpy(cmp->leftdir, wa.szCurrentPath1);
2510          strcpy(cmp->rightdir, wa.szCurrentPath2);
2511          *cmp->rightlist = 0;
2512          PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2513          PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2514        }
2515      }
2516      break;
2517
2518    case COMP_COPYLEFT:
2519    case COMP_MOVELEFT:
2520    case COMP_COPYRIGHT:
2521    case COMP_MOVERIGHT:
2522    case COMP_DELETELEFT:
2523    case COMP_DELETERIGHT:
2524      cmp = INSTDATA(hwnd);
2525      if (cmp) {
2526
2527        COMPARE *forthread;
2528
2529        cmp->filling = TRUE;
2530        forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2531        if (forthread) {
2532          *forthread = *cmp;
2533          forthread->cmp = cmp;
2534          forthread->action = SHORT1FROMMP(mp1);
2535          if (_beginthread(ActionCnrThread, NULL, 122880, (PVOID) forthread)
2536              == -1) {
2537            Runtime_Error(pszSrcFile, __LINE__,
2538                          GetPString(IDS_COULDNTSTARTTHREADTEXT));
2539            free(forthread);
2540          }
2541          else {
2542            WinEnableWindowUpdate(hwndLeft, FALSE);
2543            WinEnableWindowUpdate(hwndRight, FALSE);
2544            switch (SHORT1FROMMP(mp1)) {
2545            case COMP_DELETELEFT:
2546            case COMP_DELETERIGHT:
2547              WinSetDlgItemText(hwnd, COMP_NOTE,
2548                                GetPString(IDS_COMPHOLDDELETINGTEXT));
2549              break;
2550            case COMP_MOVELEFT:
2551            case COMP_MOVERIGHT:
2552              WinSetDlgItemText(hwnd, COMP_NOTE,
2553                                GetPString(IDS_COMPHOLDMOVINGTEXT));
2554              break;
2555            case COMP_COPYLEFT:
2556            case COMP_COPYRIGHT:
2557              WinSetDlgItemText(hwnd, COMP_NOTE,
2558                                GetPString(IDS_COMPHOLDCOPYINGTEXT));
2559              break;
2560            default:
2561              WinSetDlgItemText(hwnd, COMP_NOTE,
2562                                GetPString(IDS_COMPHOLDDUNNOTEXT));
2563              break;
2564            }
2565            WinEnableWindow(hwndRight, FALSE);
2566            WinEnableWindow(hwndLeft, FALSE);
2567            WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
2568            WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
2569            WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
2570            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
2571            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
2572            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
2573            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
2574            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
2575            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
2576            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
2577            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
2578            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
2579            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
2580            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
2581            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER),
2582                            FALSE);
2583            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
2584            WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS),
2585                            FALSE);
2586            WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
2587            WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
2588            WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
2589            WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
2590            WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
2591            WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
2592            WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
2593            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT),
2594                            FALSE);
2595            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL),
2596                            FALSE);
2597            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
2598            WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
2599            WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
2600          }
2601        }
2602      }
2603      break;
2604
2605    case DID_OK:
2606      WinDismissDlg(hwnd, 0);
2607      break;
2608    case DID_CANCEL:
2609      WinDismissDlg(hwnd, 1);
2610      break;
2611
2612    case IDM_HELP:
2613      if (hwndHelp)
2614        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
2615                   MPFROM2SHORT(HELP_COMPARE, 0), MPFROMSHORT(HM_RESOURCEID));
2616      break;
2617
2618    case IDM_DESELECTALL:
2619    case IDM_SELECTNEWER:
2620    case IDM_SELECTOLDER:
2621    case IDM_SELECTBIGGER:
2622    case IDM_SELECTSMALLER:
2623    case IDM_DESELECTNEWER:
2624    case IDM_DESELECTOLDER:
2625    case IDM_DESELECTBIGGER:
2626    case IDM_DESELECTSMALLER:
2627    case IDM_DESELECTONE:
2628    case IDM_DESELECTBOTH:
2629    case IDM_SELECTBOTH:
2630    case IDM_SELECTONE:
2631    case IDM_SELECTSAMECONTENT:
2632    case IDM_SELECTIDENTICAL:           // Name, size and time
2633    case IDM_SELECTSAME:                // Name and size
2634    case IDM_INVERT:
2635      cmp = INSTDATA(hwnd);
2636      if (!cmp)
2637        Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2638      else {
2639        COMPARE *forthread;
2640
2641        cmp->filling = TRUE;
2642        forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2643        if (forthread) {
2644          *forthread = *cmp;
2645          forthread->cmp = cmp;
2646          forthread->action = SHORT1FROMMP(mp1);
2647          if (_beginthread(SelectCnrsThread, NULL, 65536, (PVOID) forthread)
2648              == -1) {
2649            Runtime_Error(pszSrcFile, __LINE__,
2650                          GetPString(IDS_COULDNTSTARTTHREADTEXT));
2651            free(forthread);
2652          }
2653          else {
2654            WinEnableWindowUpdate(hwndLeft, FALSE);
2655            WinEnableWindowUpdate(hwndRight, FALSE);
2656            switch (SHORT1FROMMP(mp1)) {
2657            case IDM_DESELECTALL:
2658            case IDM_DESELECTNEWER:
2659            case IDM_DESELECTOLDER:
2660            case IDM_DESELECTBIGGER:
2661            case IDM_DESELECTSMALLER:
2662            case IDM_DESELECTONE:
2663            case IDM_DESELECTBOTH:
2664              WinSetDlgItemText(hwnd, COMP_NOTE,
2665                                GetPString(IDS_COMPHOLDDESELTEXT));
2666              break;
2667            case IDM_INVERT:
2668              WinSetDlgItemText(hwnd, COMP_NOTE,
2669                                GetPString(IDS_COMPHOLDINVERTTEXT));
2670              break;
2671            default:
2672              WinSetDlgItemText(hwnd, COMP_NOTE,
2673                                GetPString(IDS_COMPHOLDSELTEXT));
2674              break;
2675            }
2676            WinEnableWindow(hwndRight, FALSE);
2677            WinEnableWindow(hwndLeft, FALSE);
2678            WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
2679            WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
2680            WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
2681            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
2682            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
2683            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
2684            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
2685            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
2686            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
2687            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
2688            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
2689            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
2690            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
2691            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
2692            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER),
2693                            FALSE);
2694            WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
2695            WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS),
2696                            FALSE);
2697            WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
2698            WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
2699            WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
2700            WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
2701            WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
2702            WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
2703            WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
2704            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT),
2705                            FALSE);
2706            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL),
2707                            FALSE);
2708            WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
2709            WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
2710            WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
2711          }
2712        }
2713      }
2714      break;
2715
2716    case COMP_COLLECT:
2717      cmp = INSTDATA(hwnd);
2718      if (cmp) {
2719
2720        CHAR **listl, **listr = NULL;
2721
2722        if (!Collector) {
2723
2724          SWP swp;
2725          HWND hwndC;
2726
2727          if (!fAutoTile && !ParentIsDesktop(hwnd, cmp->hwndParent) &&
2728              (!fExternalCollector && !strcmp(realappname, FM3Str)))
2729            GetNextWindowPos(cmp->hwndParent, &swp, NULL, NULL);
2730          hwndC = StartCollector((fExternalCollector ||
2731                                  strcmp(realappname, FM3Str)) ?
2732                                 HWND_DESKTOP : cmp->hwndParent, 4);
2733          if (hwndC) {
2734            if (!fAutoTile && !ParentIsDesktop(hwnd, cmp->hwndParent) &&
2735                (!fExternalCollector && !strcmp(realappname, FM3Str)))
2736              WinSetWindowPos(hwndC, HWND_TOP, swp.x, swp.y,
2737                              swp.cx, swp.cy, SWP_MOVE | SWP_SIZE |
2738                              SWP_SHOW | SWP_ZORDER);
2739            else if (!ParentIsDesktop(hwnd, cmp->hwndParent) && fAutoTile &&
2740                     !strcmp(realappname, FM3Str))
2741              TileChildren(cmp->hwndParent, TRUE);
2742            DosSleep(64);
2743            PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(COMP_COLLECT, 0), MPVOID);
2744            break;
2745          }
2746        }
2747        else
2748          StartCollector(cmp->hwndParent, 4);
2749        {
2750          BOOL temp;
2751
2752          temp = fSelectedAlways;
2753          fSelectedAlways = TRUE;
2754          listl = BuildList(hwndLeft);
2755          if (!*cmp->rightlist)
2756            listr = BuildList(hwndRight);
2757          fSelectedAlways = temp;
2758        }
2759        if (listl || listr) {
2760          if (Collector) {
2761            if (listl) {
2762              if (!PostMsg(Collector, WM_COMMAND,
2763                           MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listl)))
2764                FreeList(listl);
2765            }
2766            if (listr) {
2767              if (!PostMsg(Collector, WM_COMMAND,
2768                           MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listr)))
2769                FreeList(listr);
2770            }
2771            WinSetWindowPos(WinQueryWindow(WinQueryWindow(Collector,
2772                                                          QW_PARENT),
2773                                           QW_PARENT), HWND_TOP, 0, 0, 0, 0,
2774                            SWP_ACTIVATE);
2775          }
2776          else {
2777            FreeList(listl);
2778            FreeList(listr);
2779          }
2780        }
2781      }
2782      break;
2783    }
2784    return 0;
2785
2786  case WM_CLOSE:
2787    WinDismissDlg(hwnd, 0);
2788    return 0;
2789
2790  case WM_DESTROY:
2791    cmp = INSTDATA(hwnd);
2792    if (cmp) {
2793      if (cmp->dcd.hwndLastMenu)
2794        WinDestroyWindow(cmp->dcd.hwndLastMenu);
2795      if (cmp->dcd.hwndObject) {
2796        WinSetWindowPtr(cmp->dcd.hwndObject, QWL_USER, (PVOID) NULL);
2797        if (!PostMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID))
2798          WinSendMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID);
2799      }
2800      free(cmp);
2801    }
2802    EmptyCnr(hwndLeft);
2803    EmptyCnr(hwndRight);
2804    DosPostEventSem(CompactSem);
2805    break;
2806  }
2807  return WinDefDlgProc(hwnd, msg, mp1, mp2);
2808}
Note: See TracBrowser for help on using the repository browser.