source: trunk/dll/comp.c@ 938

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

Compare directory dialog saves and restores size and position (Ticket 49)

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