source: trunk/dll/comp.c@ 1335

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

Ticket 26: Add exception handlers to all threads using xbeginthread

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