source: trunk/dll/comp.c@ 1335

Last change on this file since 1335 was 1335, checked in by Steven Levine, 17 years ago

Ticket 26: Add exception handlers to all threads using xbeginthread

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