source: trunk/dll/comp.c@ 1438

Last change on this file since 1438 was 1438, checked in by Gregg Young, 16 years ago

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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