source: trunk/dll/comp.c@ 985

Last change on this file since 985 was 985, checked in by Gregg Young, 17 years ago

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

  • 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 985 2008-03-01 01:37:14Z 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 29 Feb 08 GKY Use xfree where appropriate
54 29 Feb 08 GKY Refactor global command line variables to notebook.h
55
56***********************************************************************/
57
58#include <stdlib.h>
59#include <string.h>
60#include <share.h>
61#include <io.h>
62#include <process.h> // _beginthread
63
64#define INCL_DOS
65#define INCL_WIN
66#define INCL_DOSERRORS
67#define INCL_GPI
68#define INCL_LONGLONG
69
70#include "fm3dlg.h"
71#include "fm3str.h"
72#include "pathutil.h" // BldFullPathName
73#include "filldir.h" // EmptyCnr...
74#include "makelist.h" // AddToFileList...
75#include "errutil.h" // Dos_Error...
76#include "strutil.h" // GetPString
77#include "tmrsvcs.h" // IsITimerExpired
78#include "comp.h"
79#include "fm3dll.h"
80#include "notebook.h" // External compare/dircompare
81
82typedef struct
83{
84 CHAR filename[CCHMAXPATH];
85 CHAR dirname[CCHMAXPATH];
86 BOOL recurse;
87}
88SNAPSTUFF;
89
90static PSZ pszSrcFile = __FILE__;
91
92//=== SnapShot() Write directory tree to file and recurse if requested ===
93
94static VOID SnapShot(char *path, FILE *fp, BOOL recurse)
95{
96 PFILEFINDBUF4L pffb;
97 char *mask, *enddir;
98 HDIR hdir = HDIR_CREATE;
99 ULONG ulFindCnt;
100
101 // 13 Aug 07 SHL fimxe to use FileToGet
102 pffb = xmalloc(sizeof(FILEFINDBUF4L), pszSrcFile, __LINE__);
103 if (pffb) {
104 mask = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
105 if (mask) {
106 BldFullPathName(mask, path, "*");
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 xfree(mask);
146 }
147 xfree(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 xfree(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 xfree(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 xfree(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 xfree(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 xfree(pciDa);
819 xfree(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 xfree(pciSa);
846 xfree(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 xfree(pciSa);
1290 xfree(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 xfree(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 xfree(maskstr);
1399 xfree(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 xfree(filesl); // Free header - have already freed elements
1981 filesl = NULL;
1982 xfree(filesr);
1983 filesr = NULL;
1984
1985 // Say inserting
1986 WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
1987
1988 // Insert left side
1989 memset(&ri, 0, sizeof(RECORDINSERT));
1990 ri.cb = sizeof(RECORDINSERT);
1991 ri.pRecordOrder = (PRECORDCORE)CMA_END;
1992 ri.pRecordParent = (PRECORDCORE)NULL;
1993 ri.zOrder = (ULONG)CMA_TOP;
1994 ri.cRecordsInsert = recsNeeded;
1995 ri.fInvalidateRecord = FALSE;
1996
1997 if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
1998 MPFROMP(pcilFirst), MPFROMP(&ri))) {
1999 Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
2000 FreeCnrItemList(hwndLeft, pcilFirst);
2001 cmp->cmp->totalleft = 0;
2002 }
2003
2004 // Insert right side
2005 memset(&ri, 0, sizeof(RECORDINSERT));
2006 ri.cb = sizeof(RECORDINSERT);
2007 ri.pRecordOrder = (PRECORDCORE)CMA_END;
2008 ri.pRecordParent = (PRECORDCORE)NULL;
2009 ri.zOrder = (ULONG)CMA_TOP;
2010 ri.cRecordsInsert = recsNeeded;
2011 ri.fInvalidateRecord = FALSE;
2012
2013 if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
2014 MPFROMP(pcirFirst), MPFROMP(&ri))) {
2015 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
2016 RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
2017 FreeCnrItemList(hwndRight, pcirFirst);
2018 cmp->cmp->totalright = 0;
2019 }
2020
2021 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread filled");
2022
2023 } // if recsNeeded
2024
2025 Deselect(hwndLeft);
2026 Deselect(hwndRight);
2027
2028 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread deselected");
2029
2030 // Request window update
2031 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID))
2032 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
2033 notified = TRUE;
2034
2035 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread FILLED posted");
2036
2037 if (filesl)
2038 FreeList((CHAR **)filesl); // Must have failed to create container
2039 if (filesr)
2040 FreeList((CHAR **)filesr);
2041
2042 WinDestroyMsgQueue(hmq);
2043 } // if have queue
2044 if (!notified)
2045 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
2046 DecrThreadUsage();
2047 WinTerminate(hab);
2048 }
2049 xfree(cmp);
2050 DosPostEventSem(CompactSem);
2051
2052 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread exit");
2053}
2054
2055// fixme to be gone - use variable?
2056#define hwndLeft (WinWindowFromID(hwnd,COMP_LEFTDIR))
2057#define hwndRight (WinWindowFromID(hwnd,COMP_RIGHTDIR))
2058
2059//=== CompareDlgProc() Compare directories dialog procedure ===
2060
2061MRESULT EXPENTRY CompareDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
2062{
2063 COMPARE *cmp;
2064 BOOL temp;
2065 CHAR s[81];
2066
2067 static HPOINTER hptr;
2068
2069 switch (msg) {
2070 case WM_INITDLG:
2071 cmp = (COMPARE *)mp2;
2072 if (!cmp) {
2073 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2074 WinDismissDlg(hwnd, 0);
2075 }
2076 else {
2077 if (!hptr)
2078 hptr = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, COMPARE_ICON);
2079 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptr), MPVOID);
2080 cmp->hwnd = hwnd;
2081 WinSetWindowPtr(hwnd, QWL_USER, (PVOID)cmp);
2082 {
2083 SWP swp;
2084 ULONG size = sizeof(SWP);
2085
2086 PrfQueryProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp, &size);
2087 WinSetWindowPos(hwnd,
2088 HWND_TOP,
2089 swp.x,
2090 swp.y,
2091 swp.cx,
2092 swp.cy,
2093 swp.fl);
2094 }
2095 SetCnrCols(hwndLeft, TRUE);
2096 SetCnrCols(hwndRight, TRUE);
2097 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2098 WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2099 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
2100 {
2101 USHORT ids[] = { COMP_LEFTDIR, COMP_RIGHTDIR, COMP_TOTALLEFT,
2102 COMP_TOTALRIGHT, COMP_SELLEFT, COMP_SELRIGHT,
2103 0
2104 };
2105 UINT x;
2106 for (x = 0; ids[x]; x++) {
2107 SetPresParams(WinWindowFromID(hwnd, ids[x]),
2108 &RGBGREY,
2109 &RGBBLACK, &RGBBLACK, GetPString(IDS_8HELVTEXT));
2110 }
2111 }
2112 WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER, 500);
2113 }
2114 break;
2115
2116 case UM_STRETCH:
2117 {
2118 SWP swp, swpC;
2119 LONG titl, szbx, szby, sz;
2120 HWND hwndActive;
2121
2122 WinQueryWindowPos(hwnd, &swp);
2123 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
2124 hwndActive = WinQueryFocus(HWND_DESKTOP);
2125 szbx = SysVal(SV_CXSIZEBORDER);
2126 szby = SysVal(SV_CYSIZEBORDER);
2127 titl = SysVal(SV_CYTITLEBAR);
2128 titl += 26;
2129 swp.cx -= (szbx * 2);
2130 sz = (swp.cx / 8);
2131 WinQueryWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), &swpC);
2132 WinSetWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), HWND_TOP,
2133 szbx + 6,
2134 swpC.y,
2135 (swp.cx / 2) - (szbx + 6),
2136 ((swp.cy - swpC.y) - titl) - szby,
2137 SWP_MOVE | SWP_SIZE);
2138 WinSetWindowPos(WinWindowFromID(hwnd, COMP_RIGHTDIR), HWND_TOP,
2139 (swp.cx / 2) + (szbx + 6),
2140 swpC.y,
2141 (swp.cx / 2) - (szbx + 6),
2142 ((swp.cy - swpC.y) - titl) - szby,
2143 SWP_MOVE | SWP_SIZE);
2144 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFTHDR), HWND_TOP,
2145 szbx + 6,
2146 ((swp.cy - titl) - szby) + 4,
2147 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2148 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFT), HWND_TOP,
2149 sz + (szbx + 6),
2150 ((swp.cy - titl) - szby) + 4,
2151 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2152 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFTHDR), HWND_TOP,
2153 (sz * 2) + (szbx + 6),
2154 ((swp.cy - titl) - szby) + 4,
2155 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2156 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFT), HWND_TOP,
2157 (sz * 3) + (szbx + 6),
2158 ((swp.cy - titl) - szby) + 4,
2159 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2160 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHTHDR), HWND_TOP,
2161 (sz * 4) + (szbx + 6),
2162 ((swp.cy - titl) - szby) + 4,
2163 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2164 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHT), HWND_TOP,
2165 (sz * 5) + (szbx + 6),
2166 ((swp.cy - titl) - szby) + 4,
2167 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2168 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHTHDR), HWND_TOP,
2169 (sz * 6) + (szbx + 6),
2170 ((swp.cy - titl) - szby) + 4,
2171 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2172 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHT), HWND_TOP,
2173 (sz * 7) + (szbx + 6),
2174 ((swp.cy - titl) - szby) + 4,
2175 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
2176 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALLEFT),
2177 (HPS)0, FALSE, FALSE);
2178 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELLEFT),
2179 (HPS)0, FALSE, FALSE);
2180 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALRIGHT),
2181 (HPS)0, FALSE, FALSE);
2182 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELRIGHT),
2183 (HPS)0, FALSE, FALSE);
2184 PaintRecessedWindow(hwndLeft, (HPS)0,
2185 (hwndActive == hwndLeft), TRUE);
2186 PaintRecessedWindow(hwndRight, (HPS)0,
2187 (hwndActive == hwndRight), TRUE);
2188 }
2189 }
2190 return 0;
2191
2192 case WM_ADJUSTWINDOWPOS:
2193 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
2194 break;
2195
2196 case UM_SETUP:
2197 {
2198 CNRINFO cnri;
2199 BOOL tempsubj;
2200
2201 cmp = INSTDATA(hwnd);
2202 if (!cmp)
2203 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2204 else {
2205 cmp->dcd.size = sizeof(DIRCNRDATA);
2206 cmp->dcd.type = DIR_FRAME;
2207 cmp->dcd.hwndFrame = hwnd;
2208 cmp->dcd.hwndClient = hwnd;
2209 cmp->dcd.mask.attrFile = (FILE_DIRECTORY | FILE_ARCHIVED |
2210 FILE_READONLY | FILE_SYSTEM | FILE_HIDDEN);
2211 LoadDetailsSwitches("DirCmp", &cmp->dcd);
2212 cmp->dcd.detailslongname = FALSE;
2213 cmp->dcd.detailsicon = FALSE; // TRUE;
2214 }
2215 memset(&cnri, 0, sizeof(CNRINFO));
2216 cnri.cb = sizeof(CNRINFO);
2217 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_QUERYCNRINFO,
2218 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2219 cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
2220 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 68;
2221 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2222 MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
2223 memset(&cnri, 0, sizeof(CNRINFO));
2224 cnri.cb = sizeof(CNRINFO);
2225 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_QUERYCNRINFO,
2226 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2227 cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
2228 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 54;
2229 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2230 MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
2231 AdjustCnrColRO(hwndLeft, GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
2232 AdjustCnrColRO(hwndLeft, GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
2233 AdjustCnrColRO(hwndRight, GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
2234 AdjustCnrColRO(hwndRight, GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
2235 AdjustCnrColsForPref(hwndLeft, cmp->leftdir, &cmp->dcd, TRUE);
2236 tempsubj = cmp->dcd.detailssubject;
2237 cmp->dcd.detailssubject = FALSE;
2238 AdjustCnrColsForPref(hwndRight, cmp->rightdir, &cmp->dcd, TRUE);
2239 if (*cmp->rightlist) {
2240 AdjustCnrColVis(hwndRight, GetPString(IDS_LADATECOLTEXT), FALSE,
2241 FALSE);
2242 AdjustCnrColVis(hwndRight, GetPString(IDS_LATIMECOLTEXT), FALSE,
2243 FALSE);
2244 AdjustCnrColVis(hwndRight, GetPString(IDS_CRDATECOLTEXT), FALSE,
2245 FALSE);
2246 AdjustCnrColVis(hwndRight, GetPString(IDS_CRTIMECOLTEXT), FALSE,
2247 FALSE);
2248 }
2249 cmp->dcd.detailssubject = tempsubj;
2250 }
2251 return 0;
2252
2253 case WM_DRAWITEM:
2254 if (mp2) {
2255 POWNERITEM pown = (POWNERITEM)mp2;
2256 PCNRDRAWITEMINFO pcown;
2257 PCNRITEM pci;
2258
2259 pcown = (PCNRDRAWITEMINFO)pown->hItem;
2260 if (pcown) {
2261 pci = (PCNRITEM)pcown->pRecord;
2262 // 01 Aug 07 SHL if field null or blank, we draw
2263 // fixme to document why - probably to optimize and bypass draw?
2264 if (pci && (INT)pci != -1 && !*pci->pszFileName)
2265 return MRFROMLONG(TRUE);
2266 }
2267 }
2268 return 0;
2269
2270 case UM_CONTAINERHWND:
2271 // Building list
2272 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDBLDLISTTEXT));
2273 return 0;
2274
2275 case UM_CONTAINERDIR:
2276 // Filling container
2277 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDFILLCNRTEXT));
2278 return 0;
2279
2280 case WM_TIMER:
2281 // Show current totals
2282 cmp = INSTDATA(hwnd);
2283 if (!cmp) {
2284 Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL");
2285 WinDismissDlg(hwnd, 0);
2286 }
2287 else {
2288 if (cmp->uOldTotalLeft != cmp->totalleft) {
2289 cmp->uOldTotalLeft = cmp->totalleft;
2290 sprintf(s, " %d", cmp->totalleft);
2291 WinSetDlgItemText(hwnd, COMP_TOTALLEFT, s);
2292 }
2293 if (cmp->uOldTotalRight != cmp->totalright) {
2294 cmp->uOldTotalRight = cmp->totalright;
2295 sprintf(s, " %d", cmp->totalright);
2296 WinSetDlgItemText(hwnd, COMP_TOTALRIGHT, s);
2297 }
2298 if (cmp->uOldSelLeft != cmp->selleft) {
2299 cmp->uOldSelLeft = cmp->selleft;
2300 sprintf(s, " %d", cmp->selleft);
2301 WinSetDlgItemText(hwnd, COMP_SELLEFT, s);
2302 }
2303 if (cmp->uOldSelRight != cmp->selright) {
2304 cmp->uOldSelRight = cmp->selright;
2305 sprintf(s, " %d", cmp->selright);
2306 WinSetDlgItemText(hwnd, COMP_SELRIGHT, s);
2307 }
2308 }
2309 break;
2310
2311 case UM_CONTAINER_FILLED:
2312 cmp = INSTDATA(hwnd);
2313 if (!cmp) {
2314 Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL");
2315 WinDismissDlg(hwnd, 0);
2316 }
2317 else {
2318 cmp->filling = FALSE;
2319 WinEnableWindow(hwndLeft, TRUE);
2320 WinEnableWindow(hwndRight, TRUE);
2321 WinEnableWindowUpdate(hwndLeft, TRUE);
2322 WinEnableWindowUpdate(hwndRight, TRUE);
2323 WinPostMsg(hwnd, WM_TIMER, MPFROMLONG(ID_TIMER), 0); // Force update
2324 // 12 Jan 08 SHL fixme to have SetButtonEnables(COMPARE* pcmp, BOOL fEnable)
2325 // to replace duplicated code here and elsewhere
2326 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), TRUE);
2327 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), TRUE);
2328 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), TRUE);
2329 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), TRUE);
2330 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), TRUE);
2331 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), TRUE);
2332 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), TRUE);
2333 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), TRUE);
2334 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), TRUE);
2335 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), TRUE);
2336 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), TRUE);
2337 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), TRUE);
2338 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), TRUE);
2339 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), TRUE);
2340 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), TRUE);
2341 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), TRUE);
2342 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), TRUE);
2343 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), TRUE);
2344 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), TRUE);
2345 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), TRUE);
2346 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), TRUE);
2347 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), TRUE);
2348 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), TRUE);
2349 if (!*cmp->rightlist) {
2350 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), TRUE);
2351 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), TRUE);
2352 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), TRUE);
2353 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), TRUE);
2354 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), TRUE);
2355 }
2356 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), TRUE);
2357 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), TRUE);
2358 if (*cmp->dcd.mask.szMask) {
2359 sprintf(s,
2360 GetPString(IDS_COMPREADYFILTEREDTEXT),
2361 cmp->dcd.mask.szMask);
2362 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2363 }
2364 else
2365 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
2366 }
2367 break;
2368
2369 case WM_INITMENU:
2370 cmp = INSTDATA(hwnd);
2371 if (cmp) {
2372 switch (SHORT1FROMMP(mp1)) {
2373 case IDM_COMMANDSMENU:
2374 SetupCommandMenu(cmp->dcd.hwndLastMenu, hwnd);
2375 break;
2376 }
2377 }
2378 break;
2379
2380 case WM_MENUEND:
2381 cmp = INSTDATA(hwnd);
2382 if (cmp) {
2383 if ((HWND)mp2 == cmp->dcd.hwndLastMenu) {
2384 MarkAll(hwndLeft, TRUE, FALSE, TRUE);
2385 MarkAll(hwndRight, TRUE, FALSE, TRUE);
2386 WinDestroyWindow(cmp->dcd.hwndLastMenu);
2387 cmp->dcd.hwndLastMenu = (HWND)0;
2388 }
2389 }
2390 break;
2391
2392 case WM_CONTROL:
2393 switch (SHORT1FROMMP(mp1)) {
2394 case COMP_INCLUDESUBDIRS:
2395 switch (SHORT2FROMMP(mp1)) {
2396 case BN_CLICKED:
2397 cmp = INSTDATA(hwnd);
2398 if (cmp)
2399 *cmp->rightlist = 0;
2400 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2401 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2402 break;
2403 }
2404 break;
2405 case COMP_HIDENOTSELECTED:
2406 switch (SHORT2FROMMP(mp1)) {
2407 case BN_CLICKED:
2408 WinSendMsg(hwnd, UM_HIDENOTSELECTED, MPVOID, MPVOID);
2409 break;
2410 }
2411 break;
2412
2413 case COMP_LEFTDIR:
2414 case COMP_RIGHTDIR:
2415 switch (SHORT2FROMMP(mp1)) {
2416 case CN_KILLFOCUS:
2417 PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
2418 (HPS)0, FALSE, TRUE);
2419 break;
2420
2421 case CN_SETFOCUS:
2422 PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
2423 (HPS)0, TRUE, TRUE);
2424 break;
2425
2426 case CN_ENTER:
2427 if (mp2) {
2428
2429 PCNRITEM pci = (PCNRITEM)((PNOTIFYRECORDENTER)mp2)->pRecord;
2430 HWND hwndCnr = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
2431
2432 SetShiftState();
2433 if (pci) {
2434 if (pci->rc.flRecordAttr & CRA_INUSE || !pci || !*pci->pszFileName)
2435 break;
2436 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
2437 MPFROM2SHORT(TRUE, CRA_INUSE));
2438 if (pci->attrFile & FILE_DIRECTORY) {
2439 if ((shiftstate & (KC_CTRL | KC_SHIFT)) == (KC_CTRL | KC_SHIFT))
2440 OpenObject(pci->pszFileName, Settings, hwnd);
2441 else
2442 OpenObject(pci->pszFileName, Default, hwnd);
2443 }
2444 else
2445 DefaultViewKeys(hwnd, hwnd, HWND_DESKTOP, NULL,
2446 pci->pszFileName);
2447 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS,
2448 MPFROMP(pci),
2449 MPFROM2SHORT(FALSE,
2450 CRA_INUSE | (fUnHilite ? CRA_SELECTED : 0)));
2451 }
2452 }
2453 break;
2454
2455 case CN_CONTEXTMENU:
2456 cmp = INSTDATA(hwnd);
2457 if (cmp) {
2458 PCNRITEM pci = (PCNRITEM)mp2;
2459 USHORT id = COMP_CNRMENU;
2460
2461 if (cmp->dcd.hwndLastMenu)
2462 WinDestroyWindow(cmp->dcd.hwndLastMenu);
2463 cmp->dcd.hwndLastMenu = (HWND)0;
2464 cmp->hwndCalling = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
2465 if (pci) {
2466 if (!pci || !*pci->pszFileName || *cmp->rightlist)
2467 break;
2468 id = COMP_MENU;
2469 WinSendMsg(cmp->hwndCalling, CM_SETRECORDEMPHASIS,
2470 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
2471 }
2472 cmp->dcd.hwndLastMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
2473 if (cmp->dcd.hwndLastMenu) {
2474 if (id == COMP_CNRMENU) {
2475 if (SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
2476 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2477 MPFROM2SHORT(IDM_SHOWSUBJECT, FALSE), MPVOID);
2478 SetDetailsSwitches(cmp->dcd.hwndLastMenu, &cmp->dcd);
2479 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR)
2480 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2481 MPFROM2SHORT(IDM_LOADLISTFILE, 0), MPVOID);
2482 else if (*cmp->rightlist)
2483 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
2484 MPFROM2SHORT(IDM_SAVELISTFILE, 0), MPVOID);
2485 }
2486 PopupMenu(hwnd, hwnd, cmp->dcd.hwndLastMenu);
2487 }
2488 }
2489 break;
2490
2491 case CN_INITDRAG:
2492 cmp = INSTDATA(hwnd);
2493 if (*cmp->rightlist && SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
2494 break;
2495 DoFileDrag(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
2496 (HWND)0, mp2, NULL, NULL, TRUE);
2497 break;
2498
2499 case CN_BEGINEDIT:
2500 case CN_REALLOCPSZ:
2501 // fixme to be gone - field edits not allowed?
2502 Runtime_Error(pszSrcFile, __LINE__,
2503 "CN_BEGINEDIT/CN_REALLOCPSZ unexpected");
2504 break;
2505
2506 case CN_EMPHASIS:
2507 {
2508 PNOTIFYRECORDEMPHASIS pnre = mp2;
2509 BOOL fSelected;
2510 if (pnre->fEmphasisMask & CRA_SELECTED) {
2511 // Select toggled
2512 PCNRITEM pci = (PCNRITEM)pnre->pRecord;
2513 if (pci) {
2514 if (!*pci->pszFileName) {
2515 // Slot empty
2516 // 17 Jan 08 SHL fixme to know how can get here
2517 // 12 Jan 08 SHL fixme to know if select counts need update?
2518 if (pci->rc.flRecordAttr & CRA_SELECTED)
2519 WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1),
2520 CM_SETRECORDEMPHASIS,
2521 MPFROMP(pci),
2522 MPFROM2SHORT(FALSE, CRA_SELECTED));
2523 }
2524 else {
2525 BOOL fUpdateHideButton = FALSE;
2526 cmp = INSTDATA(hwnd);
2527 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR) {
2528 fSelected = pci->rc.flRecordAttr & CRA_SELECTED;
2529 cmp->selleft += fSelected ? 1 : -1;
2530 if (!fSelected)
2531 fUpdateHideButton = TRUE;
2532 }
2533 else if (SHORT1FROMMP(mp1) == COMP_RIGHTDIR) {
2534 fSelected = pci->rc.flRecordAttr & CRA_SELECTED;
2535 cmp->selright += fSelected ? 1 : -1;
2536 if (!fSelected)
2537 fUpdateHideButton = TRUE;
2538 }
2539 else {
2540 Runtime_Error(pszSrcFile, __LINE__,
2541 "mp1 %u unexpected", SHORT1FROMMP(mp1));
2542 }
2543 if (fUpdateHideButton) {
2544 USHORT state = WinQueryButtonCheckstate(hwnd,COMP_HIDENOTSELECTED);
2545 if (state == 1) {
2546 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 2);
2547 }
2548 }
2549 }
2550 }
2551 }
2552 }
2553 break;
2554
2555 case CN_SCROLL:
2556 cmp = INSTDATA(hwnd);
2557 if (!cmp->forcescroll) {
2558
2559 PNOTIFYSCROLL pns = mp2;
2560
2561 if (pns->fScroll & CMA_VERTICAL) {
2562 cmp->forcescroll = TRUE;
2563 // Scroll other window to match
2564 WinSendDlgItemMsg(hwnd,
2565 SHORT1FROMMP(mp1) == COMP_LEFTDIR ?
2566 COMP_RIGHTDIR : COMP_LEFTDIR,
2567 CM_SCROLLWINDOW,
2568 MPFROMSHORT(CMA_VERTICAL),
2569 MPFROMLONG(pns->lScrollInc));
2570 cmp->forcescroll = FALSE;
2571 }
2572 }
2573 break;
2574 } // switch COMP_LEFTDIR mp1
2575 break; // COMP_LEFTDIR / COMP_RIGHTDIR
2576 } // switch WM_CONTROL mp1
2577 return 0; // WM_CONTROL
2578
2579 case UM_SETDIR:
2580 cmp = INSTDATA(hwnd);
2581 if (cmp) {
2582 COMPARE *forthread;
2583 CNRINFO cnri;
2584 cmp->includesubdirs = WinQueryButtonCheckstate(hwnd,
2585 COMP_INCLUDESUBDIRS);
2586 memset(&cnri, 0, sizeof(CNRINFO));
2587 cnri.cb = sizeof(CNRINFO);
2588 cnri.pszCnrTitle = cmp->leftdir;
2589 cnri.flWindowAttr = CV_DETAIL | CV_MINI |
2590 CA_CONTAINERTITLE | CA_TITLESEPARATOR |
2591 CA_DETAILSVIEWTITLES | CA_OWNERDRAW;
2592 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2593 MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
2594 cnri.pszCnrTitle = cmp->rightdir;
2595 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
2596 MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
2597 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 0);
2598 cmp->filling = TRUE;
2599 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2600 if (!forthread)
2601 WinDismissDlg(hwnd, 0);
2602 else {
2603 *forthread = *cmp;
2604 forthread->cmp = cmp;
2605 if (_beginthread(FillCnrsThread, NULL, 122880, (PVOID)forthread) ==
2606 -1) {
2607 Runtime_Error(pszSrcFile, __LINE__,
2608 GetPString(IDS_COULDNTSTARTTHREADTEXT));
2609 WinDismissDlg(hwnd, 0);
2610 xfree(forthread);
2611 }
2612 else {
2613 WinEnableWindowUpdate(hwndLeft, FALSE);
2614 WinEnableWindowUpdate(hwndRight, FALSE);
2615 cmp->selleft = cmp->selright = 0;
2616 WinSetDlgItemText(hwnd, COMP_NOTE,
2617 GetPString(IDS_COMPHOLDREADDISKTEXT));
2618 WinEnableWindow(hwndRight, FALSE);
2619 WinEnableWindow(hwndLeft, FALSE);
2620 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
2621 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
2622 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
2623 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
2624 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
2625 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
2626 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
2627 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
2628 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
2629 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
2630 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
2631 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
2632 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
2633 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
2634 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), FALSE);
2635 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
2636 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
2637 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
2638 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
2639 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
2640 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
2641 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
2642 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
2643 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), FALSE);
2644 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), FALSE);
2645 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
2646 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
2647 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
2648 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), FALSE);
2649 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), FALSE);
2650 }
2651 }
2652 }
2653 return 0;
2654
2655 case UM_FILTER:
2656 cmp = INSTDATA(hwnd);
2657 if (cmp) {
2658 if (mp1) {
2659 DosEnterCritSec();
2660 SetMask((CHAR *)mp1, &cmp->dcd.mask);
2661 DosExitCritSec();
2662 }
2663 WinSetDlgItemText(hwnd, COMP_NOTE,
2664 GetPString(IDS_COMPHOLDFILTERINGTEXT));
2665 // cmp->dcd.suspendview = 1; // 12 Jan 08 SHL appears not to be used here
2666 priority_idle(); // Don't hog resources
2667 WinSendMsg(hwndLeft, CM_FILTER, MPFROMP(Filter),
2668 MPFROMP(&cmp->dcd.mask));
2669 WinSendMsg(hwndRight, CM_FILTER, MPFROMP(Filter),
2670 MPFROMP(&cmp->dcd.mask));
2671 priority_normal();
2672 // cmp->dcd.suspendview = 0; // 12 Jan 08 SHL appears not to be used here
2673 if (*cmp->dcd.mask.szMask) {
2674 sprintf(s,
2675 GetPString(IDS_COMPREADYFILTEREDTEXT),
2676 cmp->dcd.mask.szMask);
2677 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2678 }
2679 else
2680 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
2681 }
2682 return 0;
2683
2684 case UM_HIDENOTSELECTED:
2685 cmp = INSTDATA(hwnd);
2686 if (cmp) {
2687 USHORT wasHidden = WinQueryButtonCheckstate(hwnd,
2688 COMP_HIDENOTSELECTED);
2689
2690 // cmp->dcd.suspendview = 1; // 12 Jan 08 SHL appears not to be used here
2691 if (wasHidden != 1) {
2692 // Hide if not selected on both sides
2693 BOOL needRefresh = FALSE;
2694 HWND hwndl = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
2695 HWND hwndr = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
2696 PCNRITEM pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPVOID,
2697 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2698 PCNRITEM pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPVOID,
2699 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
2700
2701 while (pcil && (INT)pcil != -1 && pcir && (INT)pcir != -1) {
2702 if (~pcil->rc.flRecordAttr & CRA_SELECTED &&
2703 ~pcir->rc.flRecordAttr & CRA_SELECTED) {
2704 // 17 Jan 08 SHL fixme to optimize refresh
2705 pcil->rc.flRecordAttr |= CRA_FILTERED;
2706 pcir->rc.flRecordAttr |= CRA_FILTERED;
2707 needRefresh = TRUE;
2708 }
2709 pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPFROMP(pcil),
2710 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2711 pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPFROMP(pcir),
2712 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2713 } // while
2714 if (needRefresh) {
2715 WinSendMsg(hwndl, CM_INVALIDATERECORD,
2716 MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
2717 WinSendMsg(hwndr, CM_INVALIDATERECORD,
2718 MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
2719 }
2720 }
2721 else {
2722 // Unhide
2723 WinSendMsg(hwndLeft, CM_FILTER, MPFROMP(Filter),
2724 MPFROMP(&cmp->dcd.mask));
2725 WinSendMsg(hwndRight, CM_FILTER, MPFROMP(Filter),
2726 MPFROMP(&cmp->dcd.mask));
2727 }
2728 // cmp->dcd.suspendview = 0; // 12 Jan 08 SHL appears not to be used here
2729 if (*cmp->dcd.mask.szMask) {
2730 sprintf(s,
2731 GetPString(IDS_COMPREADYFILTEREDTEXT),
2732 cmp->dcd.mask.szMask);
2733 WinSetDlgItemText(hwnd, COMP_NOTE, s);
2734 }
2735 else
2736 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
2737 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, wasHidden != 1 ? 1 : 0);
2738 }
2739 return 0;
2740
2741 case WM_COMMAND:
2742 switch (SHORT1FROMMP(mp1)) {
2743 case IDM_COMPARE:
2744 cmp = INSTDATA(hwnd);
2745 if (cmp) {
2746 PCNRITEM pci;
2747 CHAR ofile[CCHMAXPATH];
2748
2749 pci = (PCNRITEM)WinSendMsg(cmp->hwndCalling,
2750 CM_QUERYRECORDEMPHASIS,
2751 MPFROMLONG(CMA_FIRST),
2752 MPFROMSHORT(CRA_CURSORED));
2753 // 01 Aug 07 SHL
2754 if (pci && *pci->pszFileName) {
2755 if (cmp->hwndCalling == hwndLeft)
2756 strcpy(ofile, cmp->rightdir);
2757 else
2758 strcpy(ofile, cmp->leftdir);
2759 if (ofile[strlen(ofile) - 1] != '\\')
2760 strcat(ofile, "\\");
2761 strcat(ofile, pci->pszDisplayName);
2762 if (*compare) {
2763 CHAR *fakelist[3];
2764 fakelist[0] = pci->pszFileName;
2765 fakelist[1] = ofile;
2766 fakelist[2] = NULL;
2767 ExecOnList(hwnd, compare,
2768 WINDOWED | SEPARATEKEEP, NULL, fakelist, NULL,
2769 pszSrcFile, __LINE__);
2770 }
2771 else {
2772 FCOMPARE fc;
2773 memset(&fc, 0, sizeof(fc));
2774 fc.size = sizeof(fc);
2775 fc.hwndParent = hwnd;
2776 strcpy(fc.file1, pci->pszFileName);
2777 strcpy(fc.file2, ofile);
2778 WinDlgBox(HWND_DESKTOP, hwnd,
2779 CFileDlgProc, FM3ModHandle, FCMP_FRAME, (PVOID)&fc);
2780 }
2781 }
2782 }
2783 break;
2784
2785 case COMP_FILTER:
2786 case IDM_FILTER:
2787 cmp = INSTDATA(hwnd);
2788 if (cmp) {
2789 BOOL empty = FALSE;
2790 PCNRITEM pci;
2791 CHAR *p;
2792 BOOL temp;
2793
2794 if (!*cmp->dcd.mask.szMask) {
2795 empty = TRUE;
2796 temp = fSelectedAlways;
2797 fSelectedAlways = TRUE;
2798 pci = (PCNRITEM)CurrentRecord(hwnd);
2799 fSelectedAlways = temp;
2800 // 01 Aug 07 SHL
2801 if (pci && ~pci->attrFile & FILE_DIRECTORY) {
2802 p = strrchr(pci->pszFileName, '\\');
2803 if (p) {
2804 p++;
2805 strcpy(cmp->dcd.mask.szMask, p);
2806 }
2807 }
2808 }
2809 cmp->dcd.mask.fNoAttribs = TRUE;
2810 cmp->dcd.mask.attrFile = ALLATTRS;
2811 cmp->dcd.mask.antiattr = 0;
2812 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
2813 FM3ModHandle, MSK_FRAME, MPFROMP(&cmp->dcd.mask))) {
2814 cmp->dcd.mask.attrFile = ALLATTRS;
2815 cmp->dcd.mask.antiattr = 0;
2816 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2817 }
2818 else if (empty) {
2819 *cmp->dcd.mask.szMask = 0;
2820 cmp->dcd.mask.attrFile = ALLATTRS;
2821 cmp->dcd.mask.antiattr = 0;
2822 }
2823 }
2824 break;
2825
2826 case IDM_SHOWSUBJECT:
2827 case IDM_SHOWEAS:
2828 case IDM_SHOWSIZE:
2829 case IDM_SHOWLWDATE:
2830 case IDM_SHOWLWTIME:
2831 case IDM_SHOWLADATE:
2832 case IDM_SHOWLATIME:
2833 case IDM_SHOWCRDATE:
2834 case IDM_SHOWCRTIME:
2835 case IDM_SHOWATTR:
2836 cmp = INSTDATA(hwnd);
2837 if (cmp) {
2838 DIRCNRDATA dcd1;
2839 BOOL tempsubj;
2840
2841 dcd1 = cmp->dcd;
2842 AdjustDetailsSwitches(hwndLeft,
2843 (HWND)0, SHORT1FROMMP(mp1),
2844 cmp->leftdir, "DirCmp", &cmp->dcd, TRUE);
2845 tempsubj = cmp->dcd.detailssubject;
2846 cmp->dcd = dcd1;
2847 cmp->dcd.detailssubject = FALSE;
2848 AdjustDetailsSwitches(hwndRight,
2849 cmp->dcd.hwndLastMenu, SHORT1FROMMP(mp1),
2850 cmp->rightdir, "DirCmp", &cmp->dcd, TRUE);
2851 cmp->dcd.detailssubject = tempsubj;
2852 }
2853 break;
2854
2855 case IDM_LOADLISTFILE:
2856 cmp = INSTDATA(hwnd);
2857 if (cmp) {
2858 CHAR fullname[CCHMAXPATH];
2859
2860 strcpy(fullname, "*.PMD");
2861 if (insert_filename(HWND_DESKTOP, fullname, TRUE, FALSE) &&
2862 *fullname && !strchr(fullname, '*') && !strchr(fullname, '?')) {
2863 strcpy(cmp->rightlist, fullname);
2864 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2865 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2866 }
2867 }
2868 break;
2869
2870 case IDM_SAVELISTFILE:
2871 cmp = INSTDATA(hwnd);
2872 if (cmp) {
2873 SNAPSTUFF *sf;
2874 CHAR fullname[CCHMAXPATH];
2875
2876 strcpy(fullname, "*.PMD");
2877 if (export_filename(HWND_DESKTOP, fullname, 1) && *fullname &&
2878 !strchr(fullname, '*') && !strchr(fullname, '?')) {
2879 sf = xmallocz(sizeof(SNAPSTUFF), pszSrcFile, __LINE__);
2880 if (sf) {
2881 strcpy(sf->filename, fullname);
2882 if (hwndLeft == cmp->hwndCalling)
2883 strcpy(sf->dirname, cmp->leftdir);
2884 else
2885 strcpy(sf->dirname, cmp->rightdir);
2886 sf->recurse = cmp->includesubdirs;
2887 if (_beginthread(StartSnap, NULL, 65536, (PVOID)sf) == -1) {
2888 Runtime_Error(pszSrcFile, __LINE__,
2889 GetPString(IDS_COULDNTSTARTTHREADTEXT));
2890 xfree(sf);
2891 }
2892 }
2893 }
2894 }
2895 break;
2896
2897 case COMP_SETDIRS:
2898 cmp = INSTDATA(hwnd);
2899 if (cmp) {
2900 WALK2 wa;
2901 memset(&wa, 0, sizeof(wa));
2902 wa.size = sizeof(wa);
2903 strcpy(wa.szCurrentPath1, cmp->leftdir);
2904 strcpy(wa.szCurrentPath2, cmp->rightdir);
2905 if (WinDlgBox(HWND_DESKTOP,
2906 hwnd,
2907 WalkTwoCmpDlgProc,
2908 FM3ModHandle,
2909 WALK2_FRAME,
2910 MPFROMP(&wa)) &&
2911 !IsFile(wa.szCurrentPath1) &&
2912 !IsFile(wa.szCurrentPath2)) {
2913 strcpy(cmp->leftdir, wa.szCurrentPath1);
2914 strcpy(cmp->rightdir, wa.szCurrentPath2);
2915 *cmp->rightlist = 0;
2916 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2917 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2918 }
2919 }
2920 break;
2921
2922 case COMP_COPYLEFT:
2923 case COMP_MOVELEFT:
2924 case COMP_COPYRIGHT:
2925 case COMP_MOVERIGHT:
2926 case COMP_DELETELEFT:
2927 case COMP_DELETERIGHT:
2928 cmp = INSTDATA(hwnd);
2929 if (cmp) {
2930 COMPARE *forthread;
2931
2932 cmp->filling = TRUE;
2933 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2934 if (forthread) {
2935 *forthread = *cmp;
2936 forthread->cmp = cmp;
2937 forthread->action = SHORT1FROMMP(mp1);
2938 if (_beginthread(ActionCnrThread, NULL, 122880, (PVOID)forthread)
2939 == -1) {
2940 Runtime_Error(pszSrcFile, __LINE__,
2941 GetPString(IDS_COULDNTSTARTTHREADTEXT));
2942 xfree(forthread);
2943 }
2944 else {
2945 WinEnableWindowUpdate(hwndLeft, FALSE);
2946 WinEnableWindowUpdate(hwndRight, FALSE);
2947 switch (SHORT1FROMMP(mp1)) {
2948 case COMP_DELETELEFT:
2949 case COMP_DELETERIGHT:
2950 WinSetDlgItemText(hwnd, COMP_NOTE,
2951 GetPString(IDS_COMPHOLDDELETINGTEXT));
2952 break;
2953 case COMP_MOVELEFT:
2954 case COMP_MOVERIGHT:
2955 WinSetDlgItemText(hwnd, COMP_NOTE,
2956 GetPString(IDS_COMPHOLDMOVINGTEXT));
2957 break;
2958 case COMP_COPYLEFT:
2959 case COMP_COPYRIGHT:
2960 WinSetDlgItemText(hwnd, COMP_NOTE,
2961 GetPString(IDS_COMPHOLDCOPYINGTEXT));
2962 break;
2963 default:
2964 Runtime_Error(pszSrcFile, __LINE__, "mp1 %u unexpected", SHORT1FROMMP(mp1));
2965 }
2966 WinEnableWindow(hwndRight, FALSE);
2967 WinEnableWindow(hwndLeft, FALSE);
2968 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
2969 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
2970 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
2971 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
2972 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
2973 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
2974 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
2975 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
2976 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
2977 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
2978 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
2979 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
2980 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
2981 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
2982 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), FALSE);
2983 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
2984 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
2985 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
2986 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
2987 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
2988 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
2989 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
2990 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
2991 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), FALSE);
2992 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), FALSE);
2993 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
2994 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
2995 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
2996 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), FALSE);
2997 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), FALSE);
2998 }
2999 }
3000 }
3001 break;
3002
3003 case DID_OK:
3004 {
3005 SWP swp;
3006 ULONG size = sizeof(SWP);
3007
3008 WinQueryWindowPos(hwnd, &swp);
3009 PrfWriteProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp,
3010 size);
3011 }
3012 WinDismissDlg(hwnd, 0);
3013 break;
3014 case DID_CANCEL:
3015 {
3016 SWP swp;
3017 ULONG size = sizeof(SWP);
3018
3019 WinQueryWindowPos(hwnd, &swp);
3020 PrfWriteProfileData(fmprof, FM3Str, "CompDir.Position", (PVOID) &swp,
3021 size);
3022 }
3023 WinDismissDlg(hwnd, 1);
3024 break;
3025
3026 case IDM_HELP:
3027 if (hwndHelp)
3028 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
3029 MPFROM2SHORT(HELP_COMPARE, 0), MPFROMSHORT(HM_RESOURCEID));
3030 break;
3031
3032 case IDM_DESELECTALL:
3033 case IDM_SELECTNEWER:
3034 case IDM_SELECTOLDER:
3035 case IDM_SELECTBIGGER:
3036 case IDM_SELECTSMALLER:
3037 case IDM_DESELECTNEWER:
3038 case IDM_DESELECTOLDER:
3039 case IDM_DESELECTBIGGER:
3040 case IDM_DESELECTSMALLER:
3041 case IDM_DESELECTONE:
3042 case IDM_DESELECTBOTH:
3043 case IDM_SELECTBOTH:
3044 case IDM_SELECTONE:
3045 case IDM_SELECTSAMECONTENT:
3046 case IDM_SELECTIDENTICAL: // Name, size and time
3047 case IDM_SELECTSAME: // Name and size
3048 case IDM_INVERT:
3049 cmp = INSTDATA(hwnd);
3050 if (!cmp)
3051 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
3052 else {
3053 COMPARE *forthread;
3054
3055 cmp->filling = TRUE;
3056 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
3057 if (forthread) {
3058 *forthread = *cmp;
3059 forthread->cmp = cmp;
3060 forthread->action = SHORT1FROMMP(mp1);
3061 if (_beginthread(SelectCnrsThread, NULL, 65536, (PVOID)forthread)
3062 == -1) {
3063 Runtime_Error(pszSrcFile, __LINE__,
3064 GetPString(IDS_COULDNTSTARTTHREADTEXT));
3065 xfree(forthread);
3066 }
3067 else {
3068 WinEnableWindowUpdate(hwndLeft, FALSE);
3069 WinEnableWindowUpdate(hwndRight, FALSE);
3070 switch (SHORT1FROMMP(mp1)) {
3071 case IDM_DESELECTALL:
3072 case IDM_DESELECTNEWER:
3073 case IDM_DESELECTOLDER:
3074 case IDM_DESELECTBIGGER:
3075 case IDM_DESELECTSMALLER:
3076 case IDM_DESELECTONE:
3077 case IDM_DESELECTBOTH:
3078 WinSetDlgItemText(hwnd, COMP_NOTE,
3079 GetPString(IDS_COMPHOLDDESELTEXT));
3080 break;
3081 case IDM_INVERT:
3082 WinSetDlgItemText(hwnd, COMP_NOTE,
3083 GetPString(IDS_COMPHOLDINVERTTEXT));
3084 break;
3085 default:
3086 WinSetDlgItemText(hwnd, COMP_NOTE,
3087 GetPString(IDS_COMPHOLDSELTEXT));
3088 break;
3089 }
3090 WinEnableWindow(hwndRight, FALSE);
3091 WinEnableWindow(hwndLeft, FALSE);
3092 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
3093 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
3094 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
3095 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
3096 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
3097 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
3098 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
3099 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
3100 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
3101 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
3102 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
3103 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
3104 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
3105 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
3106 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), FALSE);
3107 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
3108 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), FALSE);
3109 WinEnableWindow(WinWindowFromID(hwnd, COMP_HIDENOTSELECTED), FALSE);
3110 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
3111 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
3112 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
3113 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
3114 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
3115 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
3116 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
3117 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), FALSE);
3118 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), FALSE);
3119 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
3120 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
3121 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
3122 }
3123 }
3124 }
3125 break;
3126
3127 case COMP_COLLECT:
3128 cmp = INSTDATA(hwnd);
3129 if (!cmp)
3130 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
3131 else {
3132 CHAR **listl;
3133 CHAR **listr = NULL;
3134 if (!Collector) {
3135 SWP swp;
3136 HWND hwndC;
3137 if (!fAutoTile &&
3138 !ParentIsDesktop(hwnd, cmp->hwndParent) &&
3139 !fExternalCollector &&
3140 !strcmp(realappname, FM3Str)) {
3141 GetNextWindowPos(cmp->hwndParent, &swp, NULL, NULL);
3142 }
3143 hwndC = StartCollector(fExternalCollector ||
3144 strcmp(realappname, FM3Str) ?
3145 HWND_DESKTOP :
3146 cmp->hwndParent,
3147 4);
3148 if (hwndC) {
3149 if (!fAutoTile &&
3150 !ParentIsDesktop(hwnd, cmp->hwndParent) &&
3151 !fExternalCollector &&
3152 !strcmp(realappname, FM3Str)) {
3153 WinSetWindowPos(hwndC, HWND_TOP,
3154 swp.x, swp.y, swp.cx, swp.cy,
3155 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
3156 }
3157 else if (!ParentIsDesktop(hwnd, cmp->hwndParent) &&
3158 fAutoTile &&
3159 !strcmp(realappname, FM3Str)) {
3160 TileChildren(cmp->hwndParent, TRUE);
3161 }
3162 DosSleep(1); // 12 Jan 08 SHL Let screen update
3163 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(COMP_COLLECT, 0), MPVOID);
3164 break;
3165 }
3166 }
3167 else
3168 StartCollector(cmp->hwndParent, 4);
3169
3170 temp = fSelectedAlways;
3171 fSelectedAlways = TRUE;
3172 listl = BuildList(hwndLeft);
3173 if (!*cmp->rightlist)
3174 listr = BuildList(hwndRight);
3175 fSelectedAlways = temp;
3176
3177 if (listl || listr) {
3178 if (Collector) {
3179 // 07 Aug 07 SHL Avoid collected from empty list
3180 if (listl && listl[0] && *listl[0]) {
3181 if (PostMsg(Collector, WM_COMMAND,
3182 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listl)))
3183 listl = NULL; // Collector will free
3184 }
3185 if (listr && listr[0] && *listr[0]) {
3186 if (PostMsg(Collector, WM_COMMAND,
3187 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listr)))
3188 listr = NULL; // Collector will free
3189 }
3190 WinSetWindowPos(WinQueryWindow(WinQueryWindow(Collector,
3191 QW_PARENT),
3192 QW_PARENT),
3193 HWND_TOP, 0, 0, 0, 0,
3194 SWP_ACTIVATE);
3195 }
3196 FreeList(listl);
3197 FreeList(listr);
3198 }
3199 }
3200 break;
3201 }
3202 return 0;
3203
3204 case WM_CLOSE:
3205 // 18 Jan 08 SHL fixme to hold off if thread busy?
3206 WinDismissDlg(hwnd, 0);
3207 return 0;
3208
3209 case WM_DESTROY:
3210 cmp = INSTDATA(hwnd);
3211 if (cmp) {
3212 // 17 Jan 08 SHL fixme to know if stop really needed?
3213 WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER);
3214 if (cmp->dcd.hwndLastMenu)
3215 WinDestroyWindow(cmp->dcd.hwndLastMenu);
3216 if (cmp->dcd.hwndObject) {
3217 WinSetWindowPtr(cmp->dcd.hwndObject, QWL_USER, (PVOID)NULL);
3218 if (!PostMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID))
3219 WinSendMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID);
3220 }
3221 xfree(cmp);
3222 }
3223 EmptyCnr(hwndLeft);
3224 EmptyCnr(hwndRight);
3225 DosPostEventSem(CompactSem);
3226 break;
3227 }
3228 return WinDefDlgProc(hwnd, msg, mp1, mp2);
3229}
3230
3231#pragma alloc_text(COMPAREDIR,FillCnrsThread,FillDirList,CompNames,BldFullPathName)
3232#pragma alloc_text(COMPAREDIR1,CompareDlgProc)
3233#pragma alloc_text(COMPAREDIR2,SelectCnrsThread,ActionCnrThread)
3234#pragma alloc_text(COMPAREFILE,CFileDlgProc,CompareFilesThread)
3235#pragma alloc_text(SNAPSHOT,SnapShot,StartSnap)
3236#pragma alloc_text(COMPSELECT,CompSelect)
3237
Note: See TracBrowser for help on using the repository browser.