source: trunk/dll/comp.c@ 929

Last change on this file since 929 was 929, checked in by Steven Levine, 18 years ago

Compare directories rework.
Change hide not selected to 3 state checkbox.
Honor filters in actions.
Do all total and select count updates on WM_TIMER.

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