source: trunk/dll/comp.c@ 1398

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

Move embeded strings to PCSZ variables or string table; Eliminate Error2 functions Runtime_Error with NULL format string returns "No data" error. Change declares from PSZ to PCSZ in functions where the variable isn't changed. Added btm as an executable file type in several additional places. Use fProtectOnly to prevent attempt to execute Dos and Win programs on "Protect only" installs in several additional places.

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