source: trunk/dll/comp.c @ 551

Last change on this file since 551 was 551, checked in by Gregg Young, 14 years ago

Indentation cleanup

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