source: trunk/dll/comp.c@ 1063

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

Fortify ifdef reformat

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