source: trunk/dll/comp.c@ 1402

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

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

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