source: trunk/dll/comp.c@ 929

Last change on this file since 929 was 929, checked in by Steven Levine, 18 years ago

Compare directories rework.
Change hide not selected to 3 state checkbox.
Honor filters in actions.
Do all total and select count updates on WM_TIMER.

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