source: trunk/dll/comp.c @ 748

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

Rework comp.c to to sync with CNRITEM mods
Rework comp.c to remove vast amount of duplicate code
Clean up select.c while auditing for CNRITEM sync
Sync fm3dll.h with comp.c mods

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