source: trunk/dll/comp.c@ 1132

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

Point pci fields at NullStr to sync with FreeCnrItemData mods

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