source: trunk/dll/comp.c@ 1573

Last change on this file since 1573 was 1573, checked in by Steven Levine, 14 years ago

Minor cleanup

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