source: trunk/dll/comp.c@ 1409

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

Rename some container ini keys consolidate inline code in WriteDetailsSwitches, LoadDetailsSwitches and RemoveCnrSwitches (Ticket 343, 345, 347) Save changes to detail switches for compare directories (Ticket 346). Move additional messages to PCSZs (Ticket 6). Comments and minor code clean up.

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