source: trunk/dll/comp.c@ 1175

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

Avoid aliased pszLongName pointer in ActionCnrThread IDM_MOVE

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