source: trunk/dll/comp.c@ 1370

Last change on this file since 1370 was 1358, checked in by Gregg Young, 17 years ago

Comments for CS 1354/55

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