source: trunk/dll/comp.c@ 783

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

Rework DosFindFirst/Next loops to optimize memory allocation and code paths
Adjust FilesToGet limits
Update configuration notebook scanning page
Start updating #pragma alloc_text positioning for OpenWatcom compatibility

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 74.9 KB
Line 
1
2/***********************************************************************
3
4 $Id: comp.c 783 2007-08-14 04:09:54Z stevenhl $
5
6 Compare directories
7
8 Copyright (c) 1993-02 M. Kimes
9 Copyright (c) 2003, 2007 Steven H. Levine
10
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
15 24 May 05 SHL Rework for CNRITEM.szSubject
16 25 May 05 SHL Rework with ULONGLONG
17 06 Jun 05 SHL Drop unused
18 12 Jul 06 SHL Renames and comments
19 13 Jul 06 SHL Use Runtime_Error
20 26 Jul 06 SHL Drop unreachable CN_... code
21 29 Jul 06 SHL Use xfgets_bstripcr
22 15 Aug 06 SHL Turn off hide not selected on dir change
23 19 Oct 06 SHL Correct . and .. detect
24 03 Nov 06 SHL Count thread usage
25 22 Mar 07 GKY Use QWL_USER
26 29 Jul 07 SHL Use Win_Error to report container errors
27 01 Aug 07 SHL Rework to sync with CNRITEM mods
28 01 Aug 07 SHL Rework to remove vast amount of duplicate code
29 03 Aug 07 GKY Enlarged and made setable everywhere Findbuf (speed file loading)
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
32 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
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
35
36***********************************************************************/
37
38#define INCL_DOS
39#define INCL_WIN
40#define INCL_DOSERRORS
41#define INCL_GPI
42#define INCL_LONGLONG
43#include <os2.h>
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <ctype.h>
49#include <share.h>
50#include <io.h>
51#include <process.h> // _beginthread
52
53#include "fm3dll.h"
54#include "fm3dlg.h"
55#include "fm3str.h"
56
57typedef struct
58{
59 CHAR filename[CCHMAXPATH];
60 CHAR dirname[CCHMAXPATH];
61 BOOL recurse;
62}
63SNAPSTUFF;
64
65static PSZ pszSrcFile = __FILE__;
66
67/**
68 * Build full path name in callers buffer given directory
69 * name and filename
70 * @param pszPathName points to drive/directory if not NULL
71 * @returns pointer to full path name in caller's buffer
72 * @note OK for pszFullPathName and pszPathName to point to same buffer
73 *
74 */
75
76PSZ BldFullPathName(PSZ pszFullPathName, PSZ pszPathName, PSZ pszFileName)
77{
78 UINT c = pszPathName ? strlen(pszPathName) : 0;
79 if (c > 0) {
80 memcpy(pszFullPathName, pszPathName, c);
81 if (pszFullPathName[c - 1] != '\\')
82 pszFullPathName[c++] = '\\';
83 }
84 strcpy(pszFullPathName + c, pszFileName);
85 return pszFullPathName;
86}
87
88//=== SnapShot() Write directory tree to file and recurse if requested ===
89
90static VOID SnapShot(char *path, FILE *fp, BOOL recurse)
91{
92 PFILEFINDBUF4 pffb;
93 char *mask, *enddir;
94 HDIR hdir = HDIR_CREATE;
95 ULONG ulFindCnt;
96
97 // 13 Aug 07 SHL fimxe to use FileToGet
98 pffb = xmalloc(sizeof(FILEFINDBUF4), pszSrcFile, __LINE__);
99 if (pffb) {
100 mask = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
101 if (mask) {
102 BldFullPathName(mask, path, "*");
103 // sprintf(mask,
104 // "%s%s*",
105 // path, (path[strlen(path) - 1] != '\\') ? "\\" : NullStr);
106 enddir = strrchr(mask, '\\');
107 enddir++;
108 ulFindCnt = 1;
109 // 13 Aug 07 SHL fixme to report errors
110 if (!DosFindFirst(mask,
111 &hdir,
112 FILE_NORMAL | FILE_DIRECTORY |
113 FILE_ARCHIVED | FILE_READONLY | FILE_HIDDEN |
114 FILE_SYSTEM,
115 pffb, sizeof(FILEFINDBUF4), &ulFindCnt, FIL_QUERYEASIZE)) {
116 do {
117 strcpy(enddir, pffb->achName);
118 if (!(pffb->attrFile & FILE_DIRECTORY))
119 fprintf(fp,
120 "\"%s\",%u,%lu,%04u/%02u/%02u,%02u:%02u:%02u,%lu,%lu,N\n",
121 mask,
122 enddir - mask,
123 pffb->cbFile,
124 (pffb->fdateLastWrite.year + 1980),
125 pffb->fdateLastWrite.month,
126 pffb->fdateLastWrite.day,
127 pffb->ftimeLastWrite.hours,
128 pffb->ftimeLastWrite.minutes,
129 pffb->ftimeLastWrite.twosecs,
130 pffb->attrFile, (pffb->cbList > 4) ? (pffb->cbList / 2) : 0);
131 // Skip . and ..
132 else if (recurse &&
133 (pffb->achName[0] != '.' ||
134 (pffb->achName[1] &&
135 (pffb->achName[1] != '.' || pffb->achName[2])))) {
136 SnapShot(mask, fp, recurse);
137 }
138 ulFindCnt = 1;
139 } while (!DosFindNext(hdir, pffb, sizeof(FILEFINDBUF4), &ulFindCnt));
140 DosFindClose(hdir);
141 }
142 free(mask);
143 }
144 free(pffb);
145 }
146}
147
148//=== StartSnap() Write directory tree to snapshot file ===
149
150static VOID StartSnap(VOID * dummy)
151{
152 SNAPSTUFF *sf = (SNAPSTUFF *) dummy;
153 FILE *fp;
154 CHAR *p;
155
156 if (sf) {
157 if (*sf->dirname && *sf->filename) {
158 priority_normal();
159 p = sf->dirname;
160 while (*p) {
161 if (*p == '/')
162 *p = '\\';
163 p++;
164 }
165 if (*(p - 1) != '\\') {
166 *p = '\\';
167 p++;
168 }
169 fp = xfopen(sf->filename, "w", pszSrcFile, __LINE__);
170 if (fp) {
171 fprintf(fp, "\"%s\"\n", sf->dirname);
172 SnapShot(sf->dirname, fp, sf->recurse);
173 fclose(fp);
174 }
175 }
176 free(sf);
177 }
178}
179
180//=== CompareFilesThread() Compare files and update container select flags ===
181
182static VOID CompareFilesThread(VOID * args)
183{
184 FCOMPARE fc;
185 HAB hab2;
186 HMQ hmq2;
187 FILE *fp1, *fp2;
188 ULONG len1, len2, offset = 0L;
189 LONG numread1, numread2;
190 CHAR s[1024], ss[1024], *p1, *p2;
191
192 if (args) {
193 fc = *(FCOMPARE *) args;
194 hab2 = WinInitialize(0);
195 if (hab2) {
196 hmq2 = WinCreateMsgQueue(hab2, 0);
197 if (hmq2) {
198 WinCancelShutdown(hmq2, TRUE);
199 IncrThreadUsage();
200 if (!IsFile(fc.file1) || IsRoot(fc.file1)) {
201 p1 = strrchr(fc.file2, '\\');
202 if (p1) {
203 if (fc.file1[strlen(fc.file1) - 1] == '\\')
204 p1++;
205 strcat(fc.file1, p1);
206 }
207 }
208 else if (!IsFile(fc.file2) || IsRoot(fc.file2)) {
209 p1 = strrchr(fc.file1, '\\');
210 if (p1) {
211 if (fc.file2[strlen(fc.file2) - 1] == '\\')
212 p1++;
213 strcat(fc.file2, p1);
214 }
215 }
216 sprintf(s, GetPString(IDS_COMPCOMPARETEXT), fc.file1);
217 AddToListboxBottom(fc.hwndList, s);
218 sprintf(s, GetPString(IDS_COMPTOTEXT), fc.file2);
219 AddToListboxBottom(fc.hwndList, s);
220 fp1 = _fsopen(fc.file1, "rb", SH_DENYNO);
221 if (!fp1) {
222 sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file1);
223 AddToListboxBottom(fc.hwndList, s);
224 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
225 }
226 else {
227 fp2 = _fsopen(fc.file2, "rb", SH_DENYNO);
228 if (!fp2) {
229 sprintf(s, GetPString(IDS_COMPCANTOPENTEXT), fc.file2);
230 AddToListboxBottom(fc.hwndList, s);
231 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
232 }
233 else {
234 len1 = filelength(fileno(fp1));
235 len2 = filelength(fileno(fp2));
236 if (len1 != len2) {
237 strcpy(s, GetPString(IDS_COMPDIFSIZESTEXT));
238 AddToListboxBottom(fc.hwndList, s);
239 sprintf(s, GetPString(IDS_COMPVSBYTESTEXT), len1, len2);
240 AddToListboxBottom(fc.hwndList, s);
241 WinSetWindowText(fc.hwndHelp,
242 GetPString(IDS_COMPDONTMATCHTEXT));
243 }
244 else {
245 WinSetWindowText(fc.hwndHelp,
246 GetPString(IDS_COMPCOMPARINGTEXT));
247 while (WinIsWindow(hab2, fc.hwndList)) {
248 numread1 = fread(s, 1, 1024, fp1);
249 numread2 = fread(ss, 1, 1024, fp2);
250 if (numread1 != numread2 || feof(fp1) != feof(fp2)) {
251 sprintf(s, GetPString(IDS_COMPREADERRORTEXT),
252 offset, offset);
253 AddToListboxBottom(fc.hwndList, s);
254 WinSetWindowText(fc.hwndHelp, GetPString(IDS_ERRORTEXT));
255 break;
256 }
257 else if (!numread1 && feof(fp1) && feof(fp2)) {
258 AddToListboxBottom(fc.hwndList,
259 GetPString(IDS_COMPFILESMATCHTEXT));
260 if (!stricmp(fc.file1, fc.file2))
261 AddToListboxBottom(fc.hwndList,
262 GetPString(IDS_COMPWONDERWHYTEXT));
263 WinSetWindowText(fc.hwndHelp,
264 GetPString(IDS_COMPCOMPLETETEXT));
265 break;
266 }
267 else if (numread1 <= 0 || numread2 <= 0) {
268 if (offset == len1)
269 break;
270 else {
271 sprintf(s, GetPString(IDS_COMPMATCHREADERRORTEXT),
272 offset, offset);
273 WinSetWindowText(fc.hwndHelp,
274 GetPString(IDS_COMPODDERRORTEXT));
275 AddToListboxBottom(fc.hwndList, s);
276 break;
277 }
278 }
279 else if (memcmp(s, ss, numread1)) {
280 p1 = s;
281 p2 = ss;
282 while (p1 < s + numread1) {
283 if (*p1 != *p2) {
284 sprintf(s, GetPString(IDS_COMPMISMATCHERRORTEXT),
285 offset + (p1 - s), offset + (p1 - s));
286 AddToListboxBottom(fc.hwndList, s);
287 WinSetWindowText(fc.hwndHelp,
288 GetPString(IDS_COMPDONTMATCHTEXT));
289 break;
290 }
291 p1++;
292 p2++;
293 }
294 break;
295 }
296 offset += numread1;
297 }
298 }
299 fclose(fp2);
300 }
301 fclose(fp1);
302 }
303 DecrThreadUsage();
304 WinDestroyMsgQueue(hmq2);
305 }
306 WinTerminate(hab2);
307 }
308 }
309}
310
311//=== CFileDlgProc() Select directories to compare dialog procedure ===
312
313MRESULT EXPENTRY CFileDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
314{
315 FCOMPARE *fc;
316
317 switch (msg) {
318 case WM_INITDLG:
319 if (!mp2)
320 WinDismissDlg(hwnd, 0);
321 else {
322 WinSetWindowPtr(hwnd, QWL_USER, mp2);
323 fc = (FCOMPARE *) mp2;
324 fc->hwndReport = hwnd;
325 fc->hwndList = WinWindowFromID(hwnd, FCMP_LISTBOX);
326 fc->hwndHelp = WinWindowFromID(hwnd, FCMP_HELP);
327 if (!*fc->file1 || !fc->file2) {
328 WinDismissDlg(hwnd, 0);
329 break;
330 }
331 MakeFullName(fc->file1);
332 MakeFullName(fc->file2);
333 if (!stricmp(fc->file1, fc->file2)) {
334 saymsg(MB_CANCEL, hwnd,
335 GetPString(IDS_COMPSILLYALERTTEXT),
336 GetPString(IDS_COMPTOITSELFTEXT));
337 WinDismissDlg(hwnd, 0);
338 break;
339 }
340 if (_beginthread(CompareFilesThread, NULL, 65536, (PVOID) fc) == -1) {
341 Runtime_Error(pszSrcFile, __LINE__,
342 GetPString(IDS_COULDNTSTARTTHREADTEXT));
343 WinDismissDlg(hwnd, 0);
344 }
345 }
346 break;
347
348 case WM_ADJUSTWINDOWPOS:
349 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
350 break;
351
352 case UM_SETDIR:
353 PaintRecessedWindow(WinWindowFromID(hwnd, FCMP_HELP),
354 (HPS) 0, FALSE, TRUE);
355 return 0;
356
357 case WM_COMMAND:
358 switch (SHORT1FROMMP(mp1)) {
359 case DID_OK:
360 WinDismissDlg(hwnd, 0);
361 break;
362 case DID_CANCEL:
363 WinDismissDlg(hwnd, 1);
364 break;
365 }
366 return 0;
367
368 case WM_DESTROY:
369 DosSleep(50);//05 Aug 07 GKY 100
370 break;
371 }
372 return WinDefDlgProc(hwnd, msg, mp1, mp2);
373}
374
375//=== ActionCnrThread() Do requested action on container contents ===
376
377static VOID ActionCnrThread(VOID *args)
378{
379 COMPARE *cmp = (COMPARE *)args;
380 HAB hab;
381 HMQ hmq;
382 HWND hwndCnrS, hwndCnrD;
383 PCNRITEM pci, pciD, pciNextS, pciNextD;
384 CHAR szNewName[CCHMAXPATH], szDirName[CCHMAXPATH], *p;
385 APIRET rc;
386
387 if (!cmp) {
388 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
389 return;
390 }
391
392 DosError(FERR_DISABLEHARDERR);
393
394 hab = WinInitialize(0);
395 if (hab) {
396 hmq = WinCreateMsgQueue(hab, 0);
397 if (hmq) {
398 WinCancelShutdown(hmq, TRUE);
399 IncrThreadUsage();
400 priority_normal();
401 switch (cmp->action) {
402 case COMP_DELETELEFT:
403 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
404 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
405 cmp->action = IDM_DELETE;
406 break;
407 case COMP_DELETERIGHT:
408 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
409 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
410 cmp->action = IDM_DELETE;
411 break;
412 case COMP_MOVELEFT:
413 cmp->action = IDM_MOVE;
414 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
415 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
416 break;
417 case COMP_MOVERIGHT:
418 cmp->action = IDM_MOVE;
419 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
420 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
421 break;
422 case COMP_COPYLEFT:
423 cmp->action = IDM_COPY;
424 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
425 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
426 break;
427 case COMP_COPYRIGHT:
428 cmp->action = IDM_COPY;
429 hwndCnrS = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
430 hwndCnrD = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
431 break;
432 default:
433 Runtime_Error(pszSrcFile, __LINE__, "bad case %u", cmp->action);
434 goto Abort;
435 }
436
437 pci = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPVOID,
438 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
439 pciD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPVOID,
440 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
441
442 while (pci && (INT)pci != -1 && pciD && (INT)pciD != -1) {
443
444 pciNextS = WinSendMsg(hwndCnrS, CM_QUERYRECORD, MPFROMP(pci),
445 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
446 pciNextD = WinSendMsg(hwndCnrD, CM_QUERYRECORD, MPFROMP(pciD),
447 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
448
449 if (*pci->pszFileName && pci->rc.flRecordAttr & CRA_SELECTED) {
450
451 // Source name not blank
452 switch (cmp->action) {
453 case IDM_DELETE:
454 if (!unlinkf("%s", pci->pszFileName)) {
455 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pci),
456 MPFROM2SHORT(FALSE, CRA_SELECTED));
457
458 if (!*pciD->pszFileName) {
459 // Other side is blank - remove from both sides
460 RemoveCnrItems(hwndCnrS, pci, 1, CMA_FREE | CMA_INVALIDATE);
461 if (pciD->rc.flRecordAttr & CRA_SELECTED)
462 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
463 MPFROM2SHORT(FALSE, CRA_SELECTED));
464 RemoveCnrItems(hwndCnrD, pciD, 1, CMA_FREE | CMA_INVALIDATE);
465 }
466 else {
467 // Other side is not blank - update just this side
468 FreeCnrItemData(pci);
469 pci->pszDisplayName = pci->pszFileName;
470 pci->rc.pszIcon = pci->pszFileName;
471 pci->flags = 0;
472 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pci),
473 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
474 }
475 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_LEFTDIR))
476 cmp->cmp->totalleft--;
477 else
478 cmp->cmp->totalright--;
479 DosSleep(1);
480 }
481 break;
482
483 case IDM_MOVE:
484 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
485 BldFullPathName(szNewName, cmp->leftdir, pci->pszDisplayName);
486 //sprintf(szNewName, "%s%s%s",
487 // cmp->leftdir,
488 // cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\' ?
489 // NullStr : "\\",
490 // pci->pszDisplayName);
491 else
492 BldFullPathName(szNewName, cmp->rightdir, pci->pszDisplayName);
493 //sprintf(szNewName, "%s%s%s",
494 // cmp->rightdir,
495 // cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\' ?
496 // NullStr : "\\",
497 // pci->pszDisplayName);
498 // Make directory if required
499 strcpy(szDirName, szNewName);
500 p = strrchr(szDirName, '\\');
501 if (p) {
502 if (p > szDirName + 2)
503 p++;
504 *p = 0;
505 if (IsFile(szDirName) == -1)
506 MassMkdir(hwndMain, szDirName);
507 }
508 rc = docopyf(MOVE, pci->pszFileName, "%s", szNewName);
509 if (!rc && stricmp(pci->pszFileName, szNewName)) {
510 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pci),
511 MPFROM2SHORT(FALSE, CRA_SELECTED));
512 if (pciD->rc.flRecordAttr & CRA_SELECTED)
513 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
514 MPFROM2SHORT(FALSE, CRA_SELECTED));
515 FreeCnrItemData(pciD);
516 pciD->pszFileName = xstrdup(szNewName, pszSrcFile, __LINE__);
517 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
518 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
519 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
520 pciD->pszDisplayName++;
521 }
522 else {
523 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
524 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
525 pciD->pszDisplayName++;
526 }
527 // 02 Aug 07 SHL fixme to know if LongName transfer is correct?
528 pciD->pszLongName = pci->pszLongName;
529 if (pciD->pszSubject != NullStr) {
530 xfree(pciD->pszSubject);
531 pciD->pszSubject = NullStr;
532 }
533 pciD->attrFile = pci->attrFile;
534 pciD->pszDispAttr = pci->pszDispAttr;
535 pciD->flags = 0; // Just on one side
536 pciD->date = pci->date;
537 pciD->time = pci->time;
538 pciD->ladate = pci->ladate;
539 pciD->latime = pci->latime;
540 pciD->crdate = pci->crdate;
541 pciD->crtime = pci->crtime;
542 pciD->cbFile = pci->cbFile;
543 pciD->easize = pci->easize;
544
545 if (pci->pszFileName != NullStr) {
546 xfree(pci->pszFileName);
547 pci->pszFileName = NullStr;
548 pci->pszDisplayName = pci->pszFileName;
549 pci->rc.pszIcon = pci->pszFileName;
550 }
551 if (pci->pszSubject != NullStr) {
552 xfree(pci->pszSubject);
553 pci->pszSubject = NullStr;
554 }
555 pci->flags = 0;
556
557 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pci),
558 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
559 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
560 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
561 }
562 else if (rc) {
563 rc = Dos_Error(MB_ENTERCANCEL,
564 rc,
565 HWND_DESKTOP,
566 pszSrcFile,
567 __LINE__,
568 GetPString(IDS_COMPMOVEFAILEDTEXT),
569 pci->pszFileName, szNewName);
570 if (rc == MBID_CANCEL) // Cause loop to break
571 pciNextS = NULL;
572 }
573 break;
574
575 case IDM_COPY:
576 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR))
577 BldFullPathName(szNewName, cmp->leftdir, pci->pszDisplayName);
578 //sprintf(szNewName, "%s%s%s",
579 // cmp->leftdir,
580 // cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\' ?
581 // NullStr : "\\",
582 // pci->pszDisplayName);
583 else
584 BldFullPathName(szNewName, cmp->rightdir, pci->pszDisplayName);
585 //sprintf(szNewName, "%s%s%s",
586 // cmp->rightdir,
587 // cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\' ?
588 // NullStr : "\\",
589 // pci->pszDisplayName);
590 // Make directory if required
591 strcpy(szDirName, szNewName);
592 p = strrchr(szDirName, '\\');
593 if (p) {
594 if (p > szDirName + 2)
595 p++;
596 *p = 0;
597 if (IsFile(szDirName) == -1)
598 MassMkdir(hwndMain, szDirName);
599 }
600 rc = docopyf(COPY, pci->pszFileName, "%s", szNewName);
601 if (rc) {
602 rc = Dos_Error(MB_ENTERCANCEL,
603 rc,
604 HWND_DESKTOP,
605 pszSrcFile,
606 __LINE__,
607 GetPString(IDS_COMPCOPYFAILEDTEXT),
608 pci->pszFileName, szNewName);
609 if (rc == MBID_CANCEL)
610 pciNextS = NULL; // Cause loop to break
611 }
612 else {
613 WinSendMsg(hwndCnrS, CM_SETRECORDEMPHASIS, MPFROMP(pci),
614 MPFROM2SHORT(FALSE, CRA_SELECTED));
615 if (pciD->rc.flRecordAttr & CRA_SELECTED)
616 WinSendMsg(hwndCnrD, CM_SETRECORDEMPHASIS, MPFROMP(pciD),
617 MPFROM2SHORT(FALSE, CRA_SELECTED));
618 FreeCnrItemData(pciD);
619 pciD->pszFileName = xstrdup(szNewName, pszSrcFile, __LINE__);
620 if (hwndCnrS == WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR)) {
621 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->leftdir);
622 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
623 pciD->pszDisplayName++;
624 }
625 else {
626 pciD->pszDisplayName = pciD->pszFileName + strlen(cmp->rightdir);
627 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
628 pciD->pszDisplayName++;
629 }
630 pciD->attrFile = pci->attrFile;
631 pciD->pszDispAttr = pci->pszDispAttr;
632 pciD->flags = CNRITEM_EXISTS; // Now on both sides
633 pciD->date = pci->date;
634 pciD->time = pci->time;
635 pciD->ladate = pci->ladate;
636 pciD->latime = pci->latime;
637 pciD->crdate = pci->crdate;
638 pciD->crtime = pci->crtime;
639 pciD->cbFile = pci->cbFile;
640 pciD->easize = pci->easize;
641
642 // Forget status until we regenerate it
643 if (pci->pszSubject != NullStr) {
644 xfree(pci->pszSubject);
645 pci->pszSubject = NullStr;
646 }
647 pci->flags = CNRITEM_EXISTS;
648
649 WinSendMsg(hwndCnrS, CM_INVALIDATERECORD, MPFROMP(&pci),
650 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
651 WinSendMsg(hwndCnrD, CM_INVALIDATERECORD, MPFROMP(&pciD),
652 MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
653 }
654 break;
655
656 default:
657 break;
658 } // switch
659
660 } // if have name
661
662 pci = pciNextS;
663 pciD = pciNextD;
664
665 } // while
666 Abort:
667 WinDestroyMsgQueue(hmq);
668 }
669 DecrThreadUsage();
670 WinTerminate(hab);
671 }
672 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID);
673 PostMsg(cmp->hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DESELECTALL, 0), MPVOID);
674 free(cmp);
675}
676
677//=== SelectCnrsThread() Update container selection flags thread ===
678
679static VOID SelectCnrsThread(VOID * args)
680{
681 COMPARE *cmp = (COMPARE *) args;
682 HAB hab;
683 HMQ hmq;
684
685 if (!cmp) {
686 Runtime_Error(pszSrcFile, __LINE__, "no data");
687 return;
688 }
689
690 DosError(FERR_DISABLEHARDERR);
691
692 hab = WinInitialize(0);
693 if (hab) {
694 hmq = WinCreateMsgQueue(hab, 0);
695 if (hmq) {
696 WinCancelShutdown(hmq, TRUE);
697 IncrThreadUsage();
698 priority_normal();
699 switch (cmp->action) {
700 case IDM_INVERT:
701 InvertAll(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
702 InvertAll(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
703 break;
704
705 case IDM_DESELECTALL:
706 Deselect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR));
707 Deselect(WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR));
708 break;
709
710 default:
711 SpecialSelect(WinWindowFromID(cmp->hwnd, COMP_LEFTDIR),
712 WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR),
713 cmp->action, cmp->reset);
714 break;
715 }
716 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID))
717 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID);
718 WinDestroyMsgQueue(hmq);
719 }
720 DecrThreadUsage();
721 WinTerminate(hab);
722 }
723 free(cmp);
724}
725
726/**
727 * Build FILELIST given pathname
728 */
729
730static VOID FillDirList(CHAR *str, INT skiplen, BOOL recurse,
731 FILELIST ***list, INT *numfiles, INT *numalloc)
732{
733 CHAR *enddir;
734 ULONG x;
735 CHAR *maskstr;
736 PFILEFINDBUF4 pffbArray;
737 PFILEFINDBUF4 pffbFile;
738 HDIR hDir;
739 ULONG ulFindCnt;
740 ULONG ulBufBytes = sizeof(FILEFINDBUF4) * FilesToGet;
741 APIRET rc;
742
743 if (!str || !*str) {
744 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
745 return;
746 }
747
748 maskstr = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
749 if (!maskstr)
750 return;
751 pffbArray = xmalloc(ulBufBytes, pszSrcFile, __LINE__);
752 if (!pffbArray) {
753 free(maskstr);
754 return;
755 }
756 x = strlen(str);
757 memcpy(maskstr, str, x + 1);
758 enddir = maskstr + x;
759 if (*(enddir - 1) != '\\') {
760 *enddir = '\\';
761 enddir++;
762 *enddir = 0;
763 }
764 *enddir = '*';
765 *(enddir + 1) = 0;
766 hDir = HDIR_CREATE;
767 DosError(FERR_DISABLEHARDERR);
768 ulFindCnt = FilesToGet;
769 rc = DosFindFirst(maskstr, &hDir,
770 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED |
771 FILE_SYSTEM | FILE_HIDDEN |
772 (recurse ? FILE_DIRECTORY : 0),
773 pffbArray, ulBufBytes, &ulFindCnt, FIL_QUERYEASIZE);
774 if (!rc) {
775 do {
776 pffbFile = pffbArray;
777 for (x = 0; x < ulFindCnt; x++) {
778 if (pffbFile->attrFile & FILE_DIRECTORY) {
779 // Skip . and ..
780 if (recurse &&
781 (pffbFile->achName[0] != '.' ||
782 (pffbFile->achName[1] &&
783 (pffbFile->achName[1] != '.' || pffbFile->achName[2])))) {
784 if (fForceUpper)
785 strupr(pffbFile->achName);
786 else if (fForceLower)
787 strlwr(pffbFile->achName);
788 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1);
789 FillDirList(maskstr, skiplen, recurse, list, numfiles, numalloc);
790 }
791 }
792 else {
793 if (fForceUpper)
794 strupr(pffbFile->achName);
795 else if (fForceLower)
796 strlwr(pffbFile->achName);
797 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1);
798 if (AddToFileList(maskstr + skiplen,
799 pffbFile, list, numfiles, numalloc)) {
800 goto Abort;
801 }
802 }
803 pffbFile = (PFILEFINDBUF4)((PBYTE)pffbFile + pffbFile->oNextEntryOffset);
804 } // for
805 DosError(FERR_DISABLEHARDERR);
806 ulFindCnt = FilesToGet;
807 rc = DosFindNext(hDir, pffbArray, ulBufBytes, &ulFindCnt);
808 } while (!rc);
809
810Abort:
811
812 DosFindClose(hDir);
813 DosSleep(1);
814 }
815
816 if (rc && rc != ERROR_NO_MORE_FILES) {
817 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
818 GetPString(IDS_CANTFINDDIRTEXT), maskstr);
819 }
820
821 free(maskstr);
822 free(pffbArray);
823}
824
825//=== CompNames() Compare names for qsort ===
826
827static int CompNames(const void *n1, const void *n2)
828{
829 FILELIST *fl1 = *(FILELIST **) n1;
830 FILELIST *fl2 = *(FILELIST **) n2;
831
832 return stricmp(fl1->fname, fl2->fname);
833}
834
835//=== FillCnrsThread() Fill left and right containers ===
836
837static VOID FillCnrsThread(VOID *args)
838{
839 COMPARE *cmp = (COMPARE *) args;
840 HAB hab;
841 HMQ hmq;
842 BOOL notified = FALSE;
843
844 HWND hwndLeft, hwndRight;
845 CHAR szBuf[CCHMAXPATH];
846 CNRINFO cnri;
847
848 if (!cmp) {
849 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
850 _endthread();
851 }
852
853 DosError(FERR_DISABLEHARDERR);
854
855 hab = WinInitialize(0);
856 if (!hab)
857 Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__, "WinInitialize");
858 else {
859 hmq = WinCreateMsgQueue(hab, 0);
860 if (!hmq)
861 Win_Error(NULLHANDLE, NULLHANDLE, pszSrcFile, __LINE__,
862 "WinCreateMsgQueue");
863 else {
864 INT x;
865 INT l;
866 INT r;
867 ULONG cntr;
868 FILELIST **filesl = NULL;
869 FILELIST **filesr = NULL;
870 INT numfilesl = 0;
871 INT numfilesr = 0;
872 INT numallocl = 0;
873 INT numallocr = 0;
874 UINT lenl; // Directory prefix length
875 UINT lenr;
876 UINT recsNeeded;
877 PCNRITEM pcilFirst;
878 PCNRITEM pcirFirst;
879 PCNRITEM pcil;
880 PCNRITEM pcir;
881 RECORDINSERT ri;
882 CHAR *pch;
883
884 WinCancelShutdown(hmq, TRUE);
885 IncrThreadUsage();
886 hwndLeft = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
887 hwndRight = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
888 lenl = strlen(cmp->leftdir);
889 if (cmp->leftdir[strlen(cmp->leftdir) - 1] != '\\')
890 lenl++;
891 lenr = strlen(cmp->rightdir);
892 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
893 lenr++;
894 priority_normal();
895 // Clear containers
896 RemoveCnrItems(hwndRight, NULL, 0, CMA_FREE | CMA_INVALIDATE);
897 RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
898 cmp->cmp->totalleft = cmp->cmp->totalright = 0;
899
900 // Build list of all files in left directory
901 if (fForceLower)
902 strlwr(cmp->leftdir);
903 else if (fForceUpper)
904 strupr(cmp->leftdir);
905 FillDirList(cmp->leftdir, lenl, cmp->includesubdirs,
906 &filesl, &numfilesl, &numallocl);
907
908 if (filesl)
909 qsort(filesl, numfilesl, sizeof(CHAR *), CompNames);
910
911 // Build list of all files in right directory
912 if (!*cmp->rightlist) {
913 if (fForceLower)
914 strlwr(cmp->rightdir);
915 else if (fForceUpper)
916 strupr(cmp->rightdir);
917 FillDirList(cmp->rightdir, lenr, cmp->includesubdirs,
918 &filesr, &numfilesr, &numallocr);
919 }
920 else {
921 // Use snapshot file
922 FILE *fp;
923 FILEFINDBUF4 fb4;
924 CHAR str[CCHMAXPATH * 2], *p;
925
926 memset(&fb4, 0, sizeof(fb4));
927 fp = fopen(cmp->rightlist, "r");
928 if (!fp)
929 Runtime_Error(pszSrcFile, __LINE__, "can not open %s (%d)",
930 cmp->rightlist, errno);
931 else {
932 while (!feof(fp)) {
933 // First get name of directory
934 if (!xfgets_bstripcr(str, sizeof(str), fp, pszSrcFile, __LINE__))
935 break; // EOF
936 p = str;
937 if (*p == '\"') {
938 // Quoted
939 p++;
940 if (*p && *p != '\"') {
941 p = strchr(p, '\"');
942 if (p) {
943 *p = 0;
944 if (*(str + 1)) {
945 strcpy(cmp->rightdir, str + 1);
946 if (fForceUpper)
947 strupr(cmp->rightdir);
948 else if (fForceLower)
949 strlwr(cmp->rightdir);
950 p = cmp->rightdir + (strlen(cmp->rightdir) - 1);
951 if (p - cmp->rightdir > 3 && *p == '\\')
952 *p = 0; // Chop trailing slash
953 break;
954 }
955 }
956 }
957 }
958 } // while !EOF
959
960 memset(&cnri, 0, sizeof(cnri));
961 cnri.cb = sizeof(cnri);
962 cnri.pszCnrTitle = cmp->rightdir;
963 if (!WinSendMsg(hwndRight, CM_SETCNRINFO,
964 MPFROMP(&cnri), MPFROMLONG(CMA_CNRTITLE))) {
965 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_SETCNRINFO");
966 }
967
968 if (*cmp->rightdir) {
969 lenr = strlen(cmp->rightdir);
970 if (cmp->rightdir[strlen(cmp->rightdir) - 1] != '\\')
971 lenr++;
972 while (!feof(fp)) {
973 if (!xfgets_bstripcr
974 (str, sizeof(str), fp, pszSrcFile, __LINE__))
975 break;
976 p = str;
977 if (*p == '\"') {
978 p++;
979 if (*p && *p != '\"') {
980 p = strchr(p, '\"');
981 if (p) {
982 *p = 0;
983 p++;
984 if (*p == ',') {
985 p++;
986 if (!cmp->includesubdirs && atol(p) > lenr)
987 continue;
988 p = strchr(p, ',');
989 if (p) {
990 p++;
991 fb4.cbFile = atol(p);
992 p = strchr(p, ',');
993 if (p) {
994 p++;
995 fb4.fdateLastWrite.year = atol(p) - 1980;
996 p = strchr(p, '/');
997 if (p) {
998 p++;
999 fb4.fdateLastWrite.month = atol(p);
1000 p = strchr(p, '/');
1001 if (p) {
1002 p++;
1003 fb4.fdateLastWrite.day = atol(p);
1004 p = strchr(p, ',');
1005 if (p) {
1006 p++;
1007 fb4.ftimeLastWrite.hours = atol(p);
1008 p = strchr(p, ':');
1009 if (p) {
1010 p++;
1011 fb4.ftimeLastWrite.minutes = atol(p);
1012 p = strchr(p, ':');
1013 if (p) {
1014 p++;
1015 fb4.ftimeLastWrite.twosecs = atol(p);
1016 p = strchr(p, ',');
1017 if (p) {
1018 p++;
1019 fb4.attrFile = atol(p);
1020 p = strchr(p, ',');
1021 if (p) {
1022 p++;
1023 fb4.cbList = atol(p) * 2;
1024 if (fForceUpper)
1025 strupr(str + 1);
1026 else if (fForceLower)
1027 strlwr(str + 1);
1028 if (AddToFileList((str + 1) + lenr,
1029 &fb4,
1030 &filesr,
1031 &numfilesr,
1032 &numallocr))
1033 break;
1034 }
1035 }
1036 }
1037 }
1038 }
1039 }
1040 }
1041 }
1042 }
1043 }
1044 }
1045 }
1046 }
1047 } // while
1048 } // if have rightdir
1049 fclose(fp);
1050 }
1051 } // if snapshot file
1052
1053 if (filesr)
1054 qsort(filesr, numfilesr, sizeof(CHAR *), CompNames);
1055
1056 // We now have two lists of files, both sorted.
1057 // Count total number of container entries required on each side
1058 l = r = 0;
1059 recsNeeded = 0;
1060 while ((filesl && filesl[l]) || (filesr && filesr[r])) {
1061
1062 if (filesl && filesl[l]) {
1063 if (filesr && filesr[r])
1064 x = stricmp(filesl[l]->fname, filesr[r]->fname);
1065 else
1066 x = -1; // Left side list longer
1067 }
1068 else
1069 x = +1; // Right side list longer
1070
1071 if (x <= 0)
1072 l++; // On left side
1073 if (x >= 0)
1074 r++; // On right side
1075
1076 recsNeeded++; // Keep count of how many entries req'd
1077
1078 } // while
1079
1080 WinSendMsg(cmp->hwnd, UM_CONTAINERHWND, MPVOID, MPVOID);
1081
1082 // Now insert records into the containers
1083 cntr = 0;
1084 l = r = 0;
1085 if (recsNeeded) {
1086 pcilFirst = WinSendMsg(hwndLeft,
1087 CM_ALLOCRECORD,
1088 MPFROMLONG(EXTRA_RECORD_BYTES),
1089 MPFROMLONG(recsNeeded));
1090 if (!pcilFirst) {
1091 Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_ALLOCRECORD %u failed",
1092 recsNeeded);
1093 recsNeeded = 0;
1094 }
1095 }
1096 if (recsNeeded) {
1097 pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
1098 MPFROMLONG(EXTRA_RECORD_BYTES),
1099 MPFROMLONG(recsNeeded));
1100 if (!pcirFirst) {
1101 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_ALLOCRECORD %u failed",
1102 recsNeeded);
1103 recsNeeded = 0;
1104 FreeCnrItemList(hwndLeft, pcilFirst);
1105 }
1106 }
1107
1108 if (recsNeeded) {
1109
1110 pcil = pcilFirst;
1111 pcir = pcirFirst;
1112 while ((filesl && filesl[l]) || (filesr && filesr[r])) {
1113 pcir->hwndCnr = hwndRight;
1114 pcir->rc.hptrIcon = (HPOINTER) 0;
1115 pcil->hwndCnr = hwndLeft;
1116 pcil->rc.hptrIcon = (HPOINTER) 0;
1117
1118 if (filesl && filesl[l]) {
1119 if (filesr && filesr[r])
1120 x = stricmp(filesl[l]->fname, filesr[r]->fname);
1121 else
1122 x = -1; // Left side list longer
1123 }
1124 else
1125 x = +1; // Right side list longer
1126
1127 if (x <= 0) {
1128 // File appears on left side
1129 BldFullPathName(szBuf, cmp->leftdir, filesl[l]->fname);
1130 //sprintf(szBuf, "%s%s%s", cmp->leftdir,
1131 // (cmp->leftdir[strlen(cmp->leftdir) - 1] == '\\') ?
1132 // NullStr : "\\", filesl[l]->fname);
1133 pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
1134 pcil->pszDisplayName = pcil->pszFileName + lenl;
1135 pcil->attrFile = filesl[l]->attrFile;
1136 pcil->pszDispAttr = FileAttrToString(pcil->attrFile);
1137 pcil->cbFile = filesl[l]->cbFile;
1138 pcil->easize = filesl[l]->easize;
1139 pcil->date.day = filesl[l]->date.day;
1140 pcil->date.month = filesl[l]->date.month;
1141 pcil->date.year = filesl[l]->date.year + 1980;
1142 pcil->time.seconds = filesl[l]->time.twosecs * 2;
1143 pcil->time.minutes = filesl[l]->time.minutes;
1144 pcil->time.hours = filesl[l]->time.hours;
1145 pcil->ladate.day = filesl[l]->ladate.day;
1146 pcil->ladate.month = filesl[l]->ladate.month;
1147 pcil->ladate.year = filesl[l]->ladate.year + 1980;
1148 pcil->latime.seconds = filesl[l]->latime.twosecs * 2;
1149 pcil->latime.minutes = filesl[l]->latime.minutes;
1150 pcil->latime.hours = filesl[l]->latime.hours;
1151 pcil->crdate.day = filesl[l]->crdate.day;
1152 pcil->crdate.month = filesl[l]->crdate.month;
1153 pcil->crdate.year = filesl[l]->crdate.year + 1980;
1154 pcil->crtime.seconds = filesl[l]->crtime.twosecs * 2;
1155 pcil->crtime.minutes = filesl[l]->crtime.minutes;
1156 pcil->crtime.hours = filesl[l]->crtime.hours;
1157 if (*cmp->dcd.mask.szMask) {
1158 if (!Filter((PMINIRECORDCORE) pcil, (PVOID)&cmp->dcd.mask)) {
1159 pcil->rc.flRecordAttr |= CRA_FILTERED;
1160 pcir->rc.flRecordAttr |= CRA_FILTERED;
1161 }
1162 }
1163 } // if on left
1164
1165 if (x >= 0) {
1166 // File appears on right side
1167 BldFullPathName(szBuf, cmp->rightdir, filesr[r]->fname);
1168 //sprintf(szBuf, "%s%s%s", cmp->rightdir,
1169 // (cmp->rightdir[strlen(cmp->rightdir) - 1] == '\\') ?
1170 // NullStr : "\\", filesr[r]->fname);
1171 pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__); // 31 Jul 07 SHL
1172 pcir->pszDisplayName = pcir->pszFileName + lenr;
1173 pcir->attrFile = filesr[r]->attrFile;
1174 // pcir->rc.hptrIcon = hptrFile;
1175 pcir->pszDispAttr = FileAttrToString(pcir->attrFile);
1176 pcir->cbFile = filesr[r]->cbFile;
1177 pcir->easize = filesr[r]->easize;
1178 pcir->date.day = filesr[r]->date.day;
1179 pcir->date.month = filesr[r]->date.month;
1180 pcir->date.year = filesr[r]->date.year + 1980;
1181 pcir->time.seconds = filesr[r]->time.twosecs * 2;
1182 pcir->time.minutes = filesr[r]->time.minutes;
1183 pcir->time.hours = filesr[r]->time.hours;
1184 pcir->ladate.day = filesr[r]->ladate.day;
1185 pcir->ladate.month = filesr[r]->ladate.month;
1186 pcir->ladate.year = filesr[r]->ladate.year + 1980;
1187 pcir->latime.seconds = filesr[r]->latime.twosecs * 2;
1188 pcir->latime.minutes = filesr[r]->latime.minutes;
1189 pcir->latime.hours = filesr[r]->latime.hours;
1190 pcir->crdate.day = filesr[r]->crdate.day;
1191 pcir->crdate.month = filesr[r]->crdate.month;
1192 pcir->crdate.year = filesr[r]->crdate.year + 1980;
1193 pcir->crtime.seconds = filesr[r]->crtime.twosecs * 2;
1194 pcir->crtime.minutes = filesr[r]->crtime.minutes;
1195 pcir->crtime.hours = filesr[r]->crtime.hours;
1196 if (~pcil->rc.flRecordAttr & CRA_FILTERED &&
1197 *cmp->dcd.mask.szMask) {
1198 if (!Filter((PMINIRECORDCORE)pcir, (PVOID)&cmp->dcd.mask)) {
1199 pcil->rc.flRecordAttr |= CRA_FILTERED;
1200 pcir->rc.flRecordAttr |= CRA_FILTERED;
1201 }
1202 }
1203 } // if on right
1204
1205 if (x == 0) {
1206 // File appears on both sides
1207 pcil->flags |= CNRITEM_EXISTS;
1208 pcir->flags |= CNRITEM_EXISTS;
1209 pch = szBuf;
1210 // Subject field holds status messages
1211 *pch = 0;
1212 if (pcil->cbFile + pcil->easize > pcir->cbFile + pcir->easize) {
1213 pcil->flags |= CNRITEM_LARGER;
1214 pcir->flags |= CNRITEM_SMALLER;
1215 strcpy(pch, GetPString(IDS_LARGERTEXT));
1216 pch += 6;
1217 }
1218 else if (pcil->cbFile + pcil->easize <
1219 pcir->cbFile + pcir->easize) {
1220 pcil->flags |= CNRITEM_SMALLER;
1221 pcir->flags |= CNRITEM_LARGER;
1222 strcpy(pch, GetPString(IDS_SMALLERTEXT));
1223 pch += 7;
1224 }
1225 if ((pcil->date.year > pcir->date.year) ? TRUE :
1226 (pcil->date.year < pcir->date.year) ? FALSE :
1227 (pcil->date.month > pcir->date.month) ? TRUE :
1228 (pcil->date.month < pcir->date.month) ? FALSE :
1229 (pcil->date.day > pcir->date.day) ? TRUE :
1230 (pcil->date.day < pcir->date.day) ? FALSE :
1231 (pcil->time.hours > pcir->time.hours) ? TRUE :
1232 (pcil->time.hours < pcir->time.hours) ? FALSE :
1233 (pcil->time.minutes > pcir->time.minutes) ? TRUE :
1234 (pcil->time.minutes < pcir->time.minutes) ? FALSE :
1235 (pcil->time.seconds > pcir->time.seconds) ? TRUE :
1236 (pcil->time.seconds < pcir->time.seconds) ? FALSE : FALSE) {
1237 pcil->flags |= CNRITEM_NEWER;
1238 pcir->flags |= CNRITEM_OLDER;
1239 if (pch != szBuf) {
1240 strcpy(pch, ", ");
1241 pch += 2;
1242 }
1243 strcpy(pch, GetPString(IDS_NEWERTEXT));
1244 pch += 5;
1245 }
1246 else if ((pcil->date.year < pcir->date.year) ? TRUE :
1247 (pcil->date.year > pcir->date.year) ? FALSE :
1248 (pcil->date.month < pcir->date.month) ? TRUE :
1249 (pcil->date.month > pcir->date.month) ? FALSE :
1250 (pcil->date.day < pcir->date.day) ? TRUE :
1251 (pcil->date.day > pcir->date.day) ? FALSE :
1252 (pcil->time.hours < pcir->time.hours) ? TRUE :
1253 (pcil->time.hours > pcir->time.hours) ? FALSE :
1254 (pcil->time.minutes < pcir->time.minutes) ? TRUE :
1255 (pcil->time.minutes > pcir->time.minutes) ? FALSE :
1256 (pcil->time.seconds < pcir->time.seconds) ? TRUE :
1257 (pcil->time.seconds > pcir->time.seconds) ? FALSE :
1258 FALSE) {
1259 pcil->flags |= CNRITEM_OLDER;
1260 pcir->flags |= CNRITEM_NEWER;
1261 if (pch != szBuf) {
1262 strcpy(pch, ", ");
1263 pch += 2;
1264 }
1265 strcpy(pch, GetPString(IDS_OLDERTEXT));
1266 pch += 5;
1267 }
1268 pcil->pszSubject = *szBuf ?
1269 xstrdup(szBuf, pszSrcFile, __LINE__) :
1270 NullStr;
1271
1272 } // if on both sides
1273
1274 if (x <= 0) {
1275 free(filesl[l]);
1276 l++;
1277 }
1278
1279 if (x >= 0) {
1280 free(filesr[r]);
1281 r++;
1282 }
1283
1284 // Ensure empty buffers point somewhere
1285 if (!pcil->pszFileName) {
1286 pcil->pszFileName = NullStr;
1287 pcil->pszDisplayName = pcil->pszFileName;
1288 }
1289
1290 if (!pcir->pszFileName) {
1291 pcir->pszFileName = NullStr;
1292 pcir->pszDisplayName = pcir->pszFileName;
1293 }
1294
1295 pcil->rc.pszIcon = pcil->pszDisplayName;
1296 pcir->rc.pszIcon = pcir->pszDisplayName;
1297
1298 pcil->pszLongName = NullStr;
1299 pcir->pszLongName = NullStr;
1300
1301 if (!pcil->pszSubject)
1302 pcil->pszSubject = NullStr;
1303 if (!pcir->pszSubject)
1304 pcil->pszSubject = NullStr;
1305
1306 if (!pcil->pszDispAttr)
1307 pcil->pszDispAttr = NullStr;
1308 if (!pcir->pszDispAttr)
1309 pcil->pszDispAttr = NullStr;
1310
1311 // fixme to be time based - every 2 sec should be OK
1312 if (!(cntr % 500))
1313 DosSleep(1);
1314 else if (!(cntr % 50))
1315 DosSleep(1);
1316
1317 cntr++;
1318
1319 pcil = (PCNRITEM) pcil->rc.preccNextRecord;
1320 pcir = (PCNRITEM) pcir->rc.preccNextRecord;
1321
1322 } // while filling left or right
1323
1324 if (filesl)
1325 free(filesl); // Free header - have already freed elements
1326 filesl = NULL;
1327 if (filesr)
1328 free(filesr);
1329 filesr = NULL;
1330 // Insert 'em
1331 WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
1332
1333 memset(&ri, 0, sizeof(RECORDINSERT));
1334 ri.cb = sizeof(RECORDINSERT);
1335 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1336 ri.pRecordParent = (PRECORDCORE) NULL;
1337 ri.zOrder = (ULONG) CMA_TOP;
1338 ri.cRecordsInsert = recsNeeded;
1339 ri.fInvalidateRecord = FALSE;
1340 if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
1341 MPFROMP(pcilFirst), MPFROMP(&ri))) {
1342 Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
1343 FreeCnrItemList(hwndLeft, pcilFirst);
1344 numfilesl = 0;
1345 }
1346
1347 memset(&ri, 0, sizeof(RECORDINSERT));
1348 ri.cb = sizeof(RECORDINSERT);
1349 ri.pRecordOrder = (PRECORDCORE) CMA_END;
1350 ri.pRecordParent = (PRECORDCORE) NULL;
1351 ri.zOrder = (ULONG) CMA_TOP;
1352 ri.cRecordsInsert = recsNeeded;
1353 ri.fInvalidateRecord = FALSE;
1354
1355 if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
1356 MPFROMP(pcirFirst), MPFROMP(&ri))) {
1357 Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
1358 RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
1359 FreeCnrItemList(hwndRight, pcirFirst);
1360 numfilesr = 0;
1361 }
1362
1363 cmp->cmp->totalleft = numfilesl;
1364 cmp->cmp->totalright = numfilesr;
1365
1366 } // if recsNeeded
1367
1368 Deselect(hwndLeft);
1369 Deselect(hwndRight);
1370
1371 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID))
1372 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
1373 notified = TRUE;
1374
1375 if (filesl)
1376 FreeList((CHAR **)filesl); // Must have failed to create container
1377 if (filesr)
1378 FreeList((CHAR **)filesr);
1379
1380 WinDestroyMsgQueue(hmq);
1381 }
1382 DecrThreadUsage();
1383 WinTerminate(hab);
1384 }
1385 if (!notified)
1386 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);
1387 free(cmp);
1388 DosPostEventSem(CompactSem);
1389}
1390
1391// fixme to be gone - use variable
1392#define hwndLeft (WinWindowFromID(hwnd,COMP_LEFTDIR))
1393#define hwndRight (WinWindowFromID(hwnd,COMP_RIGHTDIR))
1394
1395//=== CompareDlgProc() Compare directories dialog procedure ===
1396
1397MRESULT EXPENTRY CompareDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1398{
1399 COMPARE *cmp;
1400 BOOL temp;
1401
1402 static HPOINTER hptr;
1403
1404 switch (msg) {
1405 case WM_INITDLG:
1406 cmp = (COMPARE *) mp2;
1407 if (!cmp) {
1408 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
1409 WinDismissDlg(hwnd, 0);
1410 }
1411 else {
1412 if (!hptr)
1413 hptr = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, COMPARE_ICON);
1414 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptr), MPVOID);
1415 cmp->hwnd = hwnd;
1416 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) cmp);
1417 SetCnrCols(hwndLeft, TRUE);
1418 SetCnrCols(hwndRight, TRUE);
1419 WinSendMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
1420 WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
1421 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
1422 {
1423 USHORT ids[] = { COMP_LEFTDIR, COMP_RIGHTDIR, COMP_TOTALLEFT,
1424 COMP_TOTALRIGHT, COMP_SELLEFT, COMP_SELRIGHT,
1425 0
1426 };
1427 INT x;
1428
1429 for (x = 0; ids[x]; x++)
1430 SetPresParams(WinWindowFromID(hwnd, ids[x]),
1431 &RGBGREY,
1432 &RGBBLACK, &RGBBLACK, GetPString(IDS_8HELVTEXT));
1433 }
1434 }
1435 break;
1436
1437 case UM_STRETCH:
1438 {
1439 SWP swp, swpC;
1440 LONG titl, szbx, szby, sz;
1441 HWND hwndActive;
1442
1443 WinQueryWindowPos(hwnd, &swp);
1444 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
1445 hwndActive = WinQueryFocus(HWND_DESKTOP);
1446 szbx = SysVal(SV_CXSIZEBORDER);
1447 szby = SysVal(SV_CYSIZEBORDER);
1448 titl = SysVal(SV_CYTITLEBAR);
1449 titl += 26;
1450 swp.cx -= (szbx * 2);
1451 sz = (swp.cx / 8);
1452 WinQueryWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), &swpC);
1453 WinSetWindowPos(WinWindowFromID(hwnd, COMP_LEFTDIR), HWND_TOP,
1454 szbx + 6,
1455 swpC.y,
1456 (swp.cx / 2) - (szbx + 6),
1457 ((swp.cy - swpC.y) - titl) - szby,
1458 SWP_MOVE | SWP_SIZE);
1459 WinSetWindowPos(WinWindowFromID(hwnd, COMP_RIGHTDIR), HWND_TOP,
1460 (swp.cx / 2) + (szbx + 6),
1461 swpC.y,
1462 (swp.cx / 2) - (szbx + 6),
1463 ((swp.cy - swpC.y) - titl) - szby,
1464 SWP_MOVE | SWP_SIZE);
1465 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFTHDR), HWND_TOP,
1466 szbx + 6,
1467 ((swp.cy - titl) - szby) + 4,
1468 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1469 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALLEFT), HWND_TOP,
1470 sz + (szbx + 6),
1471 ((swp.cy - titl) - szby) + 4,
1472 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1473 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFTHDR), HWND_TOP,
1474 (sz * 2) + (szbx + 6),
1475 ((swp.cy - titl) - szby) + 4,
1476 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1477 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELLEFT), HWND_TOP,
1478 (sz * 3) + (szbx + 6),
1479 ((swp.cy - titl) - szby) + 4,
1480 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1481 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHTHDR), HWND_TOP,
1482 (sz * 4) + (szbx + 6),
1483 ((swp.cy - titl) - szby) + 4,
1484 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1485 WinSetWindowPos(WinWindowFromID(hwnd, COMP_TOTALRIGHT), HWND_TOP,
1486 (sz * 5) + (szbx + 6),
1487 ((swp.cy - titl) - szby) + 4,
1488 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1489 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHTHDR), HWND_TOP,
1490 (sz * 6) + (szbx + 6),
1491 ((swp.cy - titl) - szby) + 4,
1492 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1493 WinSetWindowPos(WinWindowFromID(hwnd, COMP_SELRIGHT), HWND_TOP,
1494 (sz * 7) + (szbx + 6),
1495 ((swp.cy - titl) - szby) + 4,
1496 sz - (szbx + 6), 20, SWP_MOVE | SWP_SIZE);
1497 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALLEFT),
1498 (HPS) 0, FALSE, FALSE);
1499 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELLEFT),
1500 (HPS) 0, FALSE, FALSE);
1501 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_TOTALRIGHT),
1502 (HPS) 0, FALSE, FALSE);
1503 PaintRecessedWindow(WinWindowFromID(hwnd, COMP_SELRIGHT),
1504 (HPS) 0, FALSE, FALSE);
1505 PaintRecessedWindow(hwndLeft, (HPS) 0,
1506 (hwndActive == hwndLeft), TRUE);
1507 PaintRecessedWindow(hwndRight, (HPS) 0,
1508 (hwndActive == hwndRight), TRUE);
1509 }
1510 }
1511 return 0;
1512
1513 case WM_ADJUSTWINDOWPOS:
1514 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
1515 break;
1516
1517 case UM_SETUP:
1518 {
1519 CNRINFO cnri;
1520 BOOL tempsubj;
1521
1522 cmp = INSTDATA(hwnd);
1523 if (cmp) {
1524 cmp->dcd.size = sizeof(DIRCNRDATA);
1525 cmp->dcd.type = DIR_FRAME;
1526 cmp->dcd.hwndFrame = hwnd;
1527 cmp->dcd.hwndClient = hwnd;
1528 cmp->dcd.mask.attrFile = (FILE_DIRECTORY | FILE_ARCHIVED |
1529 FILE_READONLY | FILE_SYSTEM | FILE_HIDDEN);
1530 LoadDetailsSwitches("DirCmp", &cmp->dcd);
1531 cmp->dcd.detailslongname = FALSE;
1532 cmp->dcd.detailsicon = FALSE; // TRUE;
1533 }
1534 memset(&cnri, 0, sizeof(CNRINFO));
1535 cnri.cb = sizeof(CNRINFO);
1536 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_QUERYCNRINFO,
1537 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1538 cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
1539 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 68;
1540 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
1541 MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
1542 memset(&cnri, 0, sizeof(CNRINFO));
1543 cnri.cb = sizeof(CNRINFO);
1544 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_QUERYCNRINFO,
1545 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1546 cnri.flWindowAttr |= (CA_OWNERDRAW | CV_MINI);
1547 cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 54;
1548 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
1549 MPFROMLONG(CMA_FLWINDOWATTR | CMA_XVERTSPLITBAR));
1550 AdjustCnrColRO(hwndLeft, GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
1551 AdjustCnrColRO(hwndLeft, GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
1552 AdjustCnrColRO(hwndRight, GetPString(IDS_FILENAMECOLTEXT), TRUE, FALSE);
1553 AdjustCnrColRO(hwndRight, GetPString(IDS_LONGNAMECOLTEXT), TRUE, FALSE);
1554 AdjustCnrColsForPref(hwndLeft, cmp->leftdir, &cmp->dcd, TRUE);
1555 tempsubj = cmp->dcd.detailssubject;
1556 cmp->dcd.detailssubject = FALSE;
1557 AdjustCnrColsForPref(hwndRight, cmp->rightdir, &cmp->dcd, TRUE);
1558 if (*cmp->rightlist) {
1559 AdjustCnrColVis(hwndRight, GetPString(IDS_LADATECOLTEXT), FALSE,
1560 FALSE);
1561 AdjustCnrColVis(hwndRight, GetPString(IDS_LATIMECOLTEXT), FALSE,
1562 FALSE);
1563 AdjustCnrColVis(hwndRight, GetPString(IDS_CRDATECOLTEXT), FALSE,
1564 FALSE);
1565 AdjustCnrColVis(hwndRight, GetPString(IDS_CRTIMECOLTEXT), FALSE,
1566 FALSE);
1567 }
1568 cmp->dcd.detailssubject = tempsubj;
1569 }
1570 return 0;
1571
1572 case WM_DRAWITEM:
1573 if (mp2) {
1574 POWNERITEM pown = (POWNERITEM)mp2;
1575 PCNRDRAWITEMINFO pcown;
1576 PCNRITEM pci;
1577
1578 pcown = (PCNRDRAWITEMINFO)pown->hItem;
1579 if (pcown) {
1580 pci = (PCNRITEM) pcown->pRecord;
1581 // 01 Aug 07 SHL if field null or blank, we draw
1582 // fixme to know why - probably to optimize and bypass draw?
1583 if (pci && (INT)pci != -1 && !*pci->pszFileName)
1584 return MRFROMLONG(TRUE);
1585 }
1586 }
1587 return 0;
1588
1589 case UM_CONTAINERHWND:
1590 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDBLDLISTTEXT));
1591 return 0;
1592
1593 case UM_CONTAINERDIR:
1594 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDFILLCNRTEXT));
1595 return 0;
1596
1597 case UM_CONTAINER_FILLED:
1598 cmp = INSTDATA(hwnd);
1599 if (!cmp) {
1600 Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL");
1601 WinDismissDlg(hwnd, 0);
1602 }
1603 else {
1604 CHAR s[81];
1605
1606 cmp->filling = FALSE;
1607 WinEnableWindow(hwndLeft, TRUE);
1608 WinEnableWindow(hwndRight, TRUE);
1609 WinEnableWindowUpdate(hwndLeft, TRUE);
1610 WinEnableWindowUpdate(hwndRight, TRUE);
1611 sprintf(s, " %d", cmp->totalleft);
1612 WinSetDlgItemText(hwnd, COMP_TOTALLEFT, s);
1613 sprintf(s, " %d", cmp->totalright);
1614 WinSetDlgItemText(hwnd, COMP_TOTALRIGHT, s);
1615 sprintf(s, " %d", cmp->selleft);
1616 WinSetDlgItemText(hwnd, COMP_SELLEFT, s);
1617 sprintf(s, " %d", cmp->selright);
1618 WinSetDlgItemText(hwnd, COMP_SELRIGHT, s);
1619 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), TRUE);
1620 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), TRUE);
1621 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), TRUE);
1622 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), TRUE);
1623 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), TRUE);
1624 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), TRUE);
1625 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), TRUE);
1626 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), TRUE);
1627 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), TRUE);
1628 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), TRUE);
1629 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), TRUE);
1630 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), TRUE);
1631 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), TRUE);
1632 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), TRUE);
1633 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), TRUE);
1634 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), TRUE);
1635 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT), TRUE);
1636 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), TRUE);
1637 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), TRUE);
1638 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), TRUE);
1639 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), TRUE);
1640 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), TRUE);
1641 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), TRUE);
1642 if (!*cmp->rightlist) {
1643 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), TRUE);
1644 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), TRUE);
1645 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), TRUE);
1646 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), TRUE);
1647 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), TRUE);
1648 }
1649 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), TRUE);
1650 if (*cmp->dcd.mask.szMask)
1651 WinSetDlgItemText(hwnd, COMP_NOTE,
1652 GetPString(IDS_COMPREADYFILTEREDTEXT));
1653 else
1654 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
1655 }
1656 break;
1657
1658 case WM_INITMENU:
1659 cmp = INSTDATA(hwnd);
1660 if (cmp) {
1661 switch (SHORT1FROMMP(mp1)) {
1662 case IDM_COMMANDSMENU:
1663 SetupCommandMenu(cmp->dcd.hwndLastMenu, hwnd);
1664 break;
1665 }
1666 }
1667 break;
1668
1669 case WM_MENUEND:
1670 cmp = INSTDATA(hwnd);
1671 if (cmp) {
1672 if ((HWND) mp2 == cmp->dcd.hwndLastMenu) {
1673 MarkAll(hwndLeft, TRUE, FALSE, TRUE);
1674 MarkAll(hwndRight, TRUE, FALSE, TRUE);
1675 WinDestroyWindow(cmp->dcd.hwndLastMenu);
1676 cmp->dcd.hwndLastMenu = (HWND) 0;
1677 }
1678 }
1679 break;
1680
1681 case WM_CONTROL:
1682 switch (SHORT1FROMMP(mp1)) {
1683 case COMP_INCLUDESUBDIRS:
1684 switch (SHORT2FROMMP(mp1)) {
1685 case BN_CLICKED:
1686 cmp = INSTDATA(hwnd);
1687 if (cmp)
1688 *cmp->rightlist = 0;
1689 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
1690 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
1691 break;
1692 }
1693 break;
1694 case COMP_HIDENOTSELECTED:
1695 switch (SHORT2FROMMP(mp1)) {
1696 case BN_CLICKED:
1697 WinSendMsg(hwnd, UM_HIDENOTSELECTED, MPVOID, MPVOID);
1698 break;
1699 }
1700 break;
1701
1702 case COMP_LEFTDIR:
1703 case COMP_RIGHTDIR:
1704 switch (SHORT2FROMMP(mp1)) {
1705 case CN_KILLFOCUS:
1706 PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
1707 (HPS) 0, FALSE, TRUE);
1708 break;
1709
1710 case CN_SETFOCUS:
1711 PaintRecessedWindow(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
1712 (HPS) 0, TRUE, TRUE);
1713 break;
1714
1715 case CN_ENTER:
1716 if (mp2) {
1717
1718 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
1719 HWND hwndCnr = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
1720
1721 SetShiftState();
1722 if (pci) {
1723 if (pci->rc.flRecordAttr & CRA_INUSE || !pci || !*pci->pszFileName)
1724 break;
1725 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
1726 MPFROM2SHORT(TRUE, CRA_INUSE));
1727 if (pci->attrFile & FILE_DIRECTORY) {
1728 if ((shiftstate & (KC_CTRL | KC_SHIFT)) == (KC_CTRL | KC_SHIFT))
1729 OpenObject(pci->pszFileName, Settings, hwnd);
1730 else
1731 OpenObject(pci->pszFileName, Default, hwnd);
1732 }
1733 else
1734 DefaultViewKeys(hwnd, hwnd, HWND_DESKTOP, NULL,
1735 pci->pszFileName);
1736 WinSendMsg(hwndCnr, CM_SETRECORDEMPHASIS,
1737 MPFROMP(pci),
1738 MPFROM2SHORT(FALSE, CRA_INUSE |
1739 ((fUnHilite) ? CRA_SELECTED : 0)));
1740 }
1741 }
1742 break;
1743
1744 case CN_CONTEXTMENU:
1745 cmp = INSTDATA(hwnd);
1746 if (cmp) {
1747
1748 PCNRITEM pci = (PCNRITEM) mp2;
1749 USHORT id = COMP_CNRMENU;
1750
1751 if (cmp->dcd.hwndLastMenu)
1752 WinDestroyWindow(cmp->dcd.hwndLastMenu);
1753 cmp->dcd.hwndLastMenu = (HWND) 0;
1754 cmp->hwndCalling = WinWindowFromID(hwnd, SHORT1FROMMP(mp1));
1755 if (pci) {
1756 if (!pci || !*pci->pszFileName || *cmp->rightlist)
1757 break;
1758 id = COMP_MENU;
1759 WinSendMsg(cmp->hwndCalling, CM_SETRECORDEMPHASIS,
1760 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
1761 }
1762 cmp->dcd.hwndLastMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
1763 if (cmp->dcd.hwndLastMenu) {
1764 if (id == COMP_CNRMENU) {
1765 if (SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
1766 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
1767 MPFROM2SHORT(IDM_SHOWSUBJECT, FALSE), MPVOID);
1768 SetDetailsSwitches(cmp->dcd.hwndLastMenu, &cmp->dcd);
1769 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR)
1770 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
1771 MPFROM2SHORT(IDM_LOADLISTFILE, 0), MPVOID);
1772 else if (*cmp->rightlist)
1773 WinSendMsg(cmp->dcd.hwndLastMenu, MM_DELETEITEM,
1774 MPFROM2SHORT(IDM_SAVELISTFILE, 0), MPVOID);
1775 }
1776 PopupMenu(hwnd, hwnd, cmp->dcd.hwndLastMenu);
1777 }
1778 }
1779 break;
1780
1781 case CN_INITDRAG:
1782 cmp = INSTDATA(hwnd);
1783 if (*cmp->rightlist && SHORT1FROMMP(mp1) == COMP_RIGHTDIR)
1784 break;
1785 DoFileDrag(WinWindowFromID(hwnd, SHORT1FROMMP(mp1)),
1786 (HWND) 0, mp2, NULL, NULL, TRUE);
1787 break;
1788
1789 case CN_BEGINEDIT:
1790 case CN_REALLOCPSZ:
1791 // fixme to be gone - field edits not allowed
1792 Runtime_Error(pszSrcFile, __LINE__,
1793 "CN_BEGINEDIT/CN_REALLOCPSZ unexpected");
1794 break;
1795
1796 case CN_EMPHASIS:
1797 {
1798 PNOTIFYRECORDEMPHASIS pre = mp2;
1799 PCNRITEM pci;
1800
1801 if (pre->fEmphasisMask & CRA_SELECTED) {
1802 pci = (PCNRITEM) pre->pRecord;
1803 if (pci) {
1804 if (!pci || !*pci->pszFileName) {
1805 if (pci->rc.flRecordAttr & CRA_SELECTED)
1806 WinSendDlgItemMsg(hwnd, SHORT1FROMMP(mp1),
1807 CM_SETRECORDEMPHASIS,
1808 MPFROMP(pci),
1809 MPFROM2SHORT(FALSE, CRA_SELECTED));
1810 }
1811 else {
1812
1813 CHAR s[81];
1814
1815 cmp = INSTDATA(hwnd);
1816 if (pci->rc.flRecordAttr & CRA_SELECTED) {
1817 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR)
1818 cmp->selleft++;
1819 else
1820 cmp->selright++;
1821 }
1822 else {
1823 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR) {
1824 if (cmp->selleft)
1825 cmp->selleft--;
1826 }
1827 else {
1828 if (cmp->selright)
1829 cmp->selright--;
1830 }
1831 }
1832 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR) {
1833 if (WinIsWindowEnabled(hwndLeft) || !(cmp->selleft % 50)) {
1834 sprintf(s, " %d", cmp->selleft);
1835 WinSetDlgItemText(hwnd, COMP_SELLEFT, s);
1836 }
1837 }
1838 else {
1839 if (WinIsWindowEnabled(hwndRight) || !(cmp->selright % 50)) {
1840 sprintf(s, " %d", cmp->selright);
1841 WinSetDlgItemText(hwnd, COMP_SELRIGHT, s);
1842 }
1843 }
1844 }
1845 }
1846 }
1847 }
1848 break;
1849
1850 case CN_SCROLL:
1851 cmp = INSTDATA(hwnd);
1852 if (!cmp->forcescroll) {
1853
1854 PNOTIFYSCROLL pns = mp2;
1855
1856 if (pns->fScroll & CMA_VERTICAL) {
1857 cmp->forcescroll = TRUE;
1858 WinSendDlgItemMsg(hwnd, (SHORT1FROMMP(mp1) == COMP_LEFTDIR) ?
1859 COMP_RIGHTDIR : COMP_LEFTDIR,
1860 CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL),
1861 MPFROMLONG(pns->lScrollInc));
1862 cmp->forcescroll = FALSE;
1863 }
1864 }
1865 break;
1866 }
1867 break; // COMP_RIGHTDIR
1868 }
1869 return 0; // WM_CONTROL
1870
1871 case UM_SETDIR:
1872 cmp = INSTDATA(hwnd);
1873 if (cmp) {
1874
1875 COMPARE *forthread;
1876 CNRINFO cnri;
1877
1878 cmp->includesubdirs = WinQueryButtonCheckstate(hwnd,
1879 COMP_INCLUDESUBDIRS);
1880 memset(&cnri, 0, sizeof(CNRINFO));
1881 cnri.cb = sizeof(CNRINFO);
1882 cnri.pszCnrTitle = cmp->leftdir;
1883 cnri.flWindowAttr = CV_DETAIL | CV_MINI |
1884 CA_CONTAINERTITLE | CA_TITLESEPARATOR |
1885 CA_DETAILSVIEWTITLES | CA_OWNERDRAW;
1886 WinSendDlgItemMsg(hwnd, COMP_LEFTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
1887 MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
1888 cnri.pszCnrTitle = cmp->rightdir;
1889 WinSendDlgItemMsg(hwnd, COMP_RIGHTDIR, CM_SETCNRINFO, MPFROMP(&cnri),
1890 MPFROMLONG(CMA_CNRTITLE | CMA_FLWINDOWATTR));
1891 WinCheckButton(hwnd, COMP_HIDENOTSELECTED, 0);
1892 cmp->filling = TRUE;
1893 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
1894 if (!forthread)
1895 WinDismissDlg(hwnd, 0);
1896 else {
1897 *forthread = *cmp;
1898 forthread->cmp = cmp;
1899 if (_beginthread(FillCnrsThread, NULL, 122880, (PVOID) forthread) ==
1900 -1) {
1901 Runtime_Error(pszSrcFile, __LINE__,
1902 GetPString(IDS_COULDNTSTARTTHREADTEXT));
1903 WinDismissDlg(hwnd, 0);
1904 free(forthread);
1905 }
1906 else {
1907 WinEnableWindowUpdate(hwndLeft, FALSE);
1908 WinEnableWindowUpdate(hwndRight, FALSE);
1909 cmp->selleft = cmp->selright = 0;
1910 WinSetDlgItemText(hwnd, COMP_SELLEFT, "0");
1911 WinSetDlgItemText(hwnd, COMP_SELRIGHT, "0");
1912 WinSetDlgItemText(hwnd, COMP_TOTALLEFT, "0");
1913 WinSetDlgItemText(hwnd, COMP_TOTALRIGHT, "0");
1914 WinSetDlgItemText(hwnd, COMP_NOTE,
1915 GetPString(IDS_COMPHOLDREADDISKTEXT));
1916 WinEnableWindow(hwndRight, FALSE);
1917 WinEnableWindow(hwndLeft, FALSE);
1918 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
1919 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
1920 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
1921 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
1922 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
1923 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
1924 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
1925 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
1926 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
1927 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
1928 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
1929 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
1930 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
1931 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
1932 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER), FALSE);
1933 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
1934 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS), FALSE);
1935 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
1936 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
1937 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
1938 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
1939 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
1940 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
1941 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
1942 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT),
1943 FALSE);
1944 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL), FALSE);
1945 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
1946 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
1947 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
1948 }
1949 }
1950 }
1951 return 0;
1952
1953 case UM_FILTER:
1954 cmp = INSTDATA(hwnd);
1955 if (cmp) {
1956 if (mp1) {
1957 DosEnterCritSec();
1958 SetMask((CHAR *) mp1, &cmp->dcd.mask);
1959 DosExitCritSec();
1960 }
1961 cmp->dcd.suspendview = 1;
1962 WinSendMsg(hwndLeft, CM_FILTER, MPFROMP(Filter),
1963 MPFROMP(&cmp->dcd.mask));
1964 WinSendMsg(hwndRight, CM_FILTER, MPFROMP(Filter),
1965 MPFROMP(&cmp->dcd.mask));
1966 cmp->dcd.suspendview = 0;
1967 if (*cmp->dcd.mask.szMask)
1968 WinSetDlgItemText(hwnd, COMP_NOTE,
1969 GetPString(IDS_COMPREADYFILTEREDTEXT));
1970 else
1971 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
1972 }
1973 return 0;
1974
1975 case UM_HIDENOTSELECTED:
1976 cmp = INSTDATA(hwnd);
1977 if (cmp) {
1978 USHORT wantHide = WinQueryButtonCheckstate(hwnd,
1979 COMP_HIDENOTSELECTED);
1980
1981 cmp->dcd.suspendview = 1;
1982 if (wantHide) {
1983 BOOL needRefresh = FALSE;
1984 HWND hwndl = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR);
1985 HWND hwndr = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR);
1986 PCNRITEM pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPVOID,
1987 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1988 PCNRITEM pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPVOID,
1989 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1990
1991 while (pcil && (INT) pcil != -1 && pcir && (INT) pcir != -1) {
1992 if (~pcil->rc.flRecordAttr & CRA_SELECTED &&
1993 ~pcir->rc.flRecordAttr & CRA_SELECTED) {
1994 pcil->rc.flRecordAttr |= CRA_FILTERED;
1995 pcir->rc.flRecordAttr |= CRA_FILTERED;
1996 needRefresh = TRUE;
1997 }
1998 pcil = WinSendMsg(hwndl, CM_QUERYRECORD, MPFROMP(pcil),
1999 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2000 pcir = WinSendMsg(hwndr, CM_QUERYRECORD, MPFROMP(pcir),
2001 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
2002 } // while
2003 if (needRefresh) {
2004 WinSendMsg(hwndl, CM_INVALIDATERECORD,
2005 MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
2006 WinSendMsg(hwndr, CM_INVALIDATERECORD,
2007 MPVOID, MPFROM2SHORT(0, CMA_REPOSITION));
2008 }
2009 }
2010 else {
2011 WinSendMsg(hwndLeft, CM_FILTER, MPFROMP(Filter),
2012 MPFROMP(&cmp->dcd.mask));
2013 WinSendMsg(hwndRight, CM_FILTER, MPFROMP(Filter),
2014 MPFROMP(&cmp->dcd.mask));
2015 }
2016 cmp->dcd.suspendview = 0;
2017 if (*cmp->dcd.mask.szMask)
2018 WinSetDlgItemText(hwnd, COMP_NOTE,
2019 GetPString(IDS_COMPREADYFILTEREDTEXT));
2020 else
2021 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPREADYTEXT));
2022 }
2023 return 0;
2024
2025 case WM_COMMAND:
2026 switch (SHORT1FROMMP(mp1)) {
2027 case IDM_COMPARE:
2028 cmp = INSTDATA(hwnd);
2029 if (cmp) {
2030
2031 PCNRITEM pci;
2032 CHAR ofile[CCHMAXPATH];
2033
2034 pci = (PCNRITEM) WinSendMsg(cmp->hwndCalling,
2035 CM_QUERYRECORDEMPHASIS,
2036 MPFROMLONG(CMA_FIRST),
2037 MPFROMSHORT(CRA_CURSORED));
2038 // 01 Aug 07 SHL
2039 if (pci && *pci->pszFileName) {
2040 if (cmp->hwndCalling == hwndLeft)
2041 strcpy(ofile, cmp->rightdir);
2042 else
2043 strcpy(ofile, cmp->leftdir);
2044 if (ofile[strlen(ofile) - 1] != '\\')
2045 strcat(ofile, "\\");
2046 strcat(ofile, pci->pszDisplayName);
2047 if (*compare) {
2048 CHAR *fakelist[3];
2049 fakelist[0] = pci->pszFileName;
2050 fakelist[1] = ofile;
2051 fakelist[2] = NULL;
2052 ExecOnList(hwnd, compare,
2053 WINDOWED | SEPARATEKEEP, NULL, fakelist, NULL);
2054 }
2055 else {
2056 FCOMPARE fc;
2057 memset(&fc, 0, sizeof(fc));
2058 fc.size = sizeof(fc);
2059 fc.hwndParent = hwnd;
2060 strcpy(fc.file1, pci->pszFileName);
2061 strcpy(fc.file2, ofile);
2062 WinDlgBox(HWND_DESKTOP, hwnd,
2063 CFileDlgProc, FM3ModHandle, FCMP_FRAME, (PVOID) & fc);
2064 }
2065 }
2066 }
2067 break;
2068
2069 case COMP_FILTER:
2070 case IDM_FILTER:
2071 cmp = INSTDATA(hwnd);
2072 if (cmp) {
2073
2074 BOOL empty = FALSE;
2075 PCNRITEM pci;
2076 CHAR *p;
2077 BOOL temp;
2078
2079 if (!*cmp->dcd.mask.szMask) {
2080 empty = TRUE;
2081 temp = fSelectedAlways;
2082 fSelectedAlways = TRUE;
2083 pci = (PCNRITEM)CurrentRecord(hwnd);
2084 fSelectedAlways = temp;
2085 // 01 Aug 07 SHL
2086 if (pci && ~pci->attrFile & FILE_DIRECTORY) {
2087 p = strrchr(pci->pszFileName, '\\');
2088 if (p) {
2089 p++;
2090 strcpy(cmp->dcd.mask.szMask, p);
2091 }
2092 }
2093 }
2094 cmp->dcd.mask.fNoAttribs = TRUE;
2095 cmp->dcd.mask.attrFile = ALLATTRS;
2096 cmp->dcd.mask.antiattr = 0;
2097 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
2098 FM3ModHandle, MSK_FRAME, MPFROMP(&cmp->dcd.mask))) {
2099 cmp->dcd.mask.attrFile = ALLATTRS;
2100 cmp->dcd.mask.antiattr = 0;
2101 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2102 }
2103 else if (empty) {
2104 *cmp->dcd.mask.szMask = 0;
2105 cmp->dcd.mask.attrFile = ALLATTRS;
2106 cmp->dcd.mask.antiattr = 0;
2107 }
2108 }
2109 break;
2110
2111 case IDM_SHOWSUBJECT:
2112 case IDM_SHOWEAS:
2113 case IDM_SHOWSIZE:
2114 case IDM_SHOWLWDATE:
2115 case IDM_SHOWLWTIME:
2116 case IDM_SHOWLADATE:
2117 case IDM_SHOWLATIME:
2118 case IDM_SHOWCRDATE:
2119 case IDM_SHOWCRTIME:
2120 case IDM_SHOWATTR:
2121 cmp = INSTDATA(hwnd);
2122 if (cmp) {
2123
2124 DIRCNRDATA dcd1;
2125 BOOL tempsubj;
2126
2127 dcd1 = cmp->dcd;
2128 AdjustDetailsSwitches(hwndLeft,
2129 (HWND) 0, SHORT1FROMMP(mp1),
2130 cmp->leftdir, "DirCmp", &cmp->dcd, TRUE);
2131 tempsubj = cmp->dcd.detailssubject;
2132 cmp->dcd = dcd1;
2133 cmp->dcd.detailssubject = FALSE;
2134 AdjustDetailsSwitches(hwndRight,
2135 cmp->dcd.hwndLastMenu, SHORT1FROMMP(mp1),
2136 cmp->rightdir, "DirCmp", &cmp->dcd, TRUE);
2137 cmp->dcd.detailssubject = tempsubj;
2138 }
2139 break;
2140
2141 case IDM_LOADLISTFILE:
2142 cmp = INSTDATA(hwnd);
2143 if (cmp) {
2144
2145 CHAR fullname[CCHMAXPATH];
2146
2147 strcpy(fullname, "*.PMD");
2148 if (insert_filename(HWND_DESKTOP, fullname, TRUE, FALSE) &&
2149 *fullname && !strchr(fullname, '*') && !strchr(fullname, '?')) {
2150 strcpy(cmp->rightlist, fullname);
2151 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2152 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2153 }
2154 }
2155 break;
2156
2157 case IDM_SAVELISTFILE:
2158 cmp = INSTDATA(hwnd);
2159 if (cmp) {
2160
2161 SNAPSTUFF *sf;
2162 CHAR fullname[CCHMAXPATH];
2163
2164 strcpy(fullname, "*.PMD");
2165 if (export_filename(HWND_DESKTOP, fullname, 1) && *fullname &&
2166 !strchr(fullname, '*') && !strchr(fullname, '?')) {
2167 sf = xmallocz(sizeof(SNAPSTUFF), pszSrcFile, __LINE__);
2168 if (sf) {
2169 strcpy(sf->filename, fullname);
2170 if (hwndLeft == cmp->hwndCalling)
2171 strcpy(sf->dirname, cmp->leftdir);
2172 else
2173 strcpy(sf->dirname, cmp->rightdir);
2174 sf->recurse = cmp->includesubdirs;
2175 if (_beginthread(StartSnap, NULL, 65536, (PVOID) sf) == -1) {
2176 Runtime_Error(pszSrcFile, __LINE__,
2177 GetPString(IDS_COULDNTSTARTTHREADTEXT));
2178 free(sf);
2179 }
2180 }
2181 }
2182 }
2183 break;
2184
2185 case COMP_SETDIRS:
2186 cmp = INSTDATA(hwnd);
2187 if (cmp) {
2188
2189 WALK2 wa;
2190
2191 memset(&wa, 0, sizeof(wa));
2192 wa.size = sizeof(wa);
2193 strcpy(wa.szCurrentPath1, cmp->leftdir);
2194 strcpy(wa.szCurrentPath2, cmp->rightdir);
2195 if (WinDlgBox(HWND_DESKTOP, hwnd, WalkTwoCmpDlgProc,
2196 FM3ModHandle, WALK2_FRAME,
2197 MPFROMP(&wa)) &&
2198 !IsFile(wa.szCurrentPath1) &&
2199 !IsFile(wa.szCurrentPath2)) {
2200 strcpy(cmp->leftdir, wa.szCurrentPath1);
2201 strcpy(cmp->rightdir, wa.szCurrentPath2);
2202 *cmp->rightlist = 0;
2203 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
2204 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
2205 }
2206 }
2207 break;
2208
2209 case COMP_COPYLEFT:
2210 case COMP_MOVELEFT:
2211 case COMP_COPYRIGHT:
2212 case COMP_MOVERIGHT:
2213 case COMP_DELETELEFT:
2214 case COMP_DELETERIGHT:
2215 cmp = INSTDATA(hwnd);
2216 if (cmp) {
2217
2218 COMPARE *forthread;
2219
2220 cmp->filling = TRUE;
2221 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2222 if (forthread) {
2223 *forthread = *cmp;
2224 forthread->cmp = cmp;
2225 forthread->action = SHORT1FROMMP(mp1);
2226 if (_beginthread(ActionCnrThread, NULL, 122880, (PVOID) forthread)
2227 == -1) {
2228 Runtime_Error(pszSrcFile, __LINE__,
2229 GetPString(IDS_COULDNTSTARTTHREADTEXT));
2230 free(forthread);
2231 }
2232 else {
2233 WinEnableWindowUpdate(hwndLeft, FALSE);
2234 WinEnableWindowUpdate(hwndRight, FALSE);
2235 switch (SHORT1FROMMP(mp1)) {
2236 case COMP_DELETELEFT:
2237 case COMP_DELETERIGHT:
2238 WinSetDlgItemText(hwnd, COMP_NOTE,
2239 GetPString(IDS_COMPHOLDDELETINGTEXT));
2240 break;
2241 case COMP_MOVELEFT:
2242 case COMP_MOVERIGHT:
2243 WinSetDlgItemText(hwnd, COMP_NOTE,
2244 GetPString(IDS_COMPHOLDMOVINGTEXT));
2245 break;
2246 case COMP_COPYLEFT:
2247 case COMP_COPYRIGHT:
2248 WinSetDlgItemText(hwnd, COMP_NOTE,
2249 GetPString(IDS_COMPHOLDCOPYINGTEXT));
2250 break;
2251 default:
2252 WinSetDlgItemText(hwnd, COMP_NOTE,
2253 GetPString(IDS_COMPHOLDDUNNOTEXT));
2254 break;
2255 }
2256 WinEnableWindow(hwndRight, FALSE);
2257 WinEnableWindow(hwndLeft, FALSE);
2258 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
2259 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
2260 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
2261 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
2262 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
2263 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
2264 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
2265 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
2266 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
2267 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
2268 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
2269 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
2270 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
2271 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
2272 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER),
2273 FALSE);
2274 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
2275 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS),
2276 FALSE);
2277 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
2278 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
2279 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
2280 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
2281 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
2282 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
2283 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
2284 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT),
2285 FALSE);
2286 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL),
2287 FALSE);
2288 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
2289 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
2290 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
2291 }
2292 }
2293 }
2294 break;
2295
2296 case DID_OK:
2297 WinDismissDlg(hwnd, 0);
2298 break;
2299 case DID_CANCEL:
2300 WinDismissDlg(hwnd, 1);
2301 break;
2302
2303 case IDM_HELP:
2304 if (hwndHelp)
2305 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
2306 MPFROM2SHORT(HELP_COMPARE, 0), MPFROMSHORT(HM_RESOURCEID));
2307 break;
2308
2309 case IDM_DESELECTALL:
2310 case IDM_SELECTNEWER:
2311 case IDM_SELECTOLDER:
2312 case IDM_SELECTBIGGER:
2313 case IDM_SELECTSMALLER:
2314 case IDM_DESELECTNEWER:
2315 case IDM_DESELECTOLDER:
2316 case IDM_DESELECTBIGGER:
2317 case IDM_DESELECTSMALLER:
2318 case IDM_DESELECTONE:
2319 case IDM_DESELECTBOTH:
2320 case IDM_SELECTBOTH:
2321 case IDM_SELECTONE:
2322 case IDM_SELECTSAMECONTENT:
2323 case IDM_SELECTIDENTICAL: // Name, size and time
2324 case IDM_SELECTSAME: // Name and size
2325 case IDM_INVERT:
2326 cmp = INSTDATA(hwnd);
2327 if (!cmp)
2328 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2329 else {
2330 COMPARE *forthread;
2331
2332 cmp->filling = TRUE;
2333 forthread = xmalloc(sizeof(COMPARE), pszSrcFile, __LINE__);
2334 if (forthread) {
2335 *forthread = *cmp;
2336 forthread->cmp = cmp;
2337 forthread->action = SHORT1FROMMP(mp1);
2338 if (_beginthread(SelectCnrsThread, NULL, 65536, (PVOID) forthread)
2339 == -1) {
2340 Runtime_Error(pszSrcFile, __LINE__,
2341 GetPString(IDS_COULDNTSTARTTHREADTEXT));
2342 free(forthread);
2343 }
2344 else {
2345 WinEnableWindowUpdate(hwndLeft, FALSE);
2346 WinEnableWindowUpdate(hwndRight, FALSE);
2347 switch (SHORT1FROMMP(mp1)) {
2348 case IDM_DESELECTALL:
2349 case IDM_DESELECTNEWER:
2350 case IDM_DESELECTOLDER:
2351 case IDM_DESELECTBIGGER:
2352 case IDM_DESELECTSMALLER:
2353 case IDM_DESELECTONE:
2354 case IDM_DESELECTBOTH:
2355 WinSetDlgItemText(hwnd, COMP_NOTE,
2356 GetPString(IDS_COMPHOLDDESELTEXT));
2357 break;
2358 case IDM_INVERT:
2359 WinSetDlgItemText(hwnd, COMP_NOTE,
2360 GetPString(IDS_COMPHOLDINVERTTEXT));
2361 break;
2362 default:
2363 WinSetDlgItemText(hwnd, COMP_NOTE,
2364 GetPString(IDS_COMPHOLDSELTEXT));
2365 break;
2366 }
2367 WinEnableWindow(hwndRight, FALSE);
2368 WinEnableWindow(hwndLeft, FALSE);
2369 WinEnableWindow(WinWindowFromID(hwnd, DID_OK), FALSE);
2370 WinEnableWindow(WinWindowFromID(hwnd, DID_CANCEL), FALSE);
2371 WinEnableWindow(WinWindowFromID(hwnd, COMP_COLLECT), FALSE);
2372 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBOTH), FALSE);
2373 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTONE), FALSE);
2374 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTNEWER), FALSE);
2375 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTOLDER), FALSE);
2376 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTBIGGER), FALSE);
2377 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSMALLER), FALSE);
2378 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBOTH), FALSE);
2379 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTONE), FALSE);
2380 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTNEWER), FALSE);
2381 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTOLDER), FALSE);
2382 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTBIGGER), FALSE);
2383 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTSMALLER),
2384 FALSE);
2385 WinEnableWindow(WinWindowFromID(hwnd, IDM_DESELECTALL), FALSE);
2386 WinEnableWindow(WinWindowFromID(hwnd, COMP_INCLUDESUBDIRS),
2387 FALSE);
2388 WinEnableWindow(WinWindowFromID(hwnd, COMP_SETDIRS), FALSE);
2389 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETELEFT), FALSE);
2390 WinEnableWindow(WinWindowFromID(hwnd, COMP_DELETERIGHT), FALSE);
2391 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYLEFT), FALSE);
2392 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVELEFT), FALSE);
2393 WinEnableWindow(WinWindowFromID(hwnd, COMP_COPYRIGHT), FALSE);
2394 WinEnableWindow(WinWindowFromID(hwnd, COMP_MOVERIGHT), FALSE);
2395 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAMECONTENT),
2396 FALSE);
2397 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTIDENTICAL),
2398 FALSE);
2399 WinEnableWindow(WinWindowFromID(hwnd, IDM_SELECTSAME), FALSE);
2400 WinEnableWindow(WinWindowFromID(hwnd, IDM_INVERT), FALSE);
2401 WinEnableWindow(WinWindowFromID(hwnd, COMP_FILTER), FALSE);
2402 }
2403 }
2404 }
2405 break;
2406
2407 case COMP_COLLECT:
2408 cmp = INSTDATA(hwnd);
2409 if (!cmp)
2410 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2411 else {
2412 CHAR **listl;
2413 CHAR **listr = NULL;
2414 if (!Collector) {
2415 SWP swp;
2416 HWND hwndC;
2417 if (!fAutoTile &&
2418 !ParentIsDesktop(hwnd, cmp->hwndParent) &&
2419 !fExternalCollector &&
2420 !strcmp(realappname, FM3Str)) {
2421 GetNextWindowPos(cmp->hwndParent, &swp, NULL, NULL);
2422 }
2423 hwndC = StartCollector(fExternalCollector ||
2424 strcmp(realappname, FM3Str) ?
2425 HWND_DESKTOP :
2426 cmp->hwndParent,
2427 4);
2428 if (hwndC) {
2429 if (!fAutoTile &&
2430 !ParentIsDesktop(hwnd, cmp->hwndParent) &&
2431 !fExternalCollector &&
2432 !strcmp(realappname, FM3Str)) {
2433 WinSetWindowPos(hwndC, HWND_TOP,
2434 swp.x, swp.y, swp.cx, swp.cy,
2435 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
2436 }
2437 else if (!ParentIsDesktop(hwnd, cmp->hwndParent) &&
2438 fAutoTile &&
2439 !strcmp(realappname, FM3Str)) {
2440 TileChildren(cmp->hwndParent, TRUE);
2441 }
2442 DosSleep(32); // 05 Aug 07 GKY 64
2443 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(COMP_COLLECT, 0), MPVOID);
2444 break;
2445 }
2446 }
2447 else
2448 StartCollector(cmp->hwndParent, 4);
2449
2450 temp = fSelectedAlways;
2451 fSelectedAlways = TRUE;
2452 listl = BuildList(hwndLeft);
2453 if (!*cmp->rightlist)
2454 listr = BuildList(hwndRight);
2455 fSelectedAlways = temp;
2456
2457 if (listl || listr) {
2458 if (Collector) {
2459 // 07 Aug 07 SHL Avoid collected from empty list
2460 if (listl && listl[0] && *listl[0]) {
2461 if (PostMsg(Collector, WM_COMMAND,
2462 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listl)))
2463 listl = NULL; // Collector will free
2464 }
2465 if (listr && listr[0] && *listr[0]) {
2466 if (PostMsg(Collector, WM_COMMAND,
2467 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(listr)))
2468 listr = NULL; // Collector will free
2469 }
2470 WinSetWindowPos(WinQueryWindow(WinQueryWindow(Collector,
2471 QW_PARENT),
2472 QW_PARENT),
2473 HWND_TOP, 0, 0, 0, 0,
2474 SWP_ACTIVATE);
2475 }
2476 FreeList(listl);
2477 FreeList(listr);
2478 }
2479 }
2480 break;
2481 }
2482 return 0;
2483
2484 case WM_CLOSE:
2485 WinDismissDlg(hwnd, 0);
2486 return 0;
2487
2488 case WM_DESTROY:
2489 cmp = INSTDATA(hwnd);
2490 if (cmp) {
2491 if (cmp->dcd.hwndLastMenu)
2492 WinDestroyWindow(cmp->dcd.hwndLastMenu);
2493 if (cmp->dcd.hwndObject) {
2494 WinSetWindowPtr(cmp->dcd.hwndObject, QWL_USER, (PVOID) NULL);
2495 if (!PostMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID))
2496 WinSendMsg(cmp->dcd.hwndObject, WM_CLOSE, MPVOID, MPVOID);
2497 }
2498 free(cmp);
2499 }
2500 EmptyCnr(hwndLeft);
2501 EmptyCnr(hwndRight);
2502 DosPostEventSem(CompactSem);
2503 break;
2504 }
2505 return WinDefDlgProc(hwnd, msg, mp1, mp2);
2506}
2507
2508#pragma alloc_text(COMPAREDIR,FillCnrsThread,FillDirList,CompNames,BldFullPathName)
2509#pragma alloc_text(COMPAREDIR1,CompareDlgProc)
2510#pragma alloc_text(COMPAREDIR2,SelectCnrsThread,ActionCnrThread)
2511#pragma alloc_text(COMPAREFILE,CFileDlgProc,CompareFilesThread)
2512#pragma alloc_text(SNAPSHOT,SnapShot,StartSnap)
2513
Note: See TracBrowser for help on using the repository browser.