source: trunk/dll/comp.c@ 1304

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

Move DosEnterCritSec into SetMask Replace 2 more with semaphore(Ticket 308)

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