source: trunk/dll/comp.c@ 1179

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

Ticket 187: Draft 2: Move remaining function declarations

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