source: trunk/dll/comp.c@ 1402

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

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 101.9 KB
Line 
1
2/***********************************************************************
3
4 $Id: comp.c 1402 2009-03-14 17:17:59Z gyoung $
5
6 Compare directories
7
8 Copyright (c) 1993-02 M. Kimes
9 Copyright (c) 2003, 2009 Steven H. Levine
10
11 16 Oct 02 MK Baseline
12 04 Nov 03 SHL Force window refresh after subdir toggle
13 01 Aug 04 SHL Rework lstrip/rstrip usage
14 24 May 05 SHL Rework Win_Error usage
15 24 May 05 SHL Rework for CNRITEM.szSubject
16 25 May 05 SHL Rework with ULONGLONG
17 06 Jun 05 SHL Drop unused
18 12 Jul 06 SHL Renames and comments
19 13 Jul 06 SHL Use Runtime_Error
20 26 Jul 06 SHL Drop unreachable CN_... code
21 29 Jul 06 SHL Use xfgets_bstripcr
22 15 Aug 06 SHL Turn off hide not selected on dir change
23 19 Oct 06 SHL Correct . and .. detect
24 03 Nov 06 SHL Count thread usage
25 22 Mar 07 GKY Use QWL_USER
26 29 Jul 07 SHL Use Win_Error to report container errors
27 01 Aug 07 SHL Rework to sync with CNRITEM mods
28 01 Aug 07 SHL Rework to remove vast amount of duplicate code
29 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
30 06 Aug 07 SHL Move BldFullPathName here to be near primary caller
31 07 Aug 07 SHL COMP_COLLECT: Avoid collecting empty entries when nothing selected
32 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
33 13 Aug 07 SHL Sync code with other FilesToGet usage
34 13 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
35 20 Aug 07 SHL Correct remaining pcil/pcir typos (we hope)
36 20 Aug 07 SHL Revert to DosSleep(0)
37 20 Aug 07 SHL Use GetMSecTimer for timing
38 20 Aug 07 SHL A few more speed up tweaks. Some experimental timing code
39 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
40 27 Sep 07 SHL Correct ULONGLONG size formatting
41 30 Dec 07 GKY Use TestCDates for compare by file date/time
42 04 Jan 08 SHL Avoid traps if CM_ALLOCRECORD returns less that requested
43 05 Jan 08 SHL Use WM_TIMER for progress messaging
44 05 Jan 08 SHL Use ITIMER_DESC for hogging control
45 12 Jan 08 SHL Correct select count display regression
46 12 Jan 08 SHL Localize SpecialSelect here and rename
47 12 Jan 08 SHL Use SleepIfNeeded
48 12 Jan 08 SHL Reduce/eliminate more DosSleep calls
49 16 Jan 08 SHL Update total/select counts with WM_TIMER only
50 17 Jan 08 SHL Change hide not selected button to 3 state
51 18 Jan 08 SHL Honor filters in actions
52 20 Jan 08 GKY Compare dialog now saves and restores size and position
53 29 Feb 08 GKY Use xfree where appropriate
54 29 Feb 08 GKY Refactor global command line variables to notebook.h
55 16 Mar 08 GKY Prevent trap caused by files that exceed maxpath length
56 11 Jul 08 JBS Ticket 230: Simplified code and eliminated some local variables by incorporating
57 all the details view settings (both the global variables and those in the
58 DIRCNRDATA struct) into a new struct: DETAILS_SETTINGS.
59 08 Sep 08 SHL Avoid aliased pszLongName pointer in ActionCnrThread IDM_MOVE
60 10 Dec 08 SHL Integrate exception handler support
61 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis.
62 11 Jan 09 GKY Replace font names in the string file with global set at compile in init.c
63 07 Feb 09 GKY Add *DateFormat functions to format dates based on locale
64 08 Mar 09 GKY Renamed commafmt.h i18nutil.h
65 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
66 08 Mar 09 GKY Additional strings move to PCSZs in init.c & String Table
67
68***********************************************************************/
69
70#include <stdlib.h>
71#include <string.h>
72#include <share.h>
73#include <io.h>
74#include <ctype.h>
75// #include <process.h> // _endthread
76
77#define INCL_DOS
78#define INCL_WIN
79#define INCL_DOSERRORS
80#define INCL_GPI
81#define INCL_LONGLONG
82
83#include "fm3dll.h"
84#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
85#include "mainwnd2.h" // Data declaration(s)
86#include "inis.h" // Data declaration(s)
87#include "init.h" // Data declaration(s)
88#include "newview.h" // Data declarations
89#include "fm3dlg.h"
90#include "fm3str.h"
91#include "pathutil.h" // BldFullPathName
92#include "filldir.h" // EmptyCnr...
93#include "makelist.h" // AddToFileList...
94#include "errutil.h" // Dos_Error...
95#include "strutil.h" // GetPString
96#include "tmrsvcs.h" // IsITimerExpired
97#include "comp.h"
98#include "misc.h" // AddToListboxBottom, AdjustCnrColRO, AdjustCnrColVis,
99 // AdjustCnrColsForPref, CurrentRecord,
100 // AdjustDetailsSwitches, LoadDetailsSwitches, SetCnrCols
101 // SetDetailsSwitches
102#include "select.h" // Deselect, Deselect, InvertAll
103#include "mkdir.h" // MassMkdir
104#include "valid.h" // TestCDates
105#include "walkem.h" // WalkTwoCmpDlgProc
106#include "common.h" // DecrThreadUsage, IncrThreadUsage
107#include "defview.h" // DefaultViewKeys
108#include "draglist.h" // DoFileDrag
109#include "systemf.h" // ExecOnList
110#include "filter.h" // Filter
111#include "mainwnd.h" // GetNextWindowPos
112#include "shadow.h" // OpenObject
113#include "chklist.h" // PopupMenu
114#include "presparm.h" // SetPresParams
115#include "collect.h" // StartCollector
116#include "subj.h" // Subject
117#include "copyf.h" // docopyf
118#include "getnames.h" // export_filename
119#include "wrappers.h" // xDosFindNext
120#include "notebook.h" // External compare/dircompare
121#include "i18nutil.h" // CommaFmtULL
122#include "fortify.h" // 06 May 08 SHL added
123#include "excputil.h" // xbeginthread
124#include "info.h" // driveflags
125
126typedef struct
127{
128 CHAR filename[CCHMAXPATH];
129 CHAR dirname[CCHMAXPATH];
130 BOOL recurse;
131}
132SNAPSTUFF;
133
134// Data definitions
135static PSZ pszSrcFile = __FILE__;
136
137#pragma data_seg(GLOBAL1)
138BOOL fSelectedAlways;
139
140//=== SnapShot() Write directory tree to file and recurse if requested ===
141
142static VOID SnapShot(char *path, FILE *fp, BOOL recurse)
143{
144 PFILEFINDBUF4L pffb;
145 char *mask, *enddir;
146 HDIR hdir = HDIR_CREATE;
147 ULONG ulFindCnt;
148 CHAR szCmmaFmtFileSize[81], szDate[DATE_BUF_BYTES];
149
150 // 13 Aug 07 SHL fimxe to use FileToGet
151 pffb = xmalloc(sizeof(FILEFINDBUF4L), pszSrcFile, __LINE__);
152 if (pffb) {
153 mask = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
154 if (mask) {
155 BldFullPathName(mask, path, "*");
156 enddir = strrchr(mask, '\\');
157 enddir++;
158 ulFindCnt = 1;
159 // 13 Aug 07 SHL fixme to report errors
160 if (!xDosFindFirst(mask,
161 &hdir,
162 FILE_NORMAL | FILE_DIRECTORY |
163 FILE_ARCHIVED | FILE_READONLY | FILE_HIDDEN |
164 FILE_SYSTEM,
165 pffb, sizeof(FILEFINDBUF4L), &ulFindCnt, FIL_QUERYEASIZEL)) {
166 do {
167 strcpy(enddir, pffb->achName);
168 if (!(pffb->attrFile & FILE_DIRECTORY)) {
169 CommaFmtULL(szCmmaFmtFileSize,
170 sizeof(szCmmaFmtFileSize), pffb->cbFile, ' ');
171 FDateFormat(szDate, pffb->fdateLastWrite);
172 fprintf(fp,
173 "\"%s\",%u,%s,%s,%02u%s%02u%s%02u,%lu,%lu,N\n",
174 mask,
175 enddir - mask,
176 szCmmaFmtFileSize,
177 szDate,
178 pffb->ftimeLastWrite.hours,
179 TimeSeparator,
180 pffb->ftimeLastWrite.minutes,
181 TimeSeparator,
182 pffb->ftimeLastWrite.twosecs,
183 pffb->attrFile,
184 pffb->cbList > 4 ? pffb->cbList / 2 : 0);
185 }
186 // Skip . and ..
187 else if (recurse &&
188 (pffb->achName[0] != '.' ||
189 (pffb->achName[1] &&
190 (pffb->achName[1] != '.' || pffb->achName[2])))) {
191 SnapShot(mask, fp, recurse);
192 }
193 ulFindCnt = 1;
194 } while (!xDosFindNext(hdir, pffb, sizeof(FILEFINDBUF4L), &ulFindCnt, FIL_QUERYEASIZEL));
195 DosFindClose(hdir);
196 }
197 free(mask);
198 }
199 free(pffb);
200 }
201}
202
203//=== StartSnap() Write directory tree to snapshot file ===
204
205static VOID StartSnap(VOID *pargs)
206{
207 SNAPSTUFF *sf = (SNAPSTUFF *)pargs;
208 FILE *fp;
209 CHAR *p;
210
211 if (sf) {
212 if (*sf->dirname && *sf->filename) {
213 priority_normal();
214 p = sf->dirname;
215 while (*p) {
216 if (*p == '/')
217 *p = '\\';
218 p++;
219 }
220 if (*(p - 1) != '\\') {
221 *p = '\\';
222 p++;
223 }
224 fp = xfopen(sf->filename, "w", pszSrcFile, __LINE__);
225 if (fp) {
226 fprintf(fp, "\"%s\"\n", sf->dirname);
227 SnapShot(sf->dirname, fp, sf->recurse);
228 fclose(fp);
229 }
230 }
231 free(sf);
232 }
233}
234
235//=== CompareFilesThread() Compare files and update container select flags ===
236
237static VOID CompareFilesThread(VOID *args)
238{
239 FCOMPARE fc;
240 HAB hab2;
241 HMQ hmq2;
242 FILE *fp1, *fp2;
243 ULONG len1, len2;
244 ULONG offset = 0;
245 LONG numread1, numread2;
246 CHAR s[1024], ss[1024], *p1, *p2;
247
248 if (args) {
249 fc = *(FCOMPARE *)args;
250 hab2 = WinInitialize(0);
251 if (hab2) {
252# ifdef FORTIFY
253 Fortify_EnterScope();
254# endif
255 hmq2 = WinCreateMsgQueue(hab2, 0);
256 if (hmq2) {
257 WinCancelShutdown(hmq2, TRUE);
258 IncrThreadUsage();
259 if (!IsFile(fc.file1) || IsRoot(fc.file1)) {
260 p1 = strrchr(fc.file2, '\\');
261 if (p1) {
262 if (fc.file1[strlen(fc.file1) - 1] == '\\')
263 p1++;
264 strcat(fc.file1, p1);
265 }
266 }
267 else if (!IsFile(fc.file2) || IsRoot(fc.file2)) {
268 p1 = strrchr(fc.file1, '\\');
269 if (p1) {
270 if (fc.file2[strlen(fc.file2) - 1] == '\\')
271 p1++;
272 strcat(fc.file2, p1);
273 }
274 }
275 sprintf(s, GetPString(IDS_COMPCOMPARETEXT), fc.file1);
276 AddToListboxBottom(fc.hwndList, s);
277 sprintf(s, GetPString(IDS_COMPTOTEXT), fc.file2);
278 AddToListboxBottom(fc.hwndList, s);
279 fp1 = _fsopen(fc.file1, "rb", SH_DENYNO);
280 if (!fp1) {
281 sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file1);
282 AddToListboxBottom(fc.hwndList, s);
283 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
284 }
285 else {
286 fp2 = _fsopen(fc.file2, "rb", SH_DENYNO);
287 if (!fp2) {
288 sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file2);
289 AddToListboxBottom(fc.hwndList, s);
290 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
291 }
292 else {
293 len1 = filelength(fileno(fp1));
294 len2 = filelength(fileno(fp2));
295 if (len1 != len2) {
296 strcpy(s, GetPString(IDS_COMPDIFSIZESTEXT));
297 AddToListboxBottom(fc.hwndList, s);
298 sprintf(s, GetPString(IDS_COMPVSBYTESTEXT), len1, len2);
299 AddToListboxBottom(fc.hwndList, s);
300 WinSetWindowText(fc.hwndHelp,
301 GetPString(IDS_COMPDONTMATCHTEXT));
302 }
303 else {
304 WinSetWindowText(fc.hwndHelp,
305 GetPString(IDS_COMPCOMPARINGTEXT));
306 while (WinIsWindow(hab2, fc.hwndList)) {
307 numread1 = fread(s, 1, 1024, fp1);
308 numread2 = fread(ss, 1, 1024, fp2);
309 if (numread1 != numread2 || feof(fp1) != feof(fp2)) {
310 sprintf(s, GetPString(IDS_COMPREADERRORTEXT),
311 offset, offset);
312 AddToListboxBottom(fc.hwndList, s);
313 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
314 break;
315 }
316 else if (!numread1 && feof(fp1) && feof(fp2)) {
317 AddToListboxBottom(fc.hwndList,
318 GetPString(IDS_COMPFILESMATCHTEXT));
319 if (!stricmp(fc.file1, fc.file2))
320 AddToListboxBottom(fc.hwndList,
321 GetPString(IDS_COMPWONDERWHYTEXT));
322 WinSetWindowText(fc.hwndHelp,
323 GetPString(IDS_COMPCOMPLETETEXT));
324 break;
325 }
326 else if (numread1 <= 0 || numread2 <= 0) {
327 if (offset == len1)
328 break;
329 else {
330 sprintf(s, GetPString(IDS_COMPMATCHREADERRORTEXT),
331 offset, offset);
332 WinSetWindowText(fc.hwndHelp,
333 GetPString(IDS_COMPODDERRORTEXT));
334 AddToListboxBottom(fc.hwndList, s);
335 break;
336 }
337 }
338 else if (memcmp(s, ss, numread1)) {
339 p1 = s;
340 p2 = ss;
341 while (p1 < s + numread1) {
342 if (*p1 != *p2) {
343 sprintf(s, GetPString(IDS_COMPMISMATCHERRORTEXT),
344 offset + (p1 - s), offset + (p1 - s));
345 AddToListboxBottom(fc.hwndList, s);
346 WinSetWindowText(fc.hwndHelp,
347 GetPString(IDS_COMPDONTMATCHTEXT));
348 break;
349 }
350 p1++;
351 p2++;
352 }
353 break;
354 }
355 offset += numread1;
356 }
357 }
358 fclose(fp2);
359 }
360 fclose(fp1);
361 }
362 DecrThreadUsage();
363 WinDestroyMsgQueue(hmq2);
364 }
365 WinTerminate(hab2);
366# ifdef FORTIFY
367 Fortify_LeaveScope();
368# endif
369 }
370 }
371}
372
373//=== CFileDlgProc() Select directories to compare dialog procedure ===
374
375MRESULT EXPENTRY CFileDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
376{
377 FCOMPARE *fc;
378
379 switch (msg) {
380 case WM_INITDLG:
381 if (!mp2)
382 WinDismissDlg(hwnd, 0);
383 else {
384 WinSetWindowPtr(hwnd, QWL_USER, mp2);
385 fc = (FCOMPARE *)mp2;
386 fc->hwndReport = hwnd;
387 fc->hwndList = WinWindowFromID(hwnd, FCMP_LISTBOX);
388 fc->hwndHelp = WinWindowFromID(hwnd, FCMP_HELP);
389 if (!*fc->file1 || !fc->file2) {
390 WinDismissDlg(hwnd, 0);
391 break;
392 }
393 MakeFullName(fc->file1);
394 MakeFullName(fc->file2);
395 if (!stricmp(fc->file1, fc->file2)) {
396 saymsg(MB_CANCEL, hwnd,
397 GetPString(IDS_COMPSILLYALERTTEXT),
398 GetPString(IDS_COMPTOITSELFTEXT));
399 WinDismissDlg(hwnd, 0);
400 break;
401 }
402 if (xbeginthread(CompareFilesThread,
403 65536,
404 fc,
405 pszSrcFile,
406 __LINE__) == -1)
407 {
408 WinDismissDlg(hwnd, 0);
409 }
410 }
411 break;
412
413 case WM_ADJUSTWINDOWPOS:
414 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
415 break;
416
417 case UM_SETDIR:
418 PaintRecessedWindow(WinWindowFromID(hwnd, FCMP_HELP),
419 (HPS)0, FALSE, TRUE);
420 return 0;
421
422 case WM_COMMAND:
423 switch (SHORT1FROMMP(mp1)) {
424 case DID_OK:
425 WinDismissDlg(hwnd, 0);
426 break;
427 case DID_CANCEL:
428 WinDismissDlg(hwnd, 1);
429 break;
430 }
431 return 0;
432
433 case WM_DESTROY:
434 DosSleep(50); // Let others die first
435 break;
436 }
437 return WinDefDlgProc(hwnd, msg, mp1, mp2);
438}
439
440//=== ActionCnrThread() Do requested action on container contents ===
441
442static VOID ActionCnrThread(VOID *args)
443{
444 COMPARE *cmp = (COMPARE *)args;
445 HAB hab;
446 HMQ hmq;
447 HWND hwndCnrS, hwndCnrD;
448 PCNRITEM pciS, pciD, pciNextS, pciNextD;
449 CHAR szNewName[CCHMAXPATH], szDirName[CCHMAXPATH], *p;
450 APIRET rc;
451 ITIMER_DESC itdSleep = { 0 };
452
453 if (!cmp) {
454 Runtime_Error(pszSrcFile, __LINE__, NULL);
455 return;
456 }
457
458 DosError(FERR_DISABLEHARDERR);
459
460 hab = WinInitialize(0);
461 if (hab) {
462# ifdef FORTIFY
463 Fortify_EnterScope();
464# endif
465 hmq = WinCreateMsgQueue(hab, 0);
466 if (hmq) {
467 WinCancelShutdown(hmq, TRUE);
468 IncrThreadUsage();
469 priority_normal();
470 switch (cmp->action) {
471 case COMP_DELETELEFT:
472 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
473 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
474 cmp->action = IDM_DELETE;
475 break;
476 case COMP_DELETERIGHT:
477 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
478 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
479 cmp->action = IDM_DELETE;
480 break;
481 case COMP_MOVELEFT:
482 cmp->action = IDM_MOVE;
483 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
484 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
485 break;
486 case COMP_MOVERIGHT:
487 cmp->action = IDM_MOVE;
488 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
489 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
490 break;
491 case COMP_COPYLEFT:
492 cmp->action = IDM_COPY;
493 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
494 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
495 break;
496 case COMP_COPYRIGHT:
497 cmp->action = IDM_COPY;
498 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
499 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
500 break;
501 default:
502 Runtime_Error(pszSrcFile, __LINE__, "bad case %u", cmp->action);
503 goto Abort;
504 }
505
506 pciS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
507 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
508 pciD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
509 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
510
511 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
512
513 while (pciS && (INT)pciS != -1 && pciD && (INT)pciD != -1) {
514
515 pciNextS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
516 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
517 pciNextD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
518 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
519
520 // Process file if selected and not filtered
521 if (*pciS->pszFileName &&
522 pciS->rc.flRecordAttr & CRA_SELECTED &&
523 ~pciS->rc.flRecordAttr & CRA_FILTERED)
524 {
525 // Source name not blank
526 switch (cmp->action) {
527 case IDM_DELETE:
528 if (!unlinkf(pciS->pszFileName)) {
529 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
530 MPFROM2SHORT(FALSE, CRA_SELECTED));
531
532 if (!*pciD->pszFileName) {
533 // Other side is blank - remove from both sides
534 RemoveCnrItems(hwndCnrS, pciS, 1, CMA_FREE | CMA_INVALIDATE);
535 if (pciD->rc.flRecordAttr & CRA_SELECTED)
536 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
537 MPFROM2SHORT(FALSE, CRA_SELECTED));
538 RemoveCnrItems(hwndCnrD, pciD, 1, CMA_FREE | CMA_INVALIDATE);
539 }
540 else {
541 // Other side is not blank - blank just this side
542 FreeCnrItemData(pciS);
543 // 29 Aug 08 SHL Point pci fields at NullStr to sync with FreeCnrItemData mods
544 pciS->pszFileName = NullStr;
545 pciS->pszDisplayName = pciS->pszFileName;
546 pciS->rc.pszIcon = pciS->pszFileName;
547 pciS->flags = 0; // Just on one side
548 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
549 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
550 pciD->flags = 0; // Just on one side
551 if (pciD->pszSubject != NullStr) {
552 xfree(pciD->pszSubject, pszSrcFile, __LINE__);
553 pciD->pszSubject = NullStr;
554 }
555 }
556 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
557 cmp->cmp->totalleft--;
558 else
559 cmp->cmp->totalright--;
560 }
561 break;
562
563 case IDM_MOVE:
564 {
565 BOOL fResetVerify = FALSE;
566
567 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
568 BldFullPathName(szNewName, cmp->leftdir, pciS->pszDisplayName);
569 else
570 BldFullPathName(szNewName, cmp->rightdir, pciS->pszDisplayName);
571 // Make directory if required
572 strcpy(szDirName, szNewName);
573 p = strrchr(szDirName, '\\');
574 if (fVerify && (driveflags[toupper(*szNewName) - 'A'] & DRIVE_WRITEVERIFYOFF ||
575 driveflags[toupper(*pciS->pszFileName) - 'A'] & DRIVE_WRITEVERIFYOFF)) {
576 DosSetVerify(FALSE);
577 fResetVerify = TRUE;
578 }
579 if (p) {
580 if (p > szDirName + 2)
581 p++;
582 *p = 0;
583 if (IsFile(szDirName) == -1)
584 MassMkdir(hwndMain, szDirName);
585 }
586 rc = docopyf(MOVE, pciS->pszFileName, szNewName);
587 if (fResetVerify) {
588 DosSetVerify(fVerify);
589 fResetVerify = FALSE;
590 }
591 if (!rc && stricmp(pciS->pszFileName, szNewName)) {
592 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
593 MPFROM2SHORT(FALSE, CRA_SELECTED));
594 if (pciD->rc.flRecordAttr & CRA_SELECTED)
595 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
596 MPFROM2SHORT(FALSE, CRA_SELECTED));
597 FreeCnrItemData(pciD);
598 pciD->pszFileName = xstrdup(szNewName, pszSrcFile, __LINE__);
599 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
600 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
601 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
602 pciD->pszDisplayName++;
603 }
604 else {
605 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
606 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
607 pciD->pszDisplayName++;
608 }
609 pciD->pszLongName = pciS->pszLongName;
610 pciS->pszLongName = NullStr; // 07 Sep 08 SHL avoid aliased pointer
611 if (pciD->pszSubject != NullStr) {
612 xfree(pciD->pszSubject, pszSrcFile, __LINE__);
613 pciD->pszSubject = NullStr;
614 }
615 pciD->attrFile = pciS->attrFile;
616 pciD->pszDispAttr = pciS->pszDispAttr;
617 pciD->flags = 0; // Just on one side
618 pciD->date = pciS->date;
619 pciD->time = pciS->time;
620 pciD->ladate = pciS->ladate;
621 pciD->latime = pciS->latime;
622 pciD->crdate = pciS->crdate;
623 pciD->crtime = pciS->crtime;
624 pciD->cbFile = pciS->cbFile;
625 pciD->easize = pciS->easize;
626
627 if (pciS->pszFileName != NullStr) {
628 xfree(pciS->pszFileName, pszSrcFile, __LINE__);
629 pciS->pszFileName = NullStr;
630 pciS->pszDisplayName = pciS->pszFileName;
631 pciS->rc.pszIcon = pciS->pszFileName;
632 }
633 if (pciS->pszSubject != NullStr) {
634 xfree(pciS->pszSubject, pszSrcFile, __LINE__);
635 pciS->pszSubject = NullStr;
636 }
637 pciS->flags = 0; // Just on one side
638
639 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
640 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
641
642 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
643 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
644
645 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
646 cmp->cmp->totalleft--;
647 else
648 cmp->cmp->totalright--;
649 }
650 else if (rc) {
651 rc = Dos_Error(MB_ENTERCANCEL,
652 rc,
653 HWND_DESKTOP,
654 pszSrcFile,
655 __LINE__,
656 GetPString(IDS_COMPMOVEFAILEDTEXT),
657 pciS->pszFileName, szNewName);
658 if (rc == MBID_CANCEL) // Cause loop to break
659 pciNextS = NULL;
660 }
661 break;
662 }
663
664 case IDM_COPY:
665 {
666 BOOL fResetVerify = FALSE;
667
668 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
669 BldFullPathName(szNewName, cmp->leftdir, pciS->pszDisplayName);
670 else
671 BldFullPathName(szNewName, cmp->rightdir, pciS->pszDisplayName);
672 // Make directory if required
673 strcpy(szDirName, szNewName);
674 p = strrchr(szDirName, '\\');
675 if (fVerify && (driveflags[toupper(*szNewName) - 'A'] & DRIVE_WRITEVERIFYOFF ||
676 driveflags[toupper(*pciS->pszFileName) - 'A'] & DRIVE_WRITEVERIFYOFF)) {
677 DosSetVerify(FALSE);
678 fResetVerify = TRUE;
679 }
680 if (p) {
681 if (p > szDirName + 2)
682 p++;
683 *p = 0;
684 if (IsFile(szDirName) == -1)
685 MassMkdir(hwndMain, szDirName);
686 }
687 rc = docopyf(COPY, pciS->pszFileName, szNewName);
688 if (fResetVerify) {
689 DosSetVerify(fVerify);
690 fResetVerify = FALSE;
691 }
692 if (rc) {
693 rc = Dos_Error(MB_ENTERCANCEL,
694 rc,
695 HWND_DESKTOP,
696 pszSrcFile,
697 __LINE__,
698 GetPString(IDS_COMPCOPYFAILEDTEXT),
699 pciS->pszFileName, szNewName);
700 if (rc == MBID_CANCEL)
701 pciNextS = NULL; // Cause loop to break
702 }
703 else {
704 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciS),
705 MPFROM2SHORT(FALSE, CRA_SELECTED));
706 if (pciD->rc.flRecordAttr & CRA_SELECTED)
707 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
708 MPFROM2SHORT(FALSE, CRA_SELECTED));
709 // 12 Jan 08 SHL
710 if (pciD->pszFileName == NullStr) {
711 if (hwndCnrD == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
712 cmp->totalleft++;
713 else
714 cmp->totalright++;
715 }
716 FreeCnrItemData(pciD);
717 pciD->pszFileName = xstrdup(szNewName, pszSrcFile, __LINE__);
718 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
719 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
720 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
721 pciD->pszDisplayName++;
722 }
723 else {
724 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
725 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
726 pciD->pszDisplayName++;
727 }
728 pciD->attrFile = pciS->attrFile;
729 pciD->pszDispAttr = pciS->pszDispAttr;
730 pciD->flags = CNRITEM_EXISTS; // Now on both sides
731 pciD->date = pciS->date;
732 pciD->time = pciS->time;
733 pciD->ladate = pciS->ladate;
734 pciD->latime = pciS->latime;
735 pciD->crdate = pciS->crdate;
736 pciD->crtime = pciS->crtime;
737 pciD->cbFile = pciS->cbFile;
738 pciD->easize = pciS->easize;
739
740 // Forget status until we regenerate it
741 if (pciS->pszSubject != NullStr) {
742 xfree(pciS->pszSubject, pszSrcFile, __LINE__);
743 pciS->pszSubject = NullStr;
744 }
745 pciS->flags = CNRITEM_EXISTS; // Now on both sides
746
747 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pciS),
748 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
749 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
750 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
751 }
752 break;
753 }
754
755 default:
756 break;
757 } // switch
758
759 } // if have name
760
761 pciS = pciNextS;
762 pciD = pciNextD;
763
764 SleepIfNeeded(&itdSleep, 0);
765 } // while
766 WinPostMsg(cmp->hwnd, WM_TIMER, MPFROMLONG(ID_TIMER), 0); // Force update
767 Abort:
768 WinDestroyMsgQueue(hmq);
769 }
770 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1), MPVOID);
771 // PostMsg(cmp->hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DESELECTALL, 0), MPVOID); // 18 Jan 08 SHL we can count now
772 DecrThreadUsage();
773 free(cmp);
774 WinTerminate(hab);
775# ifdef FORTIFY
776 Fortify_LeaveScope();
777# endif
778 }
779 else
780 xfree(cmp, pszSrcFile, __LINE__);
781}
782
783VOID CompSelect(HWND hwndCnrS, HWND hwndCnrD, HWND hwnd, INT action, BOOL reset);
784
785//=== SelectCnrsThread() Update container selection flags thread ===
786
787static VOID SelectCnrsThread(VOID *args)
788{
789 COMPARE *cmp = (COMPARE *)args;
790 HAB hab;
791 HMQ hmq;
792
793 if (!cmp) {
794 Runtime_Error(pszSrcFile, __LINE__, NULL);
795 return;
796 }
797
798 DosError(FERR_DISABLEHARDERR);
799
800 hab = WinInitialize(0);
801 if (hab) {
802# ifdef FORTIFY
803 Fortify_EnterScope();
804# endif
805 hmq = WinCreateMsgQueue(hab, 0);
806 if (hmq) {
807 WinCancelShutdown(hmq, TRUE);
808 IncrThreadUsage();
809 priority_normal();
810 switch (cmp->action) {
811 case IDM_INVERT:
812 InvertAll(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
813 InvertAll(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
814 break;
815
816 case IDM_DESELECTALL:
817 Deselect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
818 Deselect(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
819 break;
820
821 default:
822 // 13 Jan 08 SHL fixme to decide if cmp->reset can ever get set
823 // if not lots of code can disappear
824 if (cmp->reset)
825 DbgMsg(pszSrcFile, __LINE__, "cmp->reset is TRUE");
826 CompSelect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR),
827 WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR),
828 cmp->hwnd,
829 cmp->action,
830 cmp->reset);
831 break;
832 }
833 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID))
834 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID);
835 WinDestroyMsgQueue(hmq);
836 }
837 DecrThreadUsage();
838 free(cmp);
839 WinTerminate(hab);
840# ifdef FORTIFY
841 Fortify_LeaveScope();
842# endif
843 }
844 else
845 free(cmp);
846}
847
848/**
849 * Do select actions for compare directories containers
850 * @param action is select mode
851 * @param reset requests flags by regenerated
852 */
853
854VOID CompSelect(HWND hwndCnrS, HWND hwndCnrD, HWND hwnd, INT action, BOOL reset)
855{
856 PCNRITEM pciS, pciD, *pciSa = NULL, *pciDa = NULL;
857 CNRINFO cnri;
858 BOOL slow = FALSE;
859 UINT x, numD, numS;
860 INT ret = 0;
861 ITIMER_DESC itdSleep = { 0 };
862 BOOL fUpdateHideButton = FALSE;
863
864 if (!hwndCnrS || !hwndCnrD) {
865 Runtime_Error(pszSrcFile, __LINE__, "hwndCnrS %p hwndCnrD %p", hwndCnrS, hwndCnrD);
866 return;
867 }
868
869 memset(&cnri, 0, sizeof(CNRINFO));
870 cnri.cb = sizeof(CNRINFO);
871 WinSendMsg(hwndCnrD, CM_QUERYCNRINFO, MPFROMP(&cnri),
872 MPFROMLONG(sizeof(CNRINFO)));
873 numD = cnri.cRecords;
874 memset(&cnri, 0, sizeof(CNRINFO));
875 cnri.cb = sizeof(CNRINFO);
876 WinSendMsg(hwndCnrS, CM_QUERYCNRINFO, MPFROMP(&cnri),
877 MPFROMLONG(sizeof(CNRINFO)));
878 numS = cnri.cRecords;
879 if (!numD || numS != numD) {
880 Runtime_Error(pszSrcFile, __LINE__, "numD %u != numS %u", numD, numS);
881 return;
882 }
883
884 pciDa = xmalloc(sizeof(PCNRITEM) * numD, pszSrcFile, __LINE__);
885 if (!pciDa)
886 return;
887
888 pciSa = xmalloc(sizeof(PCNRITEM) * numS, pszSrcFile, __LINE__);
889 if (!pciSa) {
890 free(pciDa);
891 return;
892 }
893
894 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
895
896Restart:
897
898 memset(pciDa, 0, sizeof(PCNRITEM) * numD);
899 memset(pciSa, 0, sizeof(PCNRITEM) * numS);
900
901 pciD = (PCNRITEM)WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
902 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
903 x = 0;
904 while (pciD && (INT)pciD != -1 && x < numD) {
905 if (reset)
906 pciD->flags = 0;
907 pciDa[x] = pciD;
908 x++;
909 if (!slow)
910 pciD = (PCNRITEM) pciD->rc.preccNextRecord;
911 else
912 pciD = (PCNRITEM) WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
913 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
914 SleepIfNeeded(&itdSleep, 0);
915 } // while
916
917 if (numD != x) {
918 // Something out of sync - fixme to document why
919 if (!slow) {
920 slow = TRUE;
921 goto Restart;
922 }
923 free(pciDa);
924 free(pciSa);
925 Runtime_Error(pszSrcFile, __LINE__, "numD %u != x %lu", numD, x);
926 return;
927 }
928
929 pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
930 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
931 x = 0;
932 while (pciS && (INT)pciS != -1 && x < numS) {
933 if (reset)
934 pciS->flags = 0;
935 pciSa[x] = pciS;
936 x++;
937 if (!slow)
938 pciS = (PCNRITEM) pciS->rc.preccNextRecord;
939 else
940 pciS = (PCNRITEM) WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pciS),
941 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
942 SleepIfNeeded(&itdSleep, 0);
943 } // while
944
945 if (numS != x) {
946 if (!slow) {
947 slow = TRUE;
948 goto Restart;
949 }
950 free(pciSa);
951 free(pciDa);
952 Runtime_Error(pszSrcFile, __LINE__, "numS (%lu) != x (%lu)", numS, x);
953 return;
954 }
955
956 if (reset) {
957 // Update flags for files that exist on both sides
958 for (x = 0; x < numS; x++) {
959
960 if (!*pciSa[x]->pszFileName || !*pciDa[x]->pszFileName) {
961 // 12 Jan 08 SHL clear flags
962 pciSa[x]->flags = 0; // File exists on one side only
963 pciDa[x]->flags = 0;
964 continue;
965 }
966
967 pciSa[x]->flags |= CNRITEM_EXISTS; // File exists on both sides
968 pciDa[x]->flags |= CNRITEM_EXISTS;
969 if (pciSa[x]->cbFile + pciSa[x]->easize >
970 pciDa[x]->cbFile + pciDa[x]->easize) {
971 pciSa[x]->flags |= CNRITEM_LARGER;
972 pciDa[x]->flags |= CNRITEM_SMALLER;
973 }
974 else if (pciSa[x]->cbFile + pciSa[x]->easize <
975 pciDa[x]->cbFile + pciDa[x]->easize) {
976 pciSa[x]->flags |= CNRITEM_SMALLER;
977 pciDa[x]->flags |= CNRITEM_LARGER;
978 }
979 ret = TestCDates(&pciDa[x]->date, &pciDa[x]->time,
980 &pciSa[x]->date, &pciSa[x]->time);
981 if (ret == 1)
982 /* 13 Jan 08 SHL fixme to be gone?
983 ((pciSa[x]->date.year > pciDa[x]->date.year) ? TRUE :
984 (pciSa[x]->date.year < pciDa[x]->date.year) ? FALSE :
985 (pciSa[x]->date.month > pciDa[x]->date.month) ? TRUE :
986 (pciSa[x]->date.month < pciDa[x]->date.month) ? FALSE :
987 (pciSa[x]->date.day > pciDa[x]->date.day) ? TRUE :
988 (pciSa[x]->date.day < pciDa[x]->date.day) ? FALSE :
989 (pciSa[x]->time.hours > pciDa[x]->time.hours) ? TRUE :
990 (pciSa[x]->time.hours < pciDa[x]->time.hours) ? FALSE :
991 (pciSa[x]->time.minutes > pciDa[x]->time.minutes) ? TRUE :
992 (pciSa[x]->time.minutes < pciDa[x]->time.minutes) ? FALSE :
993 (pciSa[x]->time.seconds > pciDa[x]->time.seconds) ? TRUE :
994 (pciSa[x]->time.seconds < pciDa[x]->time.seconds) ? FALSE : FALSE)
995 */
996 {
997 pciSa[x]->flags |= CNRITEM_NEWER;
998 pciDa[x]->flags |= CNRITEM_OLDER;
999 }
1000 else if (ret == -1)
1001 /* 13 Jan 08 SHL fixme to be gone?
1002 ((pciSa[x]->date.year < pciDa[x]->date.year) ? TRUE :
1003 (pciSa[x]->date.year > pciDa[x]->date.year) ? FALSE :
1004 (pciSa[x]->date.month < pciDa[x]->date.month) ? TRUE :
1005 (pciSa[x]->date.month > pciDa[x]->date.month) ? FALSE :
1006 (pciSa[x]->date.day < pciDa[x]->date.day) ? TRUE :
1007 (pciSa[x]->date.day > pciDa[x]->date.day) ? FALSE :
1008 (pciSa[x]->time.hours < pciDa[x]->time.hours) ? TRUE :
1009 (pciSa[x]->time.hours > pciDa[x]->time.hours) ? FALSE :
1010 (pciSa[x]->time.minutes < pciDa[x]->time.minutes) ? TRUE :
1011 (pciSa[x]->time.minutes > pciDa[x]->time.minutes) ? FALSE :
1012 (pciSa[x]->time.seconds < pciDa[x]->time.seconds) ? TRUE :
1013 (pciSa[x]->time.seconds > pciDa[x]->time.seconds) ? FALSE :
1014 FALSE)
1015 */
1016 {
1017 pciSa[x]->flags |= CNRITEM_OLDER;
1018 pciDa[x]->flags |= CNRITEM_NEWER;
1019 }
1020 SleepIfNeeded(&itdSleep, 0);
1021 } // for
1022 } // if reset
1023
1024 switch (action) {
1025 case IDM_SELECTIDENTICAL:
1026 for (x = 0; x < numS; x++) {
1027 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1028 pciSa[x]->flags & CNRITEM_EXISTS &&
1029 ~pciSa[x]->flags & CNRITEM_SMALLER &&
1030 ~pciSa[x]->flags & CNRITEM_LARGER &&
1031 ~pciSa[x]->flags & CNRITEM_NEWER &&
1032 ~pciSa[x]->flags & CNRITEM_OLDER) {
1033 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1034 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1035 MPFROM2SHORT(TRUE, CRA_SELECTED));
1036 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1037 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1038 MPFROM2SHORT(TRUE, CRA_SELECTED));
1039 }
1040 SleepIfNeeded(&itdSleep, 0);
1041 } // for
1042 break;
1043
1044 case IDM_SELECTSAME:
1045 for (x = 0; x < numS; x++) {
1046 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1047 pciSa[x]->flags & CNRITEM_EXISTS &&
1048 ~pciSa[x]->flags & CNRITEM_SMALLER &&
1049 ~pciSa[x]->flags & CNRITEM_LARGER) {
1050 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1051 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1052 MPFROM2SHORT(TRUE, CRA_SELECTED));
1053 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1054 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1055 MPFROM2SHORT(TRUE, CRA_SELECTED));
1056 }
1057 SleepIfNeeded(&itdSleep, 0);
1058 } // for
1059 break;
1060
1061 case IDM_SELECTSAMECONTENT:
1062 for (x = 0; x < numS; x++) {
1063 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1064 pciSa[x]->flags & CNRITEM_EXISTS)
1065 {
1066 FILE *fp1 = NULL;
1067 FILE *fp2 = NULL;
1068 BOOL gotMatch = FALSE;
1069 UINT errLineNo = 0;
1070 UINT compErrno = 0;
1071 CHAR buf1[1024];
1072 CHAR buf2[1024];
1073 HAB hab = WinQueryAnchorBlock(hwndCnrS);
1074
1075 if (!*pciSa[x]->pszFileName ||
1076 !*pciDa[x]->pszFileName) {
1077 Runtime_Error(pszSrcFile, __LINE__,
1078 "CNRITEM_EXISTS set with null file name for index %u", x);
1079 break;
1080 }
1081
1082 fp1 = _fsopen(pciSa[x]->pszFileName, "rb", SH_DENYNO);
1083 if (!fp1) {
1084 errLineNo = __LINE__;
1085 compErrno = errno;
1086 }
1087 else {
1088 fp2 = _fsopen(pciDa[x]->pszFileName, "rb", SH_DENYNO);
1089 if (!fp2) {
1090 errLineNo = __LINE__;
1091 compErrno = errno;
1092 }
1093 else {
1094 size_t len1 = filelength(fileno(fp1));
1095 size_t len2 = filelength(fileno(fp2));
1096
1097 if (len1 == len2) {
1098 setbuf(fp1, NULL);
1099 setbuf(fp2, NULL);
1100 while (WinIsWindow(hab, hwndCnrS)) {
1101 size_t numread1 = fread(buf1, 1, 1024, fp1);
1102 size_t numread2 = fread(buf2, 1, 1024, fp2);
1103
1104 if (!numread1 || !numread2 || numread1 != numread2) {
1105 if (ferror(fp1) || ferror(fp2)) {
1106 errLineNo = __LINE__;
1107 compErrno = errno;
1108 }
1109 else if (feof(fp1) && feof(fp2))
1110 gotMatch = TRUE;
1111 break;
1112 }
1113 else if (memcmp(buf1, buf2, numread1))
1114 break;
1115 } // while
1116 } // same len
1117 }
1118 }
1119
1120 if (fp1)
1121 fclose(fp1);
1122
1123 if (fp2)
1124 fclose(fp2);
1125
1126 if (errLineNo) {
1127 Runtime_Error(pszSrcFile, errLineNo,
1128 "error %d while comparing", compErrno);
1129 }
1130
1131 if (gotMatch) {
1132 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1133 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1134 MPFROM2SHORT(TRUE, CRA_SELECTED));
1135 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1136 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1137 MPFROM2SHORT(TRUE, CRA_SELECTED));
1138 }
1139 }
1140 SleepIfNeeded(&itdSleep, 0);
1141 } // for
1142 break;
1143
1144 case IDM_SELECTBOTH:
1145 for (x = 0; x < numS; x++) {
1146 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1147 pciSa[x]->flags & CNRITEM_EXISTS) {
1148 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1149 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1150 MPFROM2SHORT(TRUE, CRA_SELECTED));
1151 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1152 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1153 MPFROM2SHORT(TRUE, CRA_SELECTED));
1154 }
1155 SleepIfNeeded(&itdSleep, 0);
1156 } // for
1157 break;
1158
1159 case IDM_SELECTONE:
1160 for (x = 0; x < numS; x++) {
1161 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1162 ~pciSa[x]->flags & CNRITEM_EXISTS) {
1163 if (*pciSa[x]->pszFileName) {
1164 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1165 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1166 MPFROM2SHORT(TRUE, CRA_SELECTED));
1167 }
1168 }
1169 else if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
1170 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1171 MPFROM2SHORT(TRUE, CRA_SELECTED));
1172 }
1173 }
1174 SleepIfNeeded(&itdSleep, 0);
1175 } // for
1176 break;
1177
1178 case IDM_SELECTBIGGER:
1179 for (x = 0; x < numS; x++) {
1180 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1181 if (pciSa[x]->flags & CNRITEM_LARGER) {
1182 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1183 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1184 MPFROM2SHORT(TRUE, CRA_SELECTED));
1185 }
1186 else if (pciDa[x]->flags & CNRITEM_LARGER) {
1187 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1188 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1189 MPFROM2SHORT(TRUE, CRA_SELECTED));
1190 }
1191 }
1192 SleepIfNeeded(&itdSleep, 0);
1193 } // for
1194 break;
1195
1196 case IDM_SELECTSMALLER:
1197 for (x = 0; x < numS; x++) {
1198 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1199 if (pciSa[x]->flags & CNRITEM_SMALLER) {
1200 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1201 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1202 MPFROM2SHORT(TRUE, CRA_SELECTED));
1203 }
1204 else if (pciDa[x]->flags & CNRITEM_SMALLER) {
1205 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1206 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1207 MPFROM2SHORT(TRUE, CRA_SELECTED));
1208 }
1209 }
1210 SleepIfNeeded(&itdSleep, 0);
1211 } // for
1212 break;
1213
1214 case IDM_SELECTNEWER:
1215 for (x = 0; x < numS; x++) {
1216 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1217 if (pciSa[x]->flags & CNRITEM_NEWER) {
1218 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1219 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1220 MPFROM2SHORT(TRUE, CRA_SELECTED));
1221 }
1222 else if (pciDa[x]->flags & CNRITEM_NEWER) {
1223 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1224 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1225 MPFROM2SHORT(TRUE, CRA_SELECTED));
1226 }
1227 }
1228 SleepIfNeeded(&itdSleep, 0);
1229 } // for
1230 break;
1231
1232 case IDM_SELECTOLDER:
1233 for (x = 0; x < numS; x++) {
1234 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1235 if (pciSa[x]->flags & CNRITEM_OLDER) {
1236 if (~pciSa[x]->rc.flRecordAttr & CRA_SELECTED)
1237 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1238 MPFROM2SHORT(TRUE, CRA_SELECTED));
1239 }
1240 else if (pciDa[x]->flags & CNRITEM_OLDER) {
1241 if (~pciDa[x]->rc.flRecordAttr & CRA_SELECTED)
1242 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1243 MPFROM2SHORT(TRUE, CRA_SELECTED));
1244 }
1245 }
1246 SleepIfNeeded(&itdSleep, 0);
1247 } // for
1248 break;
1249
1250 case IDM_DESELECTBOTH:
1251 for (x = 0; x < numS; x++) {
1252 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED &&
1253 pciSa[x]->flags & CNRITEM_EXISTS) {
1254 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1255 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1256 MPFROM2SHORT(FALSE, CRA_SELECTED));
1257 fUpdateHideButton = TRUE;
1258 }
1259 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
1260 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1261 MPFROM2SHORT(FALSE, CRA_SELECTED));
1262 fUpdateHideButton = TRUE;
1263 }
1264 }
1265 SleepIfNeeded(&itdSleep, 0);
1266 } // for
1267 break;
1268
1269 case IDM_DESELECTONE:
1270 for (x = 0; x < numS; x++) {
1271 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1272 if (~pciSa[x]->flags & CNRITEM_EXISTS) {
1273 if (*pciSa[x]->pszFileName) {
1274 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1275 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1276 MPFROM2SHORT(FALSE, CRA_SELECTED));
1277 fUpdateHideButton = TRUE;
1278 }
1279 }
1280 else if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
1281 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1282 MPFROM2SHORT(FALSE, CRA_SELECTED));
1283 fUpdateHideButton = TRUE;
1284 }
1285 }
1286 }
1287 SleepIfNeeded(&itdSleep, 0);
1288 } // for
1289 break;
1290
1291 case IDM_DESELECTBIGGER:
1292 for (x = 0; x < numS; x++) {
1293 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1294 if (pciSa[x]->flags & CNRITEM_LARGER) {
1295 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1296 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1297 MPFROM2SHORT(FALSE, CRA_SELECTED));
1298 fUpdateHideButton = TRUE;
1299 }
1300 }
1301 else if (pciDa[x]->flags & CNRITEM_LARGER) {
1302 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
1303 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1304 MPFROM2SHORT(FALSE, CRA_SELECTED));
1305 fUpdateHideButton = TRUE;
1306 }
1307 }
1308 }
1309 SleepIfNeeded(&itdSleep, 0);
1310 } // for
1311 break;
1312
1313 case IDM_DESELECTSMALLER:
1314 for (x = 0; x < numS; x++) {
1315 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1316 if (pciSa[x]->flags & CNRITEM_SMALLER) {
1317 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1318 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1319 MPFROM2SHORT(FALSE, CRA_SELECTED));
1320 fUpdateHideButton = TRUE;
1321 }
1322 }
1323 else if (pciDa[x]->flags & CNRITEM_SMALLER) {
1324 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
1325 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1326 MPFROM2SHORT(FALSE, CRA_SELECTED));
1327 fUpdateHideButton = TRUE;
1328 }
1329 }
1330 }
1331 SleepIfNeeded(&itdSleep, 0);
1332 } // for
1333 break;
1334
1335 case IDM_DESELECTNEWER:
1336 for (x = 0; x < numS; x++) {
1337 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1338 if (pciSa[x]->flags & CNRITEM_NEWER) {
1339 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1340 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1341 MPFROM2SHORT(FALSE, CRA_SELECTED));
1342 fUpdateHideButton = TRUE;
1343 }
1344 }
1345 else if (pciDa[x]->flags & CNRITEM_NEWER) {
1346 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
1347 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1348 MPFROM2SHORT(FALSE, CRA_SELECTED));
1349 fUpdateHideButton = TRUE;
1350 }
1351 }
1352 }
1353 SleepIfNeeded(&itdSleep, 0);
1354 } // for
1355 break;
1356
1357 case IDM_DESELECTOLDER:
1358 for (x = 0; x < numS; x++) {
1359 if (~pciSa[x]->rc.flRecordAttr & CRA_FILTERED) {
1360 if (pciSa[x]->flags & CNRITEM_OLDER) {
1361 if (pciSa[x]->rc.flRecordAttr & CRA_SELECTED) {
1362 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pciSa[x]),
1363 MPFROM2SHORT(FALSE, CRA_SELECTED));
1364 fUpdateHideButton = TRUE;
1365 }
1366 }
1367 else if (pciDa[x]->flags & CNRITEM_OLDER) {
1368 if (pciDa[x]->rc.flRecordAttr & CRA_SELECTED) {
1369 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciDa[x]),
1370 MPFROM2SHORT(FALSE, CRA_SELECTED));
1371 fUpdateHideButton = TRUE;
1372 }
1373 }
1374 }
1375 SleepIfNeeded(&itdSleep, 0);
1376 } // for
1377 break;
1378
1379 default:
1380 break;
1381 } // switch
1382
1383 if (reset) {
1384 while (numS) {
1385 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD,
1386 MPFROMP(pciSa), MPFROM2SHORT((min(numS, 65535)), 0));
1387 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD,
1388 MPFROMP(pciDa), MPFROM2SHORT((min(numD, 65535)), 0));
1389 numS -= min(numS, 65535);
1390 SleepIfNeeded(&itdSleep, 0); // 12 Jan 08 SHL
1391 } // while
1392 }
1393
1394 free(pciSa);
1395 free(pciDa);
1396
1397 if (fUpdateHideButton) {
1398 if (WinQueryButtonCheckstate(hwnd,COMP_HIDENOTSELECTED) == 1)
1399 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 2);
1400 }
1401
1402 WinPostMsg(hwnd, WM_TIMER, MPFROMLONG(ID_TIMER), 0); // Force update
1403 DosPostEventSem(CompactSem);
1404}
1405
1406/**
1407 * Build FILELIST given pathname
1408 */
1409
1410static VOID FillDirList(CHAR *str, UINT skiplen, BOOL recurse,
1411 FILELIST ***list, UINT *pnumfiles, UINT *pnumalloc)
1412{
1413 CHAR *enddir;
1414 ULONG x;
1415 CHAR *maskstr;
1416 PFILEFINDBUF4L pffbArray;
1417 PFILEFINDBUF4L pffbFile;
1418 HDIR hDir;
1419 ULONG ulFindCnt;
1420 ULONG ulBufBytes = sizeof(FILEFINDBUF4L) * FilesToGet;
1421 APIRET rc;
1422 static BOOL fDone;
1423
1424 if (!str || !*str) {
1425 Runtime_Error(pszSrcFile, __LINE__, NULL);
1426 return;
1427 }
1428
1429 // DbgMsg(pszSrcFile, __LINE__, "FillDirList start %s", str);
1430
1431 maskstr = xmalloc(CCHMAXPATH + 100, pszSrcFile, __LINE__);
1432 if (!maskstr)
1433 return;
1434 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
1435 if (!pffbArray) {
1436 free(maskstr);
1437 return;
1438 }
1439 x = strlen(str);
1440 memcpy(maskstr, str, x + 1);
1441 enddir = maskstr + x;
1442 if (*(enddir - 1) != '\\') {
1443 *enddir = '\\';
1444 enddir++;
1445 *enddir = 0;
1446 }
1447 *enddir = '*';
1448 *(enddir + 1) = 0;
1449 hDir = HDIR_CREATE;
1450 DosError(FERR_DISABLEHARDERR);
1451 ulFindCnt = FilesToGet;
1452 rc = xDosFindFirst(maskstr, &hDir,
1453 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
1454 FILE_SYSTEM | FILE_HIDDEN |
1455 (recurse ? FILE_DIRECTORY : 0),
1456 pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
1457 if (!rc) {
1458 do {
1459 pffbFile = pffbArray;
1460 for (x = 0; x < ulFindCnt; x++) {
1461 if (pffbFile->attrFile & FILE_DIRECTORY) {
1462 // Skip . and ..
1463 if (recurse &&
1464 (pffbFile->achName[0] != '.' ||
1465 (pffbFile->achName[1] &&
1466 (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
1467 if (fForceUpper)
1468 strupr(pffbFile->achName);
1469 else if (fForceLower)
1470 strlwr(pffbFile->achName);
1471 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1);
1472 FillDirList(maskstr, skiplen, recurse, list, pnumfiles, pnumalloc);
1473 }
1474 }
1475 else {
1476 if (fForceUpper)
1477 strupr(pffbFile->achName);
1478 else if (fForceLower)
1479 strlwr(pffbFile->achName);
1480 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1);
1481 if (strlen(maskstr) > CCHMAXPATH) {
1482 // Complain if pathnames exceeds max
1483 DosFindClose(hDir);
1484 free(pffbArray);
1485 free(maskstr);
1486 if (!fDone) {
1487 fDone = TRUE;
1488 saymsg(MB_OK | MB_ICONASTERISK,
1489 HWND_DESKTOP,
1490 GetPString(IDS_WARNINGTEXT),
1491 GetPString(IDS_LENGTHEXCEEDSMAXPATHTEXT));
1492 }
1493 return;
1494 }
1495 if (AddToFileList(maskstr + skiplen,
1496 pffbFile, list, pnumfiles, pnumalloc)) {
1497 goto Abort;
1498 }
1499 }
1500 pffbFile = (PFILEFINDBUF4L)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
1501 } // for
1502 DosError(FERR_DISABLEHARDERR);
1503 ulFindCnt = FilesToGet;
1504 rc = xDosFindNext(hDir, pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZEL);
1505 } while (!rc);
1506
1507Abort:
1508
1509 DosFindClose(hDir);
1510 DosSleep(0);
1511 }
1512
1513 if (rc && rc != ERROR_NO_MORE_FILES) {
1514 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
1515 GetPString(IDS_CANTFINDDIRTEXT), maskstr);
1516 }
1517
1518 xfree(maskstr, pszSrcFile, __LINE__);
1519 xfree(pffbArray, pszSrcFile, __LINE__);
1520
1521 // DbgMsg(pszSrcFile, __LINE__, "FillDirList finish %s", str);
1522}
1523
1524/**
1525 * Compare names for qsort
1526 */
1527
1528static int CompNames(const void *n1, const void *n2)
1529{
1530 FILELIST *fl1 = *(FILELIST **)n1;
1531 FILELIST *fl2 = *(FILELIST **)n2;
1532
1533 return stricmp(fl1->fname, fl2->fname);
1534}
1535
1536//=== FillCnrsThread() Fill left and right containers ===
1537
1538static VOID FillCnrsThread(VOID *args)
1539{
1540 COMPARE *cmp = (COMPARE *)args;
1541 HAB hab;
1542 HMQ hmq;
1543 BOOL notified = FALSE;
1544 ITIMER_DESC itdSleep = { 0 };
1545
1546 HWND hwndLeft, hwndRight;
1547 CHAR szBuf[CCHMAXPATH];
1548 CNRINFO cnri;
1549
1550# ifdef FORTIFY
1551 // 10 May 08 SHL fixme to suppress W111
1552 Fortify_EnterScope();
1553# endif
1554
1555 if (!cmp) {
1556 Runtime_Error(pszSrcFile, __LINE__, NULL);
1557# ifdef FORTIFY
1558 // 10 May 08 SHL fixme to suppress W111
1559 Fortify_LeaveScope();
1560# endif
1561 return; // 10 Dec 08 SHL was _endthread
1562 }
1563
1564 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread enter");
1565
1566 DosError(FERR_DISABLEHARDERR);
1567
1568 InitITimer(&itdSleep, 500); // Sleep every 500 mSec
1569
1570 hab = WinInitialize(0);
1571 if (!hab)
1572 Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__, "WinInitialize");
1573 else {
1574 hmq = WinCreateMsgQueue(hab, 0);
1575 if (!hmq)
1576 Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__,
1577 "WinCreateMsgQueue");
1578 else {
1579 INT x;
1580 UINT l;
1581 UINT r;
1582 // UINT cntr;
1583 FILELIST **filesl = NULL;
1584 FILELIST **filesr = NULL;
1585 UINT numallocl = 0;
1586 UINT numallocr = 0;
1587 INT ret = 0;
1588 UINT lenl; // Directory prefix length
1589 UINT lenr;
1590 UINT recsNeeded;
1591 UINT recsGotten;
1592 PCNRITEM pcilFirst;
1593 PCNRITEM pcirFirst;
1594 PCNRITEM pcilLast;
1595 PCNRITEM pcirLast;
1596 PCNRITEM pcil;
1597 PCNRITEM pcir;
1598 RECORDINSERT ri;
1599 CHAR *pch;
1600
1601 WinCancelShutdown(hmq, TRUE);
1602 IncrThreadUsage();
1603
1604 hwndLeft = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
1605 hwndRight = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
1606 lenl = strlen(cmp->leftdir);
1607 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
1608 lenl++;
1609 lenr = strlen(cmp->rightdir);
1610 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
1611 lenr++;
1612 priority_normal();
1613 // Clear containers
1614 RemoveCnrItems(hwndRight, NULL, 0, CMA_FREE | CMA_INVALIDATE);
1615 RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
1616 cmp->cmp->totalleft = 0;
1617 cmp->cmp->totalright = 0;
1618
1619 // Build list of all files in left directory
1620 if (fForceLower)
1621 strlwr(cmp->leftdir);
1622 else if (fForceUpper)
1623 strupr(cmp->leftdir);
1624 FillDirList(cmp->leftdir, lenl, cmp->includesubdirs,
1625 &filesl, &cmp->cmp->totalleft, &numallocl);
1626
1627 if (filesl)
1628 qsort(filesl, cmp->cmp->totalleft, sizeof(CHAR *), CompNames);
1629
1630 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread sorted filesl");
1631
1632 // Build list of all files in right directory
1633 if (!*cmp->rightlist) {
1634 if (fForceLower)
1635 strlwr(cmp->rightdir);
1636 else if (fForceUpper)
1637 strupr(cmp->rightdir);
1638 FillDirList(cmp->rightdir, lenr, cmp->includesubdirs,
1639 &filesr, &cmp->cmp->totalright, &numallocr);
1640 }
1641 else {
1642 // Use snapshot file
1643 FILE *fp;
1644 FILEFINDBUF4L fb4;
1645 CHAR str[CCHMAXPATH * 2], *p;
1646
1647 memset(&fb4, 0, sizeof(fb4));
1648 fp = fopen(cmp->rightlist, "r");
1649 if (!fp)
1650 Runtime_Error(pszSrcFile, __LINE__, "can not open %s (%d)",
1651 cmp->rightlist, errno);
1652 else {
1653 while (!feof(fp)) {
1654 // First get name of directory
1655 if (!xfgets_bstripcr(str, sizeof(str), fp, pszSrcFile, __LINE__))
1656 break; // EOF
1657 p = str;
1658 if (*p == '\"') {
1659 // Quoted
1660 p++;
1661 if (*p && *p != '\"') {
1662 p = strchr(p, '\"');
1663 if (p) {
1664 *p = 0;
1665 if (*(str + 1)) {
1666 strcpy(cmp->rightdir, str + 1);
1667 if (fForceUpper)
1668 strupr(cmp->rightdir);
1669 else if (fForceLower)
1670 strlwr(cmp->rightdir);
1671 p = cmp->rightdir + (strlen(cmp->rightdir) - 1);
1672 if (p - cmp->rightdir > 3 && *p == '\\')
1673 *p = 0; // Chop trailing slash
1674 break;
1675 }
1676 }
1677 }
1678 }
1679 } // while !EOF
1680
1681 memset(&cnri, 0, sizeof(cnri));
1682 cnri.cb = sizeof(cnri);
1683 cnri.pszCnrTitle = cmp->rightdir;
1684 if (!WinSendMsg(hwndRight, CM_SETCNRINFO,
1685 MPFROMP(&cnri), MPFROMLONG(CMA_CNRTITLE))) {
1686 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_SETCNRINFO");
1687 }
1688
1689 if (*cmp->rightdir) {
1690 lenr = strlen(cmp->rightdir);
1691 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
1692 lenr++;
1693 while (!feof(fp)) {
1694 if (!xfgets_bstripcr
1695 (str, sizeof(str), fp, pszSrcFile, __LINE__))
1696 break;
1697 p = str;
1698 if (*p == '\"') {
1699 p++;
1700 if (*p && *p != '\"') {
1701 p = strchr(p, '\"');
1702 if (p) {
1703 *p = 0;
1704 p++;
1705 if (*p == ',') {
1706 p++;
1707 if (!cmp->includesubdirs && atol(p) > lenr)
1708 continue;
1709 p = strchr(p, ',');
1710 if (p) {
1711 p++;
1712 // 27 Sep 07 SHL fixme to do ULONGLONG conversion
1713 fb4.cbFile = atol(p);
1714 p = strchr(p, ',');
1715 if (p) {
1716 p++;
1717 fb4.fdateLastWrite.year = atol(p) - 1980;
1718 p = strchr(p, '/');
1719 if (p) {
1720 p++;
1721 fb4.fdateLastWrite.month = atol(p);
1722 p = strchr(p, '/');
1723 if (p) {
1724 p++;
1725 fb4.fdateLastWrite.day = atol(p);
1726 p = strchr(p, ',');
1727 if (p) {
1728 p++;
1729 fb4.ftimeLastWrite.hours = atol(p);
1730 p = strchr(p, ':');
1731 if (p) {
1732 p++;
1733 fb4.ftimeLastWrite.minutes = atol(p);
1734 p = strchr(p, ':');
1735 if (p) {
1736 p++;
1737 fb4.ftimeLastWrite.twosecs = atol(p);
1738 p = strchr(p, ',');
1739 if (p) {
1740 p++;
1741 fb4.attrFile = atol(p);
1742 p = strchr(p, ',');
1743 if (p) {
1744 p++;
1745 fb4.cbList = atol(p) * 2;
1746 if (fForceUpper)
1747 strupr(str + 1);
1748 else if (fForceLower)
1749 strlwr(str + 1);
1750 if (AddToFileList((str + 1) + lenr,
1751 &fb4,
1752 &filesr,
1753 &cmp->cmp->totalright,
1754 &numallocr))
1755 break;
1756 }
1757 }
1758 }
1759 }
1760 }
1761 }
1762 }
1763 }
1764 }
1765 }
1766 }
1767 }
1768 }
1769 } // while
1770 } // if have rightdir
1771 fclose(fp);
1772 }
1773 } // if snapshot file
1774
1775 if (filesr)
1776 qsort(filesr, cmp->cmp->totalright, sizeof(CHAR *), CompNames);
1777
1778 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread sorted filesr");
1779
1780 // We now have two lists of files, both sorted.
1781 // Count total number of container entries required on each side
1782 l = r = 0;
1783 recsNeeded = 0;
1784 while ((filesl && filesl[l]) || (filesr && filesr[r])) {
1785
1786 if (filesl && filesl[l]) {
1787 if (filesr && filesr[r])
1788 x = stricmp(filesl[l]->fname, filesr[r]->fname);
1789 else
1790 x = -1; // Left side list longer
1791 }
1792 else
1793 x = +1; // Right side list longer
1794
1795 if (x <= 0)
1796 l++; // On left side
1797 if (x >= 0)
1798 r++; // On right side
1799
1800 recsNeeded++; // Keep count of how many entries req'd
1801
1802 } // while
1803
1804 // Say building list - fixme to post?
1805 WinSendMsg(cmp->hwnd, UM_CONTAINERHWND, MPVOID, MPVOID);
1806
1807 // Now insert records into the containers
1808 if (recsNeeded) {
1809 pcilFirst = WinSendMsg(hwndLeft,
1810 CM_ALLOCRECORD,
1811 MPFROMLONG(EXTRA_RECORD_BYTES),
1812 MPFROMLONG(recsNeeded));
1813 if (!pcilFirst) {
1814 Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
1815 recsNeeded = 0;
1816 }
1817 }
1818 if (recsNeeded) {
1819 pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
1820 MPFROMLONG(EXTRA_RECORD_BYTES),
1821 MPFROMLONG(recsNeeded));
1822 if (!pcirFirst) {
1823 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
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.