source: trunk/dll/comp.c@ 1132

Last change on this file since 1132 was 1132, checked in by Steven Levine, 17 years ago

Point pci fields at NullStr to sync with FreeCnrItemData mods

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