source: trunk/dll/comp.c@ 959

Last change on this file since 959 was 959, checked in by Gregg Young, 18 years ago

Use xfree where appropriate. Check that buffer exists following all xmallocs. Stopped at eas.c with xfree checking. One remaining xmalloc without test in dirsize.c

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