source: trunk/dll/comp.c@ 1395

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

Allow user to turn off alert and/or error beeps in settings notebook. Ticket 341 Move repeated strings to PCSZs. Ticket 6 Add *DateFormat functions to format dates based on locale Ticket 28 Eliminate Win_Error2 by moving function names to PCSZs used in Win_Error Ticket 6

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