source: trunk/dll/comp.c@ 1009

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

Add xfree xstrdup Fortify support
Add MT capable Fortify scope logic

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