source: trunk/dll/comp.c@ 1400

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

Remainder of changes to rename commafmt.h/c (Ticket 28, 82); Additional strings moved to PCSZs in init.c (Ticket 6); Added WriteDetailsSwitches used it and LoadDetailsSwitches to consolidate inline code (Ticket 343, 344)

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