source: trunk/dll/comp.c@ 1221

Last change on this file since 1221 was 1221, checked in by John Small, 17 years ago

Ticket 187: Moved typedef's and some #define's from fm3dll.h

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