source: trunk/dll/comp.c@ 1438

Last change on this file since 1438 was 1438, checked in by Gregg Young, 16 years ago

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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