source: trunk/dll/comp.c@ 1358

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

Comments for CS 1354/55

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