source: trunk/dll/comp.c@ 1391

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

Move nontranslated strings to init.c and codepage.c; use those strings in place of GetPString calls. Move other strings to a StringTable; minor cleanup and code changes to codepage.c to use a string array instead of GetPString calls. Ticket 340

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