source: trunk/dll/comp.c@ 1157

Last change on this file since 1157 was 1157, checked in by John Small, 17 years ago

Ticket 187: Draft 1: Functions only

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