source: trunk/dll/collect.c @ 751

Last change on this file since 751 was 751, checked in by Steven Levine, 13 years ago

Sync rest of code with CNRITEM mods
Sync code with ARCITEM mods
Get compare dialog working
Still some issues with status display
Still some issues with directory sizes tree display
Heap check diagnostic code mostly enabled

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 70.6 KB
Line 
1
2/***********************************************************************
3
4  $Id: collect.c 751 2007-08-02 23:05:48Z stevenhl $
5
6  Collector
7
8  Copyright (c) 1993-98 M. Kimes
9  Copyright (c) 2003, 2007 Steven H. Levine
10
11  15 Oct 02 MK Baseline
12  10 Jan 04 SHL Avoid -1L byte counts
13  01 Aug 04 SHL Rework lstrip/rstrip usage
14  23 May 05 SHL Use QWL_USER
15  24 May 05 SHL Rework Win_Error usage
16  25 May 05 SHL Use ULONGLONG and CommaFmtULL
17  25 May 05 SHL Rework for FillInRecordFromFFB
18  05 Jun 05 SHL Use QWL_USER
19  06 Jun 05 SHL Indent -i2
20  06 Jun 05 SHL Make savedSortFlags static to avoid referencing garbage
21  24 Oct 05 SHL Sanitize handle references
22  24 Oct 05 SHL CollectorCnrWndProc: avoid excess writes to Status2 window
23  10 Nov 05 SHL CollectorCnrWndProc: correct missing button window updates
24  14 Jul 06 SHL Use Runtime_Error
25  27 Jul 06 SHL Avoid shutdown hang - pre3 typo
26  29 Jul 06 SHL Use xfgets_bstripcr
27  15 Aug 06 SHL Don't write garbage to CollectorFilter INI entry
28  15 Aug 06 SHL Rework SetMask args
29  18 Aug 06 SHL CollectorCnrWndProc: avoid freeing NULL pointer
30  31 Aug 06 SHL Disable Utilities->Seek and scan menu while busy
31  31 Aug 06 SHL Correct stop scan context menu enable/disable
32  30 Mar 07 GKY Remove GetPString for window class names
33  06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
34  06 Apr 07 GKY Add some error checking in drag/drop
35  19 Apr 07 SHL Use FreeDragInfoData.  Add more drag/drop error checks.
36  12 May 07 SHL Use dcd->ulItemsToUnHilite
37  10 Jun 07 GKY Add CheckPmDrgLimit including IsFm2Window as part of work around PM drag limit
38  05 Jul 07 SHL CollectorCnrWndProc: just warn if busy
39  02 Aug 07 SHL Sync with CNRITEM mods
40
41***********************************************************************/
42
43#define INCL_DOS
44#define INCL_WIN
45#define INCL_GPI
46#define INCL_DOSERRORS
47#define INCL_LONGLONG
48#include <os2.h>
49
50#include <stdarg.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <ctype.h>
55#include <time.h>
56#include <share.h>
57#include <limits.h>
58#include <process.h>                    // _beginthread
59
60#include "fm3dll.h"
61#include "fm3dlg.h"
62#include "fm3str.h"
63#include "mle.h"
64#include "grep.h"
65
66#pragma data_seg(DATA1)
67
68static PSZ pszSrcFile = __FILE__;
69
70#pragma alloc_text(COLLECTOR,CollectorCnrWndProc,CollectorObjWndProc)
71#pragma alloc_text(COLLECTOR,CollectorClientWndProc,CollectorTextProc)
72#pragma alloc_text(COLLECTOR,CollectorFrameWndProc)
73#pragma alloc_text(STARTUP,StartCollector)
74
75MRESULT EXPENTRY CollectorFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
76                                       MPARAM mp2)
77{
78  return CommonFrameWndProc(COLLECTOR_CNR, hwnd, msg, mp1, mp2);
79}
80
81MRESULT EXPENTRY CollectorTextProc(HWND hwnd, ULONG msg, MPARAM mp1,
82                                   MPARAM mp2)
83{
84  DIRCNRDATA *dcd;
85
86  static BOOL emphasized = FALSE;
87  static HWND hwndButtonPopup = (HWND) 0;
88  static ULONG timestamp = ULONG_MAX;
89  static USHORT lastid = 0;
90
91  switch (msg) {
92  case WM_CREATE:
93    return CommonTextProc(hwnd, msg, mp1, mp2);
94
95  case UM_CONTEXTMENU:
96  case WM_CONTEXTMENU:
97    {
98      USHORT id;
99
100      id = WinQueryWindowUShort(hwnd, QWS_ID);
101      switch (id) {
102      case DIR_SELECTED:
103      case DIR_VIEW:
104      case DIR_SORT:
105        {
106          POINTL ptl = { 0, 0 };
107          SWP swp;
108
109          if (hwndButtonPopup)
110            WinDestroyWindow(hwndButtonPopup);
111          if (id == lastid) {
112            ULONG check;
113
114            DosQuerySysInfo(QSV_MS_COUNT,
115                            QSV_MS_COUNT, &check, sizeof(check));
116            if (check < timestamp + 500) {
117              lastid = 0;
118              goto MenuAbort;
119            }
120          }
121          hwndButtonPopup = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
122          if (hwndButtonPopup) {
123            WinSetWindowUShort(hwndButtonPopup, QWS_ID, id);
124            dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
125                                                                   QW_PARENT),
126                                                    COLLECTOR_CNR), QWL_USER);
127            if (id == DIR_VIEW) {
128              if (dcd) {
129                SetViewMenu(hwndButtonPopup, dcd->flWindowAttr);
130                SetDetailsSwitches(hwndButtonPopup, dcd);
131              }
132
133              /* don't have tree view in collector */
134              WinSendMsg(hwndButtonPopup,
135                         MM_DELETEITEM,
136                         MPFROM2SHORT(IDM_TREEVIEW, FALSE), MPVOID);
137
138            }
139            else if (id == DIR_SORT) {
140              if (dcd)
141                SetSortChecks(hwndButtonPopup, dcd->sortFlags);
142            }
143            ptl.x = 0;
144            if (WinPopupMenu(HWND_OBJECT,
145                             HWND_OBJECT,
146                             hwndButtonPopup, -32767, -32767, 0, 0)) {
147              WinQueryWindowPos(hwndButtonPopup, &swp);
148              ptl.y = -(swp.cy + 2);
149            }
150            else {
151              WinQueryWindowPos(hwnd, &swp);
152              ptl.y = swp.cy + 2;
153            }
154            if (WinPopupMenu(hwnd,
155                             hwnd,
156                             hwndButtonPopup,
157                             ptl.x,
158                             ptl.y,
159                             0,
160                             PU_HCONSTRAIN | PU_VCONSTRAIN |
161                             PU_KEYBOARD | PU_MOUSEBUTTON1)) {
162              CenterOverWindow(hwndButtonPopup);
163              PaintRecessedWindow(hwnd, NULLHANDLE, FALSE, FALSE);
164            }
165          }
166        }
167        break;
168      default:
169        PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
170                                COLLECTOR_CNR),
171                WM_CONTROL,
172                MPFROM2SHORT(COLLECTOR_CNR, CN_CONTEXTMENU), MPVOID);
173        break;
174      }
175    }
176  MenuAbort:
177    if (msg == UM_CONTEXTMENU)
178      return 0;
179    break;
180
181  case WM_MENUEND:
182    if (hwndButtonPopup == (HWND) mp2) {
183      lastid = WinQueryWindowUShort((HWND) mp2, QWS_ID);
184      WinDestroyWindow(hwndButtonPopup);
185      hwndButtonPopup = (HWND) 0;
186      DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &timestamp,
187                      sizeof(timestamp));
188      switch (lastid) {
189      case DIR_SELECTED:
190      case DIR_VIEW:
191      case DIR_SORT:
192        PaintRecessedWindow(hwnd, NULLHANDLE, TRUE, FALSE);
193        break;
194      }
195    }
196    break;
197
198  case WM_COMMAND:
199    {
200      DIRCNRDATA *dcd;
201      MRESULT mr;
202
203      mr = WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd,
204                                                     QW_PARENT),
205                                      COLLECTOR_CNR), msg, mp1, mp2);
206      if (hwndButtonPopup &&
207          SHORT1FROMMP(mp1) > IDM_DETAILSTITLES &&
208          SHORT1FROMMP(mp1) < IDM_DETAILSSETUP) {
209        dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
210                                                               QW_PARENT),
211                                                COLLECTOR_CNR), QWL_USER);
212        if (dcd)
213          SetDetailsSwitches(hwndButtonPopup, dcd);
214      }
215      return mr;
216    }
217
218  case WM_MOUSEMOVE:
219    {
220      USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
221      char *s = NULL;
222
223      if (fOtherHelp) {
224        if ((!hwndBubble ||
225             WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
226            !WinQueryCapture(HWND_DESKTOP)) {
227          switch (id) {
228          case DIR_SELECTED:
229            s = GetPString(IDS_COLSELECTEDHELP);
230            break;
231          case DIR_TOTALS:
232            s = GetPString(IDS_COLTOTALSHELP);
233            break;
234          case DIR_VIEW:
235            s = GetPString(IDS_DIRCNRVIEWHELP);
236            break;
237          case DIR_SORT:
238            s = GetPString(IDS_DIRCNRSORTHELP);
239            break;
240          case DIR_FILTER:
241            s = GetPString(IDS_DIRCNRFILTERHELP);
242            break;
243          default:
244            break;
245          }
246          if (s)
247            MakeBubble(hwnd, TRUE, s);
248          else if (hwndBubble)
249            WinDestroyWindow(hwndBubble);
250        }
251      }
252      switch (id) {
253      case DIR_FILTER:
254      case DIR_SORT:
255      case DIR_VIEW:
256      case DIR_SELECTED:
257        return CommonTextButton(hwnd, msg, mp1, mp2);
258      }
259    }
260    break;
261
262  case WM_BUTTON3UP:
263  case WM_BUTTON1UP:
264  case WM_BUTTON3DOWN:
265  case WM_BUTTON1DOWN:
266    {
267      USHORT id;
268
269      id = WinQueryWindowUShort(hwnd, QWS_ID);
270      switch (id) {
271      case DIR_FILTER:
272      case DIR_SORT:
273      case DIR_VIEW:
274      case DIR_SELECTED:
275        return CommonTextButton(hwnd, msg, mp1, mp2);
276      }
277    }
278    break;
279
280  case UM_CLICKED:
281  case UM_CLICKED3:
282    {
283      USHORT id, cmd = 0;
284
285      id = WinQueryWindowUShort(hwnd, QWS_ID);
286      switch (id) {
287      case DIR_VIEW:
288      case DIR_SORT:
289      case DIR_SELECTED:
290        PostMsg(hwnd, UM_CONTEXTMENU, MPVOID, MPVOID);
291        break;
292      case DIR_FILTER:
293        cmd = IDM_FILTER;
294        break;
295      default:
296        break;
297      }
298      if (cmd)
299        PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
300                                COLLECTOR_CNR),
301                WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
302    }
303    return 0;
304
305  case DM_DROP:
306  case DM_DRAGOVER:
307  case DM_DRAGLEAVE:
308  case DM_DROPHELP:
309    if (msg == DM_DRAGOVER) {
310      if (!emphasized) {
311        emphasized = TRUE;
312        DrawTargetEmphasis(hwnd, emphasized);
313      }
314    }
315    else {
316      if (emphasized) {
317        emphasized = FALSE;
318        DrawTargetEmphasis(hwnd, emphasized);
319      }
320    }
321    {
322      CNRDRAGINFO cnd;
323      USHORT dcmd;
324
325      switch (msg) {
326      case DM_DROP:
327        dcmd = CN_DROP;
328        break;
329      case DM_DRAGOVER:
330        dcmd = CN_DRAGOVER;
331        break;
332      case DM_DRAGLEAVE:
333        dcmd = CN_DRAGLEAVE;
334        break;
335      case DM_DROPHELP:
336        dcmd = CN_DROPHELP;
337        break;
338      }
339      memset(&cnd, 0, sizeof(cnd));
340      cnd.pDragInfo = (PDRAGINFO) mp1;
341      cnd.pRecord = NULL;
342      return WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_CONTROL,
343                        MPFROM2SHORT(COLLECTOR_CNR, dcmd), MPFROMP(&cnd));
344    }
345  }
346  return PFNWPStatic(hwnd, msg, mp1, mp2);
347}
348
349MRESULT EXPENTRY CollectorClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
350                                        MPARAM mp2)
351{
352  switch (msg) {
353  case UM_CONTAINERHWND:
354    return MRFROMLONG(WinWindowFromID(hwnd, COLLECTOR_CNR));
355
356  case UM_VIEWSMENU:
357    return MRFROMLONG(CheckMenu(&CollectorCnrMenu, COLLECTORCNR_POPUP));
358
359  case MM_PORTHOLEINIT:
360  case WM_INITMENU:
361  case UM_INITMENU:
362  case UM_CONTAINER_FILLED:
363  case UM_FILESMENU:
364  case UM_UPDATERECORD:
365  case UM_UPDATERECORDLIST:
366    return WinSendMsg(WinWindowFromID(hwnd, COLLECTOR_CNR), msg, mp1, mp2);
367
368  case WM_PSETFOCUS:
369  case WM_SETFOCUS:
370    if (mp2)
371      PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
372    break;
373
374  case UM_FOCUSME:
375    WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, COLLECTOR_CNR));
376    break;
377
378  case WM_PAINT:
379    {
380      HPS hps;
381      RECTL rcl;
382
383      hps = WinBeginPaint(hwnd, NULLHANDLE, NULL);
384      if (hps) {
385        WinQueryWindowRect(hwnd, &rcl);
386        WinFillRect(hps, &rcl, CLR_PALEGRAY);
387        CommonTextPaint(hwnd, hps);
388        WinEndPaint(hps);
389      }
390    }
391    break;
392
393  case UM_SIZE:
394  case WM_SIZE:
395    if (msg == UM_SIZE) {
396      SWP swp;
397
398      WinQueryWindowPos(hwnd, &swp);
399      mp1 = MPFROM2SHORT(swp.cx, swp.cy);
400      mp2 = MPFROM2SHORT(swp.cx, swp.cy);
401    }
402    {
403      USHORT cx, cy, bx;
404
405      cx = SHORT1FROMMP(mp2);
406      cy = SHORT2FROMMP(mp2);
407      WinSetWindowPos(WinWindowFromID(hwnd, COLLECTOR_CNR), HWND_TOP,
408                      0, 0, cx, cy - 24, SWP_SHOW | SWP_MOVE | SWP_SIZE);
409      WinSetWindowPos(WinWindowFromID(hwnd, DIR_TOTALS), HWND_TOP,
410                      2,
411                      cy - 22,
412                      (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
413      WinSetWindowPos(WinWindowFromID(hwnd, DIR_SELECTED), HWND_TOP,
414                      2 + (cx / 3) + 2,
415                      cy - 22,
416                      (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
417      bx = (cx - (2 + (((cx / 3) + 2) * 2))) / 3;
418      WinSetWindowPos(WinWindowFromID(hwnd, DIR_VIEW), HWND_TOP,
419                      2 + (((cx / 3) + 2) * 2),
420                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
421      WinSetWindowPos(WinWindowFromID(hwnd, DIR_SORT), HWND_TOP,
422                      2 + (((cx / 3) + 2) * 2) + bx,
423                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
424      WinSetWindowPos(WinWindowFromID(hwnd, DIR_FILTER), HWND_TOP,
425                      2 + (((cx / 3) + 2) * 2) + (bx * 2),
426                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
427    }
428    CommonTextPaint(hwnd, NULLHANDLE);
429    if (msg == UM_SIZE) {
430      WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
431                      SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE);
432      return 0;
433    }
434    break;
435
436  case UM_COMMAND:
437  case WM_COMMAND:
438  case WM_CONTROL:
439  case WM_CLOSE:
440    return WinSendMsg(WinWindowFromID(hwnd, COLLECTOR_CNR), msg, mp1, mp2);
441  }
442  return WinDefWindowProc(hwnd, msg, mp1, mp2);
443}
444
445MRESULT EXPENTRY CollectorObjWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
446                                     MPARAM mp2)
447{
448  ULONG size;
449  DIRCNRDATA *dcd;
450
451  switch (msg) {
452  case WM_CREATE:
453    break;
454
455  case DM_PRINTOBJECT:
456    return MRFROMLONG(DRR_TARGET);
457
458  case DM_DISCARDOBJECT:
459    dcd = INSTDATA(hwnd);
460    if (fFM2Deletes && dcd) {
461      LISTINFO *li;
462      CNRDRAGINFO cni;
463
464      cni.pRecord = NULL;
465      cni.pDragInfo = (PDRAGINFO) mp1;
466      li = DoFileDrop(dcd->hwndCnr, NULL, FALSE, MPVOID, MPFROMP(&cni));
467      CheckPmDrgLimit(cni.pDragInfo);
468      if (li) {
469        li->type = fDefaultDeletePerm ? IDM_PERMDELETE : IDM_DELETE;
470        if (!PostMsg(hwnd, UM_MASSACTION, MPFROMP(li), MPVOID))
471          FreeListInfo(li);
472        else
473          return MRFROMLONG(DRR_SOURCE);
474      }
475    }
476    return MRFROMLONG(DRR_TARGET);
477
478  case UM_UPDATERECORDLIST:
479    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
480    if (dcd && mp1) {
481      INT numentries = 0;
482      CHAR **list = (CHAR **) mp1;
483
484      while (list[numentries])
485        numentries++;
486      if (numentries)
487        UpdateCnrList(dcd->hwndCnr, list, numentries, FALSE, dcd);
488    }
489    return 0;
490
491  case UM_SETUP:
492    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
493    if (dcd) {
494      /* set unique id */
495      WinSetWindowUShort(hwnd,
496                         QWS_ID,
497                         COLLECTOROBJ_FRAME + (COLLECTOR_FRAME - dcd->id));
498      dcd->hwndObject = hwnd;
499      if (ParentIsDesktop(hwnd, dcd->hwndParent))
500        DosSleep(250);
501    }
502    else
503      PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
504    return 0;
505
506  case UM_COMMAND:
507    if (mp1) {
508      LISTINFO *li = (LISTINFO *) mp1;
509
510      switch (li->type) {
511      case IDM_DOITYOURSELF:
512      case IDM_APPENDTOCLIP:
513      case IDM_SAVETOCLIP:
514      case IDM_ARCHIVE:
515      case IDM_ARCHIVEM:
516      case IDM_VIEW:
517      case IDM_VIEWTEXT:
518      case IDM_VIEWBINARY:
519      case IDM_VIEWARCHIVE:
520      case IDM_EDIT:
521      case IDM_EDITTEXT:
522      case IDM_EDITBINARY:
523      case IDM_OBJECT:
524      case IDM_SHADOW:
525      case IDM_SHADOW2:
526      case IDM_PRINT:
527      case IDM_ATTRS:
528      case IDM_DELETE:
529      case IDM_PERMDELETE:
530      case IDM_FAKEEXTRACT:
531      case IDM_FAKEEXTRACTM:
532      case IDM_MCIPLAY:
533      case IDM_UPDATE:
534        if (PostMsg(hwnd, UM_MASSACTION, mp1, mp2))
535          return (MRESULT) TRUE;
536        break;
537      default:
538        if (PostMsg(hwnd, UM_ACTION, mp1, mp2))
539          return (MRESULT) TRUE;
540      }
541    }
542    return 0;
543
544  case UM_COLLECT:
545    DosError(FERR_DISABLEHARDERR);
546    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
547    if (dcd) {
548      LISTINFO *li = (LISTINFO *) mp1;
549      INT x;
550      FILEFINDBUF4 fb4;
551      HDIR hdir;
552      ULONG nm;
553      PCNRITEM pci, pciFirst, pciT, pciP = NULL;
554      RECORDINSERT ri;
555      ULONG ulMaxFiles;
556      ULONGLONG ullTotalBytes;
557      CHAR fullname[CCHMAXPATH];
558
559      WinSetWindowText(WinWindowFromID(dcd->hwndClient, DIR_SELECTED),
560                       GetPString(IDS_COLLECTINGTEXT));
561      for (ulMaxFiles = 0; li->list[ulMaxFiles]; ulMaxFiles++) ;        // Count
562
563      if (ulMaxFiles) {
564        pci = WinSendMsg(dcd->hwndCnr, CM_ALLOCRECORD,
565                         MPFROMLONG(EXTRA_RECORD_BYTES),
566                         MPFROMLONG(ulMaxFiles));
567        if (!pci) {
568          Runtime_Error(pszSrcFile, __LINE__, "CM_ALLOCRECORD %u failed",
569                        ulMaxFiles);
570          break;
571        }
572        else {
573          pciFirst = pci;
574          for (x = 0; li->list[x]; x++) {
575            nm = 1;
576            hdir = HDIR_CREATE;
577            DosError(FERR_DISABLEHARDERR);
578            if (*li->list[x] &&
579                !DosQueryPathInfo(li->list[x], FIL_QUERYFULLNAME,
580                                  fullname, sizeof(fullname)) &&
581                !IsRoot(fullname) &&
582                !FindCnrRecord(dcd->hwndCnr,
583                               fullname,
584                               NULL,
585                               FALSE,
586                               FALSE,
587                               TRUE) &&
588                !DosFindFirst(fullname,
589                              &hdir,
590                              FILE_NORMAL | FILE_DIRECTORY |
591                              FILE_ARCHIVED | FILE_SYSTEM |
592                              FILE_HIDDEN | FILE_READONLY,
593                              &fb4, sizeof(fb4), &nm, FIL_QUERYEASIZE)) {
594              DosFindClose(hdir);
595              priority_normal();
596              *fb4.achName = 0;
597              ullTotalBytes = FillInRecordFromFFB(dcd->hwndCnr,
598                                                  pci,
599                                                  fullname, &fb4, FALSE, dcd);
600              dcd->ullTotalBytes += ullTotalBytes;
601              pciP = pci;
602              pci = (PCNRITEM) pci->rc.preccNextRecord;
603            }
604            else {
605              pciT = pci;
606              pci = (PCNRITEM) pci->rc.preccNextRecord;
607              if (pciP)
608                pciP->rc.preccNextRecord = (PMINIRECORDCORE) pci;
609              else
610                pciFirst = pci;
611              FreeCnrItem(hwnd, pciT);
612              ulMaxFiles--;
613            }
614            DosSleep(1);
615          }
616          if (ulMaxFiles) {
617            memset(&ri, 0, sizeof(RECORDINSERT));
618            ri.cb = sizeof(RECORDINSERT);
619            ri.pRecordOrder = (PRECORDCORE) CMA_END;
620            ri.pRecordParent = (PRECORDCORE) 0;
621            ri.zOrder = (ULONG) CMA_TOP;
622            ri.cRecordsInsert = ulMaxFiles;
623            ri.fInvalidateRecord = TRUE;
624            WinSendMsg(dcd->hwndCnr,
625                       CM_INSERTRECORD, MPFROMP(pciFirst), MPFROMP(&ri));
626            PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
627          }
628        }
629      }
630    }
631    if (dcd->flWindowAttr & CV_DETAIL)
632      WinSendDlgItemMsg(hwnd,
633                        COLLECTOR_CNR,
634                        CM_INVALIDATERECORD,
635                        MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
636    return 0;
637
638  case UM_COLLECTFROMFILE:
639    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
640    if (dcd && mp1) {
641      FILESTATUS4 fs4;
642      PCNRITEM pci;
643      RECORDINSERT ri;
644      CHAR fullname[1024], *p;
645      FILE *fp;
646      ULONG errs = 0;
647      BOOL first = FALSE;
648      size_t c;
649
650      fp = _fsopen((CHAR *) mp1, "r", SH_DENYNO);
651      if (fp) {
652        while (!feof(fp)) {
653          // Avoid too much noise if collecting from binary file - oops
654          if (!fgets(fullname, sizeof(fullname), fp)) {
655            if (ferror(fp))
656              Runtime_Error(pszSrcFile, __LINE__, "fgets");
657            break;
658          }
659
660          c = strlen(fullname);
661          if (c + 1 >= sizeof(fullname))
662            errs++;
663          else if (!c || (fullname[c - 1] != '\n' && fullname[c - 1] != '\r'))
664            errs++;
665          else {
666            bstripcr(fullname);
667
668            if (*fullname == '\"') {
669              memmove(fullname, fullname + 1, strlen(fullname) + 1);
670              lstrip(fullname);
671              p = strchr(fullname, '\"');
672              if (p)
673                *p = 0;
674              rstrip(fullname);
675            }
676            else {
677              p = strchr(fullname, ' ');
678              if (p)
679                *p = 0;
680            }
681            /* fullname now contains name of file to collect */
682            DosError(FERR_DISABLEHARDERR);
683            if (IsFullName(fullname) &&
684                !IsRoot(fullname) &&
685                !DosQueryPathInfo(fullname,
686                                  FIL_QUERYEASIZE,
687                                  &fs4,
688                                  sizeof(fs4)) &&
689                !FindCnrRecord(dcd->hwndCnr,
690                               fullname, NULL, FALSE, FALSE, TRUE)) {
691              /* collect it */
692              pci = WinSendMsg(dcd->hwndCnr,
693                               CM_ALLOCRECORD,
694                               MPFROMLONG(EXTRA_RECORD_BYTES),
695                               MPFROMLONG(1));
696              if (pci) {
697                dcd->ullTotalBytes += FillInRecordFromFSA(dcd->hwndCnr, pci,
698                                                          fullname,
699                                                          &fs4, FALSE, dcd);
700                memset(&ri, 0, sizeof(RECORDINSERT));
701                ri.cb = sizeof(RECORDINSERT);
702                ri.pRecordOrder = (PRECORDCORE) CMA_END;
703                ri.pRecordParent = (PRECORDCORE) 0;
704                ri.zOrder = (ULONG) CMA_TOP;
705                ri.cRecordsInsert = 1;
706                ri.fInvalidateRecord = TRUE;
707                WinSendMsg(dcd->hwndCnr, CM_INSERTRECORD,
708                           MPFROMP(pci), MPFROMP(&ri));
709              }
710            }
711            else
712              errs++;
713          }
714          if (errs > (first ? 0 : 50)) {
715            /* prevent runaway on bad file */
716            APIRET ret = saymsg(MB_YESNO, dcd->hwndCnr,
717                                GetPString(IDS_COLLECTNOLISTHDRTEXT),
718                                GetPString(IDS_COLLECTNOLISTTEXT),
719                                (CHAR *) mp1);
720
721            if (ret == MBID_NO)
722              break;
723            if (!first)
724              errs = 0;
725            else
726              first = FALSE;
727          }
728        }                               // while not eof
729        fclose(fp);
730      }
731    }
732    xfree(mp1);
733    return 0;
734
735  case UM_SELECT:
736    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
737    if (dcd) {
738      switch (SHORT1FROMMP(mp1)) {
739      case IDM_SELECTLIST:
740        {
741          CHAR filename[CCHMAXPATH], *p, *pp;
742
743          strcpy(filename, "*.LST");
744          size = CCHMAXPATH;
745          PrfQueryProfileData(fmprof, appname, "SaveToListName", filename,
746                              &size);
747          pp = strrchr(filename, '\\');
748          if (!pp)
749            pp = filename;
750          p = strrchr(pp, '.');
751          if (p && *(p + 1) && p > pp + 1) {
752            if (pp > filename)
753              pp++;
754            *pp = '*';
755            pp++;
756            if (p > pp)
757              memmove(pp, p, strlen(p) + 1);
758          }
759          if (insert_filename(hwnd, filename, FALSE, FALSE))
760            SelectList(dcd->hwndCnr, TRUE, FALSE, FALSE, NULL, filename,
761                       NULL);
762        }
763        break;
764      case IDM_SELECTALL:
765        SelectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, FALSE);
766        break;
767      case IDM_DESELECTALL:
768        DeselectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, FALSE);
769        break;
770      case IDM_SELECTALLFILES:
771        SelectAll(dcd->hwndCnr, TRUE, FALSE, NULL, NULL, FALSE);
772        break;
773      case IDM_DESELECTALLFILES:
774        DeselectAll(dcd->hwndCnr, TRUE, FALSE, NULL, NULL, FALSE);
775        break;
776      case IDM_SELECTALLDIRS:
777        SelectAll(dcd->hwndCnr, FALSE, TRUE, NULL, NULL, FALSE);
778        break;
779      case IDM_DESELECTALLDIRS:
780        DeselectAll(dcd->hwndCnr, FALSE, TRUE, NULL, NULL, FALSE);
781        break;
782      case IDM_DESELECTMASK:
783      case IDM_SELECTMASK:
784        {
785          MASK mask;
786          PCNRITEM pci = (PCNRITEM) mp2;
787
788          memset(&mask, 0, sizeof(MASK));
789          mask.fNoAttribs = TRUE;
790          mask.fNoDirs = TRUE;
791          mask.fText = TRUE;
792          strcpy(mask.prompt,
793                 GetPString((SHORT1FROMMP(mp1) == IDM_SELECTMASK) ?
794                            IDS_SELECTFILTERTEXT : IDS_DESELECTFILTERTEXT));
795          if (pci && (INT) pci != -1)
796            strcpy(mask.szMask, pci->pszFileName);
797          if (WinDlgBox(HWND_DESKTOP, dcd->hwndCnr, PickMaskDlgProc,
798                        FM3ModHandle, MSK_FRAME, MPFROMP(&mask))) {
799            if (SHORT1FROMMP(mp1) == IDM_SELECTMASK)
800              SelectAll(dcd->hwndCnr, TRUE, TRUE, mask.szMask, mask.szText,
801                        FALSE);
802            else
803              DeselectAll(dcd->hwndCnr, TRUE, TRUE, mask.szMask, mask.szText,
804                          FALSE);
805          }
806        }
807
808      case IDM_DESELECTCLIP:
809      case IDM_SELECTCLIP:
810        {
811          CHAR **list;
812
813          list = ListFromClipboard(hwnd);
814          if (list) {
815            SelectList(dcd->hwndCnr, TRUE, FALSE,
816                       (SHORT1FROMMP(mp1) == IDM_DESELECTCLIP),
817                       NULL, NULL, list);
818            FreeList(list);
819          }
820        }
821        break;
822
823      case IDM_INVERT:
824        InvertAll(dcd->hwndCnr);
825        break;
826      }
827    }
828    return 0;
829
830  case UM_MASSACTION:
831    if (mp1) {
832      dcd = WinQueryWindowPtr(hwnd, QWL_USER);
833      if (dcd) {
834        WORKER *wk;
835
836        wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
837        if (!wk)
838          FreeListInfo((LISTINFO *) mp1);
839        else {
840          wk->size = sizeof(WORKER);
841          wk->hwndCnr = dcd->hwndCnr;
842          wk->hwndParent = dcd->hwndParent;
843          wk->hwndFrame = dcd->hwndFrame;
844          wk->hwndClient = dcd->hwndClient;
845          wk->li = (LISTINFO *) mp1;
846          strcpy(wk->directory, dcd->directory);
847          if (_beginthread(MassAction, NULL, 122880, (PVOID) wk) == -1) {
848            Runtime_Error(pszSrcFile, __LINE__,
849                          GetPString(IDS_COULDNTSTARTTHREADTEXT));
850            free(wk);
851            FreeListInfo((LISTINFO *) mp1);
852          }
853        }
854      }
855    }
856    return 0;
857
858  case UM_ACTION:
859    if (mp1) {
860      dcd = WinQueryWindowPtr(hwnd, QWL_USER);
861      if (dcd) {
862        WORKER *wk;
863
864        wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
865        if (!wk)
866          FreeListInfo((LISTINFO *) mp1);
867        else {
868          wk->size = sizeof(WORKER);
869          wk->hwndCnr = dcd->hwndCnr;
870          wk->hwndParent = dcd->hwndParent;
871          wk->hwndFrame = dcd->hwndFrame;
872          wk->hwndClient = dcd->hwndClient;
873          wk->li = (LISTINFO *) mp1;
874          strcpy(wk->directory, dcd->directory);
875          if (_beginthread(Action, NULL, 122880, (PVOID) wk) == -1) {
876            Runtime_Error(pszSrcFile, __LINE__,
877                          GetPString(IDS_COULDNTSTARTTHREADTEXT));
878            free(wk);
879            FreeListInfo((LISTINFO *) mp1);
880          }
881        }
882      }
883    }
884    return 0;
885
886  case WM_CLOSE:
887    WinDestroyWindow(hwnd);
888    break;
889
890  case WM_DESTROY:
891    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
892    if (dcd) {
893      INT x;
894
895      dcd->stopflag = 1;
896      // Allow rescan logic to quiesce
897      for (x = 0; x < 10 && dcd->amextracted; x++)
898        DosSleep(250);
899      WinSendMsg(dcd->hwndCnr, UM_CLOSE, MPVOID, MPVOID);
900      FreeList(dcd->lastselection);
901      free(dcd);
902    }
903    DosPostEventSem(CompactSem);
904    if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
905      WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
906    break;
907  }
908  return WinDefWindowProc(hwnd, msg, mp1, mp2);
909}
910
911MRESULT EXPENTRY CollectorCnrWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
912                                     MPARAM mp2)
913{
914  DIRCNRDATA *dcd = INSTDATA(hwnd);
915  ULONG size;
916
917  static INT savedSortFlags;
918
919  switch (msg) {
920  case DM_PRINTOBJECT:
921    return MRFROMLONG(DRR_TARGET);
922
923  case DM_DISCARDOBJECT:
924    if (dcd)
925      return WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
926    else
927      return MRFROMLONG(DRR_TARGET);
928
929  case WM_CHAR:
930    shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
931    if (SHORT1FROMMP(mp1) & KC_KEYUP)
932      return (MRESULT) TRUE;
933    if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
934      switch (SHORT2FROMMP(mp2)) {
935      case VK_DELETE:
936        if ((shiftstate & KC_CTRL) == KC_CTRL)
937          PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PERMDELETE, 0), MPVOID);
938        else if ((shiftstate & KC_SHIFT) == KC_SHIFT)
939          PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_SAVETOCLIP, 0), MPVOID);
940        else
941          PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DELETE, 0), MPVOID);
942        break;
943      }
944    }
945    if (shiftstate || fNoSearch)
946      break;
947    if (SHORT1FROMMP(mp1) & KC_CHAR) {
948      ULONG thistime, len;
949      SEARCHSTRING srch;
950      PCNRITEM pci;
951
952      if (!dcd)
953        break;
954      switch (SHORT1FROMMP(mp2)) {
955      case '\x1b':
956      case '\r':
957      case '\n':
958        dcd->lasttime = 0;
959        *dcd->szCommonName = 0;
960        break;
961      default:
962        thistime = WinQueryMsgTime(WinQueryAnchorBlock(hwnd));
963        if (thistime > dcd->lasttime + 1250)
964          *dcd->szCommonName = 0;
965        dcd->lasttime = thistime;
966        if (SHORT1FROMMP(mp2) == ' ' && !dcd->szCommonName)
967          break;
968      KbdRetry:
969        len = strlen(dcd->szCommonName);
970        if (len >= CCHMAXPATH - 1) {
971          *dcd->szCommonName = 0;
972          len = 0;
973        }
974        dcd->szCommonName[len] = toupper(SHORT1FROMMP(mp2));
975        dcd->szCommonName[len + 1] = 0;
976        memset(&srch, 0, sizeof(SEARCHSTRING));
977        srch.cb = sizeof(SEARCHSTRING);
978        srch.pszSearch = dcd->szCommonName;
979        srch.fsPrefix = TRUE;
980        srch.fsCaseSensitive = FALSE;
981        srch.usView = CV_ICON;
982        pci = WinSendMsg(hwnd, CM_SEARCHSTRING, MPFROMP(&srch),
983                         MPFROMLONG(CMA_FIRST));
984        if (pci && (INT) pci != -1) {
985          USHORT attrib = CRA_CURSORED;
986
987          /* make found item current item */
988          if (!stricmp(pci->pszFileName, dcd->szCommonName))
989            attrib |= CRA_SELECTED;
990          WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPFROMP(pci),
991                     MPFROM2SHORT(TRUE, attrib));
992          /* make sure that record shows in viewport */
993          ShowCnrRecord(hwnd, (PMINIRECORDCORE) pci);
994          return (MRESULT) TRUE;
995        }
996        else {
997          if (SHORT1FROMMP(mp2) == ' ') {
998            dcd->szCommonName[len] = 0;
999            break;
1000          }
1001          *dcd->szCommonName = 0;
1002          dcd->lasttime = 0;
1003          if (len)                      // retry as first letter if no match
1004
1005            goto KbdRetry;
1006        }
1007        break;
1008      }
1009    }
1010    break;
1011
1012  case WM_MOUSEMOVE:
1013  case WM_BUTTON1UP:
1014  case WM_BUTTON2UP:
1015  case WM_BUTTON3UP:
1016  case WM_CHORD:
1017    shiftstate = (SHORT2FROMMP(mp2) & (KC_SHIFT | KC_ALT | KC_CTRL));
1018    break;
1019
1020  case WM_BUTTON1MOTIONEND:
1021    {
1022      CNRINFO cnri;
1023
1024      memset(&cnri, 0, sizeof(CNRINFO));
1025      cnri.cb = sizeof(CNRINFO);
1026      if (WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
1027                     MPFROMLONG(sizeof(CNRINFO)))) {
1028        if (cnri.flWindowAttr & CV_DETAIL)
1029          PrfWriteProfileData(fmprof, appname, "CollectorCnrSplitBar",
1030                              (PVOID) & cnri.xVertSplitbar, sizeof(LONG));
1031      }
1032    }
1033    break;
1034
1035  case WM_PRESPARAMCHANGED:
1036    PresParamChanged(hwnd, "Collector", mp1, mp2);
1037    break;
1038
1039  case UM_COMPARE:
1040    if (dcd && mp1 && mp2) {
1041      COMPARE *cmp;
1042      CHAR *leftdir = (CHAR *) mp1, *rightdir = (CHAR *) mp2;
1043
1044      if (!IsFile(leftdir) && !IsFile(rightdir)) {
1045        cmp = xmallocz(sizeof(COMPARE), pszSrcFile, __LINE__);
1046        if (cmp) {
1047          cmp->size = sizeof(COMPARE);
1048          strcpy(cmp->leftdir, leftdir);
1049          strcpy(cmp->rightdir, rightdir);
1050          cmp->hwndParent = dcd->hwndParent;
1051          cmp->dcd.hwndParent = dcd->hwndParent;
1052          WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, CompareDlgProc,
1053                    FM3ModHandle, COMP_FRAME, MPFROMP(cmp));
1054        }
1055      }
1056    }
1057    return 0;
1058
1059  case UM_UPDATERECORDLIST:
1060    if (dcd && mp1)
1061      WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
1062    return 0;
1063
1064  case UM_UPDATERECORD:
1065    if (dcd && mp1) {
1066      CHAR *filename;
1067
1068      filename = mp1;
1069      if (filename)
1070        UpdateCnrRecord(hwnd, filename, TRUE, dcd);
1071    }
1072    return 0;
1073
1074  case WM_SETFOCUS:
1075    /*
1076     * put name of our window on status line
1077     */
1078    if (dcd && hwndStatus && mp2) {
1079      PCNRITEM pci = NULL;
1080
1081      if (fAutoView && hwndMain) {
1082        pci = WinSendMsg(hwnd,
1083                         CM_QUERYRECORDEMPHASIS,
1084                         MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1085        if (pci && (INT) pci != -1 &&
1086            (!(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_SLOW)))
1087          WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
1088        else
1089          WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1090      }
1091      if (dcd->amextracted)
1092        WinSetWindowText(hwndStatus2, GetPString(IDS_INSEEKSCANTEXT));  // Say working
1093      WinSendMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1094    }
1095    break;
1096
1097  case UM_RESCAN:
1098    if (dcd) {
1099      CNRINFO cnri;
1100      CHAR s[CCHMAXPATH + 69], tb[81], tf[81], *p;
1101      PCNRITEM pci = NULL;
1102
1103      memset(&cnri, 0, sizeof(CNRINFO));
1104      cnri.cb = sizeof(CNRINFO);
1105      WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
1106                 MPFROMLONG(sizeof(CNRINFO)));
1107      dcd->totalfiles = cnri.cRecords;
1108      commafmt(tf, sizeof(tf), dcd->totalfiles);
1109      CommaFmtULL(tb, sizeof(tb), dcd->ullTotalBytes, ' ');
1110      sprintf(s, "%s / %s", tf, tb);
1111      WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, s);
1112
1113      commafmt(tf, sizeof(tf), dcd->selectedfiles);
1114      CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, ' ');
1115      sprintf(s, "%s / %s", tf, tb);
1116      WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
1117
1118      if (hwndStatus &&
1119          dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
1120        if (hwndMain) {
1121          pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1122                           MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1123          if (pci && (INT) pci != -1)
1124            PostMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
1125          else
1126            PostMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1127        }
1128        if (!fMoreButtons)
1129          sprintf(s, " %s%s%s%s", GetPString(IDS_COLLECTORTEXT),
1130                  (*dcd->mask.szMask || dcd->mask.antiattr ||
1131                   dcd->mask.attrFile != ALLATTRS) ? "  (" : NullStr,
1132                  (*dcd->mask.szMask) ? dcd->mask.szMask :
1133                  (dcd->mask.antiattr ||
1134                   dcd->mask.attrFile != ALLATTRS) ?
1135                  GetPString(IDS_ATTRTEXT) : NullStr,
1136                  (*dcd->mask.szMask || dcd->mask.antiattr ||
1137                   dcd->mask.attrFile != ALLATTRS) ? ")" : NullStr);
1138        else
1139          strcpy(s, GetPString(IDS_COLLECTORTEXT));
1140        WinSetWindowText(hwndStatus, s);
1141        if (!pci)
1142          pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1143                           MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1144        if (pci && (INT) pci != -1) {
1145          BOOL fStatus2Used = FALSE;
1146
1147          if (fSplitStatus && hwndStatus2) {
1148            if (pci->attrFile & FILE_DIRECTORY)
1149              p = pci->pszFileName;
1150            else {
1151              p = strrchr(pci->pszFileName, '\\');
1152              if (p) {
1153                if (*(p + 1))
1154                  p++;
1155                else
1156                  p = pci->pszFileName;
1157              }
1158              else
1159                p = pci->pszFileName;
1160            }
1161            CommaFmtULL(tb, sizeof(tb), pci->cbFile + pci->easize, ' ');
1162            if (!fMoreButtons) {
1163              sprintf(s, " %s  %04u/%02u/%02u %02u:%02u:%02u  [%s]  %s",
1164                      tb, pci->date.year, pci->date.month,
1165                      pci->date.day, pci->time.hours, pci->time.minutes,
1166                      pci->time.seconds, pci->pszDispAttr, p);
1167            }
1168            else {
1169              if (pci->cbFile + pci->easize > 1024)
1170                CommaFmtULL(tf, sizeof(tf), pci->cbFile + pci->easize, 'K');
1171              else
1172                *tf = 0;
1173              sprintf(s, GetPString(IDS_STATUSSIZETEXT),
1174                      tb, *tf ? " (" : NullStr, tf, *tf ? ")" : NullStr);
1175            }
1176            WinSetWindowText(hwndStatus2, s);
1177            fStatus2Used = TRUE;
1178          }
1179          if (fMoreButtons) {
1180            WinSetWindowText(hwndName, pci->pszFileName);
1181            sprintf(s, "%04u/%02u/%02u %02u:%02u:%02u",
1182                    pci->date.year, pci->date.month,
1183                    pci->date.day, pci->time.hours, pci->time.minutes,
1184                    pci->time.seconds);
1185            WinSetWindowText(hwndDate, s);
1186            WinSetWindowText(hwndAttr, pci->pszDispAttr);
1187          }
1188          if (dcd->amextracted && hwndStatus2 && !fStatus2Used)
1189            WinSetWindowText(hwndStatus2, GetPString(IDS_INSEEKSCANTEXT));      // Say working
1190        }
1191        else {
1192          if (hwndStatus2)
1193            WinSetWindowText(hwndStatus2, NullStr);
1194          if (fMoreButtons) {
1195            WinSetWindowText(hwndName, NullStr);
1196            WinSetWindowText(hwndDate, NullStr);
1197            WinSetWindowText(hwndAttr, NullStr);
1198          }
1199        }
1200      }
1201    }
1202    return 0;
1203
1204  case UM_CONTAINER_FILLED:
1205    DosBeep(1000, 50);                  // Wake up user?
1206    WinSendMsg(hwnd,
1207               CM_INVALIDATERECORD,
1208               MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
1209    disable_menuitem(WinWindowFromID(WinQueryWindow(hwndMain, QW_PARENT),
1210                                     FID_MENU), IDM_GREP, FALSE);
1211    PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1212    if (dcd) {
1213      dcd->stopflag = 0;
1214      dcd->amextracted = FALSE;         // Say not busy
1215      if (dcd->namecanchange) {
1216        if (!PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID))
1217          WinSendMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1218      }
1219      else
1220        WinSetWindowPos(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
1221                                       QW_PARENT),
1222                        HWND_TOP,
1223                        0, 0, 0, 0, SWP_SHOW | SWP_RESTORE | SWP_ZORDER);
1224    }
1225    return 0;
1226
1227  case UM_SETUP:
1228    if (dcd) {
1229      if (!dcd->hwndObject) {
1230        /* first time through -- set things up */
1231
1232        CNRINFO cnri;
1233
1234        RestorePresParams(hwnd, "Collector");
1235        LoadDetailsSwitches("Collector", dcd);
1236
1237        dcd->amextracted = FALSE;       // Say not busy
1238        dcd->stopflag = 0;
1239        memset(&cnri, 0, sizeof(CNRINFO));
1240        cnri.cb = sizeof(CNRINFO);
1241        WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
1242                   MPFROMLONG(sizeof(CNRINFO)));
1243        cnri.cyLineSpacing = 0;
1244        cnri.cxTreeIndent = 12;
1245
1246        cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT | CV_DETAIL));
1247        cnri.flWindowAttr |= (CV_NAME | CA_DETAILSVIEWTITLES |
1248                              CV_MINI | CV_FLOW);
1249        cnri.pSortRecord = (PVOID) SortCollectorCnr;
1250
1251        size = sizeof(ULONG);
1252        PrfQueryProfileData(fmprof, appname, "CollectorflWindowAttr",
1253                            (PVOID) & cnri.flWindowAttr, &size);
1254        size = sizeof(MASK);
1255        if (PrfQueryProfileSize(fmprof, appname, "CollectorFilter", &size) &&
1256            size) {
1257          PrfQueryProfileData(fmprof, appname, "CollectorFilter", &dcd->mask,
1258                              &size);
1259          SetMask(NULL, &dcd->mask);
1260        }
1261        else {
1262          dcd->mask.attrFile = (FILE_NORMAL | FILE_READONLY |
1263                                FILE_DIRECTORY | FILE_HIDDEN |
1264                                FILE_SYSTEM | FILE_ARCHIVED);
1265          dcd->mask.antiattr = 0;
1266        }
1267
1268        *(dcd->mask.prompt) = 0;
1269
1270        cnri.flWindowAttr |= CV_FLOW;
1271        cnri.flWindowAttr &= (~(CA_MIXEDTARGETEMPH | CA_ORDEREDTARGETEMPH));
1272        dcd->flWindowAttr = cnri.flWindowAttr;
1273        WinSendMsg(hwnd, CM_SETCNRINFO, MPFROMP(&cnri),
1274                   MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
1275                              CMA_CXTREEINDENT | CMA_PSORTRECORD));
1276        SetCnrCols(hwnd, FALSE);
1277        AdjustCnrColsForPref(hwnd, NULL, dcd, FALSE);
1278
1279        /* fix splitbar for collector container */
1280        cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 32;
1281        size = sizeof(LONG);
1282        PrfQueryProfileData(fmprof, appname, "CollectorCnrSplitBar",
1283                            &cnri.xVertSplitbar, &size);
1284        if (cnri.xVertSplitbar <= 0)
1285          cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 32;
1286        WinSendMsg(hwnd, CM_SETCNRINFO, MPFROMP(&cnri),
1287                   MPFROMLONG(CMA_XVERTSPLITBAR));
1288
1289        if (_beginthread(MakeObjWin, NULL, 245760, (PVOID) dcd) == -1) {
1290          Runtime_Error(pszSrcFile, __LINE__,
1291                        GetPString(IDS_COULDNTSTARTTHREADTEXT));
1292          PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1293          return 0;
1294        }
1295        else
1296          DosSleep(64);
1297      }
1298      SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1299                                DIR_FILTER), &dcd->mask, FALSE);
1300      SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1301                              DIR_SORT), CollectorsortFlags, FALSE);
1302      SayView(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1303                              DIR_VIEW), dcd->flWindowAttr);
1304    }
1305    else {
1306      PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1307      return 0;
1308    }
1309    return 0;
1310
1311  case WM_MENUEND:
1312    if (dcd) {
1313      HWND hwndMenu = (HWND) mp2;
1314
1315      if (hwndMenu == CollectorCnrMenu || hwndMenu == CollectorFileMenu ||
1316          hwndMenu == CollectorDirMenu) {
1317        MarkAll(hwnd, TRUE, FALSE, TRUE);
1318        if (dcd->cnremphasized) {
1319          WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1320                     MPFROM2SHORT(FALSE, CRA_SOURCE));
1321          dcd->cnremphasized = FALSE;
1322        }
1323      }
1324    }
1325    break;
1326
1327  case UM_OPENWINDOWFORME:
1328    if (dcd) {
1329      if (mp1 && !IsFile((CHAR *) mp1))
1330        OpenDirCnr(HWND_DESKTOP, hwndMain, dcd->hwndFrame, FALSE, (PSZ) mp1);
1331      else if (mp1 && IsFile(mp1) == 1)
1332        StartArcCnr(HWND_DESKTOP,
1333                    dcd->hwndFrame, (CHAR *) mp1, 4, (ARC_TYPE *) mp2);
1334    }
1335    return 0;
1336
1337  case MM_PORTHOLEINIT:
1338    if (dcd) {
1339      switch (SHORT1FROMMP(mp1)) {
1340      case 0:
1341      case 1:
1342        {
1343          ULONG wmsg;
1344
1345          wmsg = (SHORT1FROMMP(mp1) == 0) ? UM_FILESMENU : UM_VIEWSMENU;
1346          PortholeInit((HWND) WinSendMsg(dcd->hwndClient, wmsg, MPVOID,
1347                                         MPVOID), mp1, mp2);
1348        }
1349        break;
1350      }
1351    }
1352    break;
1353
1354  case UM_INITMENU:
1355  case WM_INITMENU:
1356    if (dcd) {
1357      switch (SHORT1FROMMP(mp1)) {
1358      case IDM_VIEWSMENU:
1359        SetViewMenu((HWND) mp2, dcd->flWindowAttr);
1360        WinEnableMenuItem((HWND) mp2, IDM_RESELECT,
1361                          (dcd->lastselection != NULL));
1362        break;
1363
1364      case IDM_DETAILSSETUP:
1365        SetDetailsSwitches((HWND) mp2, dcd);
1366        break;
1367
1368      case IDM_COMMANDSMENU:
1369        SetupCommandMenu((HWND) mp2, hwnd);
1370        break;
1371
1372      case IDM_SORTSUBMENU:
1373        SetSortChecks((HWND) mp2, CollectorsortFlags);
1374        break;
1375      }
1376      dcd->hwndLastMenu = (HWND) mp2;
1377    }
1378    if (msg == WM_INITMENU)
1379      break;
1380    return 0;
1381
1382  case UM_COLLECTFROMFILE:
1383    if (mp1) {
1384      if (!dcd) {
1385        free(mp1);
1386        Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
1387      }
1388      else {
1389        if (!PostMsg(dcd->hwndObject, UM_COLLECTFROMFILE, mp1, mp2)) {
1390          Runtime_Error(pszSrcFile, __LINE__, "PostMsg");
1391          free(mp1);
1392        }
1393      }
1394    }
1395    return 0;
1396
1397  case UM_COMMAND:
1398    if (mp1) {
1399      if (dcd) {
1400        if (!PostMsg(dcd->hwndObject, UM_COMMAND, mp1, mp2)) {
1401          Runtime_Error(pszSrcFile, __LINE__, "PostMsg");
1402          FreeListInfo((LISTINFO *) mp1);
1403        }
1404        else
1405          return (MRESULT) TRUE;
1406      }
1407      else
1408        FreeListInfo((LISTINFO *) mp1);
1409    }
1410    return 0;
1411
1412  case UM_NOTIFY:
1413    if (mp2)
1414      AddNote((CHAR *) mp2);
1415    return 0;
1416
1417  case WM_COMMAND:
1418    DosError(FERR_DISABLEHARDERR);
1419    if (dcd) {
1420      switch (SHORT1FROMMP(mp1)) {
1421      case IDM_SETTARGET:
1422        SetTargetDir(hwnd, FALSE);
1423        break;
1424
1425      case IDM_CONTEXTMENU:
1426        {
1427          PCNRITEM pci;
1428
1429          pci = (PCNRITEM) CurrentRecord(hwnd);
1430          PostMsg(hwnd, WM_CONTROL, MPFROM2SHORT(COLLECTOR_CNR,
1431                                                 CN_CONTEXTMENU),
1432                  MPFROMP(pci));
1433        }
1434        break;
1435
1436      case IDM_SHOWALLFILES:
1437        {
1438          PCNRITEM pci;
1439
1440          pci = WinSendMsg(hwnd,
1441                           CM_QUERYRECORDEMPHASIS,
1442                           MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1443          if (pci && (INT) pci != -1) {
1444            static CHAR dirname[CCHMAXPATH];
1445
1446            strcpy(dirname, pci->pszFileName);
1447            MakeValidDir(dirname);
1448            StartSeeAll(HWND_DESKTOP, FALSE, dirname);
1449          }
1450        }
1451        break;
1452
1453      case IDM_BEGINEDIT:
1454        OpenEdit(hwnd);
1455        break;
1456
1457      case IDM_ENDEDIT:
1458        WinSendMsg(hwnd, CM_CLOSEEDIT, MPVOID, MPVOID);
1459        break;
1460
1461      case IDM_SHOWSELECT:
1462        QuickPopup(hwnd, dcd,
1463                   CheckMenu(&CollectorCnrMenu, COLLECTORCNR_POPUP),
1464                   IDM_SELECTSUBMENU);
1465        break;
1466
1467      case IDM_SHOWSORT:
1468        QuickPopup(hwnd, dcd,
1469                   CheckMenu(&CollectorCnrMenu, COLLECTORCNR_POPUP),
1470                   IDM_SORTSUBMENU);
1471        break;
1472
1473      case IDM_VIEWORARC:
1474        {
1475          SWP swp;
1476          PCNRITEM pci;
1477
1478          pci = (PCNRITEM) WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1479                                      MPFROMLONG(CMA_FIRST),
1480                                      MPFROMSHORT(CRA_CURSORED));
1481          if (pci && (INT) pci != -1) {
1482            WinQueryWindowPos(dcd->hwndFrame, &swp);
1483            DefaultViewKeys(hwnd, dcd->hwndFrame, dcd->hwndParent, &swp,
1484                            pci->pszFileName);
1485          }
1486        }
1487        break;
1488
1489      case IDM_SEEALL:
1490        StartSeeAll(HWND_DESKTOP, FALSE, NULL);
1491        break;
1492
1493      case IDM_COLLECTSELECT:
1494        {
1495          CHAR filename[CCHMAXPATH], *p, *pp;
1496
1497          strcpy(filename, "*.LST");
1498          size = CCHMAXPATH;
1499          PrfQueryProfileData(fmprof, appname, "SaveToListName",
1500                              filename, &size);
1501          pp = strrchr(filename, '\\');
1502          if (!pp)
1503            pp = filename;
1504          p = strrchr(pp, '.');
1505          if (p && *(p + 1) && p > pp + 1) {
1506            if (pp > filename)
1507              pp++;
1508            *pp = '*';
1509            pp++;
1510            if (p > pp)
1511              memmove(pp, p, strlen(p) + 1);
1512          }
1513          if (insert_filename(hwnd, filename, FALSE, FALSE)) {
1514            p = xstrdup(filename, pszSrcFile, __LINE__);
1515            if (p) {
1516              if (!PostMsg(hwnd, UM_COLLECTFROMFILE, MPFROMP(p), MPVOID))
1517                free(p);
1518            }
1519          }
1520        }
1521        break;
1522
1523      case IDM_NOTEBOOK:
1524        if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndParent))
1525          PostMsg(dcd->hwndParent, msg, mp1, mp2);
1526        else
1527          WinDlgBox(HWND_DESKTOP, hwnd, CfgDlgProc, FM3ModHandle,
1528                    CFG_FRAME, (PVOID) "Collector");
1529        break;
1530
1531      case IDM_RESELECT:
1532        SelectList(hwnd, FALSE, FALSE, FALSE, NULL, NULL, dcd->lastselection);
1533        break;
1534
1535      case IDM_HELP:
1536        if (hwndHelp)
1537          WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
1538                     MPFROM2SHORT(HELP_COLLECT, 0),
1539                     MPFROMSHORT(HM_RESOURCEID));
1540        break;
1541
1542      case IDM_SORTNONE:
1543      case IDM_SORTSMARTNAME:
1544      case IDM_SORTNAME:
1545      case IDM_SORTFILENAME:
1546      case IDM_SORTSIZE:
1547      case IDM_SORTEASIZE:
1548      case IDM_SORTFIRST:
1549      case IDM_SORTLAST:
1550      case IDM_SORTLWDATE:
1551      case IDM_SORTLADATE:
1552      case IDM_SORTCRDATE:
1553      case IDM_SORTSUBJECT:
1554        savedSortFlags = CollectorsortFlags;
1555        CollectorsortFlags &= (SORT_REVERSE | SORT_DIRSFIRST | SORT_DIRSLAST);
1556      case IDM_SORTDIRSFIRST:
1557      case IDM_SORTDIRSLAST:
1558      case IDM_SORTREVERSE:
1559        switch (SHORT1FROMMP(mp1)) {
1560        case IDM_SORTSUBJECT:
1561          CollectorsortFlags |= SORT_SUBJECT;
1562          break;
1563        case IDM_SORTNONE:
1564          CollectorsortFlags |= SORT_NOSORT;
1565          break;
1566        case IDM_SORTSMARTNAME:
1567          if (~savedSortFlags & SORT_FILENAME)
1568            CollectorsortFlags |= SORT_FILENAME;
1569          break;
1570        case IDM_SORTFILENAME:
1571          CollectorsortFlags |= SORT_FILENAME;
1572          break;
1573        case IDM_SORTSIZE:
1574          CollectorsortFlags |= SORT_SIZE;
1575          break;
1576        case IDM_SORTEASIZE:
1577          CollectorsortFlags |= SORT_EASIZE;
1578          break;
1579        case IDM_SORTFIRST:
1580          CollectorsortFlags |= SORT_FIRSTEXTENSION;
1581          break;
1582        case IDM_SORTLAST:
1583          CollectorsortFlags |= SORT_LASTEXTENSION;
1584          break;
1585        case IDM_SORTLWDATE:
1586          CollectorsortFlags |= SORT_LWDATE;
1587          break;
1588        case IDM_SORTLADATE:
1589          CollectorsortFlags |= SORT_LADATE;
1590          break;
1591        case IDM_SORTCRDATE:
1592          CollectorsortFlags |= SORT_CRDATE;
1593          break;
1594        case IDM_SORTDIRSFIRST:
1595          if (CollectorsortFlags & SORT_DIRSFIRST)
1596            CollectorsortFlags &= (~SORT_DIRSFIRST);
1597          else {
1598            CollectorsortFlags |= SORT_DIRSFIRST;
1599            CollectorsortFlags &= (~SORT_DIRSLAST);
1600          }
1601          break;
1602        case IDM_SORTDIRSLAST:
1603          if (CollectorsortFlags & SORT_DIRSLAST)
1604            CollectorsortFlags &= (~SORT_DIRSLAST);
1605          else {
1606            CollectorsortFlags |= SORT_DIRSLAST;
1607            CollectorsortFlags &= (~SORT_DIRSFIRST);
1608          }
1609          break;
1610        case IDM_SORTREVERSE:
1611          if (CollectorsortFlags & SORT_REVERSE)
1612            CollectorsortFlags &= (~SORT_REVERSE);
1613          else
1614            CollectorsortFlags |= SORT_REVERSE;
1615          break;
1616        }
1617        PrfWriteProfileData(fmprof, appname, "CollectorSort",
1618                            &CollectorsortFlags, sizeof(INT));
1619        WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(SortCollectorCnr), MPVOID);
1620        SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1621                                DIR_SORT), CollectorsortFlags, FALSE);
1622        break;
1623
1624      case IDM_COLLECTFROMCLIP:
1625        {
1626          LISTINFO *li;
1627
1628          li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
1629          if (li) {
1630            li->list = ListFromClipboard(hwnd);
1631            if (!li->list || !li->list[0])
1632              FreeListInfo(li);
1633            else {
1634              li->type = IDM_COLLECT;
1635              if (!PostMsg(dcd->hwndObject, UM_COLLECT, MPFROMP(li), MPVOID))
1636                FreeListInfo(li);
1637            }
1638          }
1639        }
1640        break;
1641
1642      case IDM_REMOVE:
1643        if (fAutoView && hwndMain)
1644          PostMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1645        dcd->suspendview = 1;
1646        RemoveAll(hwnd, &dcd->ullTotalBytes, &dcd->totalfiles);
1647        dcd->suspendview = 0;
1648        PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1649        break;
1650
1651      case IDM_CLEARCNR:
1652        {
1653          PCNRITEM pci;
1654
1655          pci = (PCNRITEM) WinSendMsg(hwnd,
1656                                      CM_QUERYRECORD,
1657                                      MPVOID,
1658                                      MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
1659          if (pci && (INT) pci != -1) {
1660            RemoveCnrItems(hwnd, NULL, 0, CMA_FREE | CMA_INVALIDATE);
1661            dcd->ullTotalBytes = dcd->selectedbytes = dcd->selectedfiles =
1662              dcd->totalfiles = 0;
1663            PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1664          }
1665        }
1666        break;
1667
1668      case DID_CANCEL:
1669        if (dcd->amextracted)
1670          dcd->stopflag = 1;            // Request cancel
1671        break;
1672
1673      case IDM_COLLECTOR:
1674        if (mp2) {
1675          LISTINFO *li;
1676
1677          li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
1678          if (li) {
1679            li->list = mp2;
1680            if (!li->list || !li->list[0])
1681              FreeListInfo(li);
1682            else {
1683              li->type = IDM_COLLECT;
1684              if (!PostMsg(dcd->hwndObject, UM_COLLECT, MPFROMP(li), MPVOID))
1685                FreeListInfo(li);
1686            }
1687          }
1688          else
1689            FreeList(mp2);
1690        }
1691        break;
1692
1693      case IDM_UNDELETE:
1694        {
1695          PCNRITEM pci;
1696          CHAR path[CCHMAXPATH];
1697
1698          pci = (PCNRITEM) CurrentRecord(hwnd);
1699          if (pci) {
1700            strcpy(path, pci->pszFileName);
1701            MakeValidDir(path);
1702            WinDlgBox(HWND_DESKTOP, hwnd, UndeleteDlgProc, FM3ModHandle,
1703                      UNDEL_FRAME, MPFROMP(path));
1704          }
1705        }
1706        break;
1707
1708      case IDM_GREP:
1709        if (dcd->amextracted) {
1710          saymsg(MB_OK | MB_ICONASTERISK,
1711                 hwnd,
1712                 GetPString(IDS_WARNINGTEXT),
1713                 "Collector busy - please try again later");
1714        }
1715        else {
1716          if (WinDlgBox(HWND_DESKTOP, hwnd, GrepDlgProc,
1717                        FM3ModHandle, GREP_FRAME, (PVOID) & hwnd)) {
1718            dcd->amextracted = TRUE;    // Say busy scanning
1719            disable_menuitem(WinWindowFromID
1720                             (WinQueryWindow(hwndMain, QW_PARENT), FID_MENU),
1721                             IDM_GREP, TRUE);
1722            PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1723          }
1724        }
1725        break;
1726
1727      case IDM_RESORT:
1728        WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(SortCollectorCnr), MPVOID);
1729        break;
1730
1731      case IDM_FILTER:
1732        {
1733          BOOL empty = FALSE;
1734          PCNRITEM pci;
1735          CHAR *p;
1736
1737          if (!*dcd->mask.szMask) {
1738            empty = TRUE;
1739            pci = (PCNRITEM) CurrentRecord(hwnd);
1740            if (pci && !(pci->attrFile & FILE_DIRECTORY)) {
1741              p = strrchr(pci->pszFileName, '\\');
1742              if (p) {
1743                p++;
1744                strcpy(dcd->mask.szMask, p);
1745              }
1746            }
1747          }
1748          *(dcd->mask.prompt) = 0;
1749
1750          if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
1751                        FM3ModHandle, MSK_FRAME, MPFROMP(&dcd->mask))) {
1752            size = sizeof(MASK);
1753            PrfWriteProfileData(fmprof, appname, "CollectorFilter",
1754                                &dcd->mask, size);
1755            dcd->suspendview = 1;
1756            WinSendMsg(hwnd, CM_FILTER, MPFROMP(Filter), MPFROMP(&dcd->mask));
1757            dcd->suspendview = 0;
1758            if (fAutoView && hwndMain) {
1759              pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1760                               MPFROMLONG(CMA_FIRST),
1761                               MPFROMSHORT(CRA_CURSORED));
1762              if (pci && (INT) pci != -1 &&
1763                  (!(driveflags[toupper(*pci->pszFileName) - 'A'] &
1764                     DRIVE_SLOW)))
1765                WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->pszFileName),
1766                           MPVOID);
1767              else
1768                WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1769            }
1770            PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1771          }
1772          else if (empty)
1773            *dcd->mask.szMask = 0;
1774          SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1775                                    DIR_FILTER), &dcd->mask, FALSE);
1776        }
1777        break;
1778
1779      case IDM_HIDEALL:
1780        if (fAutoView && hwndMain)
1781          PostMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1782        dcd->suspendview = 1;
1783        HideAll(hwnd);
1784        dcd->suspendview = 0;
1785        PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1786        break;
1787
1788      case IDM_SELECTLIST:
1789      case IDM_SELECTALL:
1790      case IDM_DESELECTALL:
1791      case IDM_SELECTALLFILES:
1792      case IDM_DESELECTALLFILES:
1793      case IDM_SELECTALLDIRS:
1794      case IDM_DESELECTALLDIRS:
1795      case IDM_SELECTMASK:
1796      case IDM_DESELECTMASK:
1797      case IDM_INVERT:
1798      case IDM_SELECTCLIP:
1799      case IDM_DESELECTCLIP:
1800        {
1801          PCNRITEM pci;
1802
1803          pci = (PCNRITEM) CurrentRecord(hwnd);
1804          if ((INT) pci == -1)
1805            pci = NULL;
1806          if (SHORT1FROMMP(mp1) == IDM_HIDEALL) {
1807            if (pci) {
1808              if (!(pci->rc.flRecordAttr & CRA_SELECTED))
1809                pci->rc.flRecordAttr |= CRA_FILTERED;
1810              WinSendMsg(hwnd, CM_INVALIDATERECORD, MPFROMP(&pci),
1811                         MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1812              break;
1813            }
1814          }
1815          PostMsg(dcd->hwndObject, UM_SELECT, mp1, MPFROMP(pci));
1816        }
1817        break;
1818
1819      case IDM_RESCAN:
1820        PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPVOID);
1821        break;
1822
1823      case IDM_SHOWLNAMES:
1824      case IDM_SHOWSUBJECT:
1825      case IDM_SHOWEAS:
1826      case IDM_SHOWSIZE:
1827      case IDM_SHOWICON:
1828      case IDM_SHOWLWDATE:
1829      case IDM_SHOWLWTIME:
1830      case IDM_SHOWLADATE:
1831      case IDM_SHOWLATIME:
1832      case IDM_SHOWCRDATE:
1833      case IDM_SHOWCRTIME:
1834      case IDM_SHOWATTR:
1835        AdjustDetailsSwitches(hwnd, dcd->hwndLastMenu,
1836                              SHORT1FROMMP(mp1), NULL,
1837                              "Collector", dcd, FALSE);
1838        break;
1839
1840      case IDM_ICON:
1841      case IDM_TEXT:
1842      case IDM_DETAILS:
1843      case IDM_NAME:
1844      case IDM_MINIICONS:
1845      case IDM_DETAILSTITLES:
1846        {
1847          CNRINFO cnri;
1848
1849          memset(&cnri, 0, sizeof(CNRINFO));
1850          cnri.cb = sizeof(CNRINFO);
1851          WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
1852                     MPFROMLONG(sizeof(CNRINFO)));
1853          switch (SHORT1FROMMP(mp1)) {
1854          case IDM_ICON:
1855            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
1856                                    CV_DETAIL | CV_NAME));
1857            cnri.flWindowAttr |= CV_ICON;
1858            break;
1859          case IDM_NAME:
1860            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
1861                                    CV_DETAIL | CV_NAME));
1862            cnri.flWindowAttr |= CV_NAME;
1863            break;
1864          case IDM_TEXT:
1865            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
1866                                    CV_DETAIL | CV_NAME));
1867            cnri.flWindowAttr |= CV_TEXT;
1868            break;
1869          case IDM_DETAILS:
1870            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
1871                                    CV_DETAIL | CV_NAME));
1872            cnri.flWindowAttr |= CV_DETAIL;
1873            break;
1874          case IDM_MINIICONS:
1875            if (cnri.flWindowAttr & CV_MINI)
1876              cnri.flWindowAttr &= (~CV_MINI);
1877            else
1878              cnri.flWindowAttr |= CV_MINI;
1879            break;
1880          case IDM_DETAILSTITLES:
1881            if (cnri.flWindowAttr & CA_DETAILSVIEWTITLES)
1882              cnri.flWindowAttr &= (~CA_DETAILSVIEWTITLES);
1883            else
1884              cnri.flWindowAttr |= CA_DETAILSVIEWTITLES;
1885            break;
1886          }
1887          cnri.flWindowAttr &= (~(CA_ORDEREDTARGETEMPH | CA_MIXEDTARGETEMPH));
1888          cnri.flWindowAttr |= CV_FLOW;
1889          dcd->flWindowAttr = cnri.flWindowAttr;
1890          PrfWriteProfileData(fmprof, appname, "CollectorflWindowAttr",
1891                              &cnri.flWindowAttr, sizeof(ULONG));
1892          WinSendMsg(hwnd, CM_SETCNRINFO, MPFROMP(&cnri),
1893                     MPFROMLONG(CMA_FLWINDOWATTR));
1894          WinSendMsg(hwnd, CM_INVALIDATERECORD, MPVOID,
1895                     MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
1896          SayView(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1897                                  DIR_VIEW), dcd->flWindowAttr);
1898        }
1899        break;
1900
1901      case IDM_SAVETOLIST:
1902        WinDlgBox(HWND_DESKTOP, hwnd, SaveListDlgProc, FM3ModHandle,
1903                  SAV_FRAME, MPFROMP(&hwnd));
1904        break;
1905
1906      case IDM_SIZES:
1907        {
1908          PCNRITEM pci;
1909
1910          pci = (PCNRITEM) CurrentRecord(hwnd);
1911          if (pci && (INT) pci != -1)
1912            WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DirSizeProc, FM3ModHandle,
1913                      DSZ_FRAME, pci->pszFileName);
1914        }
1915        break;
1916
1917      case IDM_MKDIR:
1918        {
1919          PCNRITEM pci;
1920
1921          pci = (PCNRITEM) CurrentRecord(hwnd);
1922          PMMkDir(dcd->hwndParent, (pci && (INT) pci != -1) ?
1923                  pci->pszFileName : NULL, FALSE);
1924        }
1925        break;
1926
1927      case IDM_DOITYOURSELF:
1928      case IDM_UPDATE:
1929      case IDM_COLLECTFROMFILE:
1930      case IDM_OPENWINDOW:
1931      case IDM_OPENSETTINGS:
1932      case IDM_OPENDEFAULT:
1933      case IDM_OPENICON:
1934      case IDM_OPENDETAILS:
1935      case IDM_OPENTREE:
1936      case IDM_OBJECT:
1937      case IDM_SHADOW:
1938      case IDM_SHADOW2:
1939      case IDM_DELETE:
1940      case IDM_PERMDELETE:
1941      case IDM_PRINT:
1942      case IDM_ATTRS:
1943      case IDM_INFO:
1944      case IDM_COPY:
1945      case IDM_MOVE:
1946      case IDM_WPSCOPY:
1947      case IDM_WPSMOVE:
1948      case IDM_COPYPRESERVE:
1949      case IDM_MOVEPRESERVE:
1950      case IDM_WILDCOPY:
1951      case IDM_WILDMOVE:
1952      case IDM_RENAME:
1953      case IDM_COMPARE:
1954      case IDM_EAS:
1955      case IDM_SUBJECT:
1956      case IDM_VIEW:
1957      case IDM_VIEWTEXT:
1958      case IDM_VIEWBINARY:
1959      case IDM_VIEWARCHIVE:
1960      case IDM_EDIT:
1961      case IDM_EDITTEXT:
1962      case IDM_EDITBINARY:
1963      case IDM_SAVETOCLIP:
1964      case IDM_APPENDTOCLIP:
1965      case IDM_ARCHIVE:
1966      case IDM_ARCHIVEM:
1967      case IDM_EXTRACT:
1968      case IDM_MCIPLAY:
1969      case IDM_UUDECODE:
1970      case IDM_MERGE:
1971        {
1972          LISTINFO *li;
1973          ULONG action = UM_ACTION;
1974
1975          li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
1976          if (li) {
1977            li->type = SHORT1FROMMP(mp1);
1978            li->hwnd = hwnd;
1979            li->list = BuildList(hwnd);
1980            if (li->list) {
1981              switch (SHORT1FROMMP(mp1)) {
1982              case IDM_DOITYOURSELF:
1983              case IDM_APPENDTOCLIP:
1984              case IDM_SAVETOCLIP:
1985              case IDM_ARCHIVE:
1986              case IDM_ARCHIVEM:
1987              case IDM_DELETE:
1988              case IDM_PERMDELETE:
1989              case IDM_ATTRS:
1990              case IDM_PRINT:
1991              case IDM_SHADOW:
1992              case IDM_SHADOW2:
1993              case IDM_OBJECT:
1994              case IDM_VIEW:
1995              case IDM_VIEWTEXT:
1996              case IDM_VIEWBINARY:
1997              case IDM_EDIT:
1998              case IDM_EDITTEXT:
1999              case IDM_EDITBINARY:
2000              case IDM_MCIPLAY:
2001              case IDM_UPDATE:
2002              case IDM_INFO:
2003              case IDM_EAS:
2004                action = UM_MASSACTION;
2005                break;
2006              }
2007              if (li->type == IDM_SHADOW || li->type == IDM_OBJECT ||
2008                  li->type == IDM_SHADOW2)
2009                *li->targetpath = 0;
2010              if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID)) {
2011                Runtime_Error(pszSrcFile, __LINE__, "PostMsg");
2012                FreeListInfo(li);
2013              }
2014              else if (fUnHilite)
2015                UnHilite(hwnd, TRUE, &dcd->lastselection, dcd->ulItemsToUnHilite);
2016            }
2017            else
2018              free(li);
2019          }
2020        }
2021        break;
2022
2023      default:
2024        if (!cmdloaded)
2025          load_commands();
2026        if (SHORT1FROMMP(mp1) >= IDM_COMMANDSTART &&
2027            SHORT1FROMMP(mp1) < IDM_QUICKTOOLSTART) {
2028          INT x;
2029
2030          x = SHORT1FROMMP(mp1) - IDM_COMMANDSTART;
2031          if (x >= 0) {
2032            x++;
2033            RunCommand(hwnd, x);
2034            if (fUnHilite)
2035              UnHilite(hwnd, TRUE, &dcd->lastselection, dcd->ulItemsToUnHilite);
2036          }
2037        }
2038        break;
2039      }
2040    }
2041    return 0;
2042
2043  case UM_FIXCNRMLE:
2044  case UM_FIXEDITNAME:
2045    return CommonCnrProc(hwnd, msg, mp1, mp2);
2046
2047  case UM_FILESMENU:
2048    {
2049      PCNRITEM pci;
2050      HWND menuHwnd = (HWND) 0;
2051
2052      pci = (PCNRITEM) CurrentRecord(hwnd);
2053      if (pci && (INT) pci != -1) {
2054        if (pci->attrFile & FILE_DIRECTORY)
2055          menuHwnd = CheckMenu(&CollectorDirMenu, COLLECTORDIR_POPUP);
2056        else
2057          menuHwnd = CheckMenu(&CollectorFileMenu, COLLECTORFILE_POPUP);
2058      }
2059      return MRFROMLONG(menuHwnd);
2060    }
2061
2062  case WM_CONTROL:
2063    DosError(FERR_DISABLEHARDERR);
2064    if (dcd) {
2065      switch (SHORT2FROMMP(mp1)) {
2066      case CN_CONTEXTMENU:
2067        {
2068          PCNRITEM pci = (PCNRITEM) mp2;
2069
2070          if (pci) {
2071            WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPFROMP(pci),
2072                       MPFROM2SHORT(TRUE, CRA_CURSORED));
2073            MarkAll(hwnd, FALSE, FALSE, TRUE);
2074            if (pci->attrFile & FILE_DIRECTORY)
2075              dcd->hwndLastMenu = CheckMenu(&CollectorDirMenu,
2076                                            COLLECTORDIR_POPUP);
2077            else
2078              dcd->hwndLastMenu = CheckMenu(&CollectorFileMenu,
2079                                            COLLECTORFILE_POPUP);
2080          }
2081          else {
2082            dcd->hwndLastMenu = CheckMenu(&CollectorCnrMenu,
2083                                          COLLECTORCNR_POPUP);
2084            if (dcd->hwndLastMenu && !dcd->cnremphasized) {
2085              WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
2086                         MPFROM2SHORT(TRUE, CRA_SOURCE));
2087              dcd->cnremphasized = TRUE;
2088            }
2089          }
2090          if (dcd->hwndLastMenu) {
2091            if (dcd->hwndLastMenu == CollectorCnrMenu) {
2092              SetViewMenu(dcd->hwndLastMenu, dcd->flWindowAttr);
2093              SetDetailsSwitches(dcd->hwndLastMenu, dcd);
2094              if (dcd->flWindowAttr & CV_MINI)
2095                WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
2096              disable_menuitem(dcd->hwndLastMenu, DID_CANCEL,
2097                               !dcd->amextracted);
2098              disable_menuitem(dcd->hwndLastMenu, IDM_GREP, dcd->amextracted);
2099            }
2100            if (!PopupMenu(hwnd, hwnd, dcd->hwndLastMenu)) {
2101              if (dcd->cnremphasized) {
2102                WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
2103                           MPFROM2SHORT(FALSE, CRA_SOURCE));
2104                dcd->cnremphasized = TRUE;
2105              }
2106              MarkAll(hwnd, TRUE, FALSE, TRUE);
2107            }
2108          }
2109        }
2110        break;
2111
2112      case CN_DROPHELP:
2113        if (mp2) {
2114          PDRAGINFO pDInfo;
2115          PCNRITEM pci;
2116          ULONG numitems;
2117          USHORT usOperation;
2118
2119          pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2120          pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2121          if (!DrgAccessDraginfo(pDInfo)) {
2122            Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
2123                      "DrgAccessDraginfo");
2124            return 0;
2125          }
2126          numitems = DrgQueryDragitemCount(pDInfo);
2127          usOperation = pDInfo->usOperation;
2128          FreeDragInfoData(hwnd, pDInfo);
2129          saymsg(MB_ENTER | MB_ICONASTERISK,
2130                 hwnd,
2131                 GetPString(IDS_DROPHELPHDRTEXT),
2132                 GetPString(IDS_DROPHELPTEXT),
2133                 numitems,
2134                 &"s"[numitems == 1],
2135                 (pci) ? NullStr : GetPString(IDS_NOTEXT),
2136                 (pci) ? NullStr : " ",
2137                 (pci) ? pci->pszFileName : NullStr,
2138                 (pci) ? " " : NullStr,
2139                 GetPString((usOperation == DO_COPY) ?
2140                            IDS_COPYTEXT :
2141                            (usOperation == DO_LINK) ?
2142                            IDS_LINKTEXT : IDS_MOVETEXT));
2143        }
2144        return 0;
2145
2146      case CN_DRAGLEAVE:
2147        if (mp2) {
2148          PDRAGINFO pDInfo;
2149
2150          // fixme to know why needed
2151          pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2152          DrgAccessDraginfo(pDInfo);    /* Access DRAGINFO */
2153          DrgFreeDraginfo(pDInfo);      /* Free DRAGINFO */
2154        }
2155        return 0;
2156
2157      case CN_DRAGAFTER:
2158      case CN_DRAGOVER:
2159        if (mp2) {
2160          PDRAGITEM pDItem;     /* Pointer to DRAGITEM */
2161          PDRAGINFO pDInfo;     /* Pointer to DRAGINFO */
2162          PCNRITEM pci;
2163          USHORT uso;
2164
2165          pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2166          // if(SHORT1FROMMP(mp1) == CN_DRAGAFTER)
2167          //    pci = NULL;
2168          pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2169          if (!DrgAccessDraginfo(pDInfo)) {
2170            Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
2171                      "DrgAccessDraginfo");
2172            return (MRFROM2SHORT(DOR_NODROP, 0));       /* Drop not valid */
2173          }
2174          if (pci) {
2175            if (pci->rc.flRecordAttr & CRA_SOURCE) {
2176              DrgFreeDraginfo(pDInfo);
2177              return (MRFROM2SHORT(DOR_NODROP, 0));
2178            }
2179            uso = pDInfo->usOperation;
2180            if (uso == DO_DEFAULT)
2181              uso = (fCopyDefault) ? DO_COPY : DO_MOVE;
2182            if (!(pci->attrFile & FILE_DIRECTORY)) {
2183              if (uso != DO_LINK && uso != DO_MOVE && uso != DO_COPY) {
2184                DrgFreeDraginfo(pDInfo);
2185                return MRFROM2SHORT(DOR_NODROP, 0);
2186              }
2187              if (uso != DO_LINK &&
2188                  !(driveflags[toupper(*pci->pszFileName) - 'A'] &
2189                    DRIVE_NOTWRITEABLE)) {
2190                ARC_TYPE *info = NULL;
2191
2192                if (!fQuickArcFind &&
2193                    !(driveflags[toupper(*pci->pszFileName) - 'A'] &
2194                      DRIVE_SLOW))
2195                  info = find_type(pci->pszFileName, NULL);
2196                else
2197                  info = quick_find_type(pci->pszFileName, NULL);
2198                if (!info || ((uso == DO_MOVE && !info->move) ||
2199                              (uso == DO_COPY && !info->create))) {
2200                  DrgFreeDraginfo(pDInfo);
2201                  return MRFROM2SHORT(DOR_NODROP, 0);
2202                }
2203              }
2204            }
2205          }
2206          pDItem = DrgQueryDragitemPtr(pDInfo,  /* Access DRAGITEM */
2207                                       0);      /* Index to DRAGITEM */
2208          if (DrgVerifyRMF(pDItem,      /* Check valid rendering */
2209                           DRM_OS2FILE, /* mechanisms and data */
2210                           NULL)) {
2211            DrgFreeDraginfo(pDInfo);    /* Free DRAGINFO */
2212            if (pci) {
2213              if (driveflags[toupper(*pci->pszFileName) - 'A'] &
2214                  DRIVE_NOTWRITEABLE)
2215                return MRFROM2SHORT(DOR_DROP, DO_LINK);
2216              if (toupper(*pci->pszFileName) < 'C')
2217                return MRFROM2SHORT(DOR_DROP, DO_COPY);
2218              return MRFROM2SHORT(DOR_DROP,     /* Return okay to drop */
2219                                  ((fCopyDefault) ? DO_COPY : DO_MOVE));
2220            }
2221            else
2222              return MRFROM2SHORT(DOR_DROP,     /* Return okay to drop */
2223                                  DO_COPY);
2224          }
2225          DrgFreeDraginfo(pDInfo);      /* Free DRAGINFO */
2226        }
2227        return (MRFROM2SHORT(DOR_NODROP, 0));   /* Drop not valid */
2228
2229      case CN_INITDRAG:
2230        if (mp2) {
2231          BOOL wasemphasized = FALSE;
2232          PCNRDRAGINIT pcd = (PCNRDRAGINIT) mp2;
2233          PCNRITEM pci;
2234
2235          if (pcd) {
2236            pci = (PCNRITEM) pcd->pRecord;
2237            if (pci) {
2238              if (pci->rc.flRecordAttr & CRA_SELECTED)
2239                wasemphasized = TRUE;
2240              if (IsRoot(pci->pszFileName))
2241                break;
2242              if (hwndStatus2)
2243                WinSetWindowText(hwndStatus2,
2244                                 GetPString(IDS_DRAGFILEOBJTEXT));
2245              if (DoFileDrag(hwnd, dcd->hwndObject, mp2, NULL, NULL, TRUE)) {
2246                if ((fUnHilite && wasemphasized) || dcd->ulItemsToUnHilite)
2247                  UnHilite(hwnd, TRUE, &dcd->lastselection, dcd->ulItemsToUnHilite);
2248              }
2249              if (hwndStatus2)
2250                PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2251            }
2252          }
2253        }
2254        return 0;
2255
2256      case CN_DROP:
2257        if (mp2) {
2258          LISTINFO *li;
2259          ULONG action = UM_ACTION;
2260
2261          li = DoFileDrop(hwnd, NULL, TRUE, mp1, mp2);
2262          CheckPmDrgLimit(((PCNRDRAGINFO)mp2)->pDragInfo);
2263          if (li) {
2264            if (!*li->targetpath) {
2265              li->type = IDM_COLLECT;
2266              action = UM_COLLECT;
2267            }
2268            else {
2269              if (li->list && li->list[0] && IsRoot(li->list[0]))
2270                li->type = DO_LINK;
2271              else if (fDragndropDlg && (!*li->arcname || !li->info)) {
2272                CHECKLIST cl;
2273
2274                memset(&cl, 0, sizeof(cl));
2275                cl.size = sizeof(cl);
2276                cl.flags = li->type;
2277                cl.list = li->list;
2278                cl.cmd = li->type;
2279                cl.prompt = li->targetpath;
2280                li->type = WinDlgBox(HWND_DESKTOP, dcd->hwndParent,
2281                                     DropListProc, FM3ModHandle,
2282                                     DND_FRAME, MPFROMP(&cl));
2283                if (li->type == DID_ERROR)
2284                  Win_Error(DND_FRAME, HWND_DESKTOP, pszSrcFile, __LINE__,
2285                            "Drag & Drop Dialog");
2286                if (!li->type) {
2287                  FreeListInfo(li);
2288                  return 0;
2289                }
2290                li->list = cl.list;
2291                if (!li->list || !li->list[0]) {
2292                  FreeListInfo(li);
2293                  return 0;
2294                }
2295              }
2296              switch (li->type) {
2297              case DND_LAUNCH:
2298                strcat(li->targetpath, " %a");
2299                ExecOnList(dcd->hwndParent, li->targetpath,
2300                           PROMPT | WINDOWED, NULL, li->list, NULL);
2301                FreeList(li->list);
2302                li->list = NULL;
2303                break;
2304              case DO_LINK:
2305                if (fLinkSetsIcon) {
2306                  li->type = IDM_SETICON;
2307                  action = UM_MASSACTION;
2308                }
2309                else
2310                  li->type = IDM_COMPARE;
2311                break;
2312              case DND_EXTRACT:
2313                if (*li->targetpath && !IsFile(li->targetpath))
2314                  li->type = IDM_EXTRACT;
2315                break;
2316              case DND_MOVE:
2317                li->type = IDM_MOVE;
2318                if (*li->targetpath && IsFile(li->targetpath) == 1) {
2319                  action = UM_MASSACTION;
2320                  li->type = IDM_ARCHIVEM;
2321                }
2322                break;
2323              case DND_WILDMOVE:
2324                li->type = IDM_WILDMOVE;
2325                if (*li->targetpath && IsFile(li->targetpath) == 1) {
2326                  action = UM_MASSACTION;
2327                  li->type = IDM_ARCHIVEM;
2328                }
2329                break;
2330              case DND_OBJECT:
2331                li->type = IDM_OBJECT;
2332                action = UM_MASSACTION;
2333                break;
2334              case DND_SHADOW:
2335                li->type = IDM_SHADOW;
2336                action = UM_MASSACTION;
2337                break;
2338              case DND_COMPARE:
2339                li->type = IDM_COMPARE;
2340                break;
2341              case DND_SETICON:
2342                action = UM_MASSACTION;
2343                li->type = IDM_SETICON;
2344                break;
2345              case DND_WILDCOPY:
2346                li->type = IDM_WILDCOPY;
2347                if (*li->targetpath && IsFile(li->targetpath) == 1) {
2348                  action = UM_MASSACTION;
2349                  li->type = IDM_ARCHIVE;
2350                }
2351                break;
2352              case DND_COPY:
2353                li->type = IDM_COPY;
2354                if (*li->targetpath && IsFile(li->targetpath) == 1) {
2355                  action = UM_MASSACTION;
2356                  li->type = IDM_ARCHIVE;
2357                }
2358                break;
2359              default:
2360                if (*li->arcname && li->info) {
2361                  action = UM_MASSACTION;
2362                  li->type =
2363                    (li->type ==
2364                     DO_MOVE) ? IDM_FAKEEXTRACTM : IDM_FAKEEXTRACT;
2365                }
2366                else if (*li->targetpath && IsFile(li->targetpath) == 1) {
2367                  action = UM_MASSACTION;
2368                  li->type =
2369                    (li->type == DO_MOVE) ? IDM_ARCHIVEM : IDM_ARCHIVE;
2370                }
2371                else
2372                  li->type = (li->type == DO_MOVE) ? IDM_MOVE : IDM_COPY;
2373                break;
2374              }
2375            }
2376            if (!li->list || !li->list[0])
2377              FreeListInfo(li);
2378            else if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID))
2379              FreeListInfo(li);
2380            else {
2381              USHORT usop = 0;
2382
2383              switch (li->type) {
2384              case IDM_COPY:
2385              case IDM_WILDCOPY:
2386                usop = DO_COPY;
2387                break;
2388              case IDM_MOVE:
2389              case IDM_WILDMOVE:
2390              case IDM_ARCHIVEM:
2391                usop = DO_MOVE;
2392                break;
2393              }
2394              if (usop)
2395                return MRFROM2SHORT(DOR_DROP, usop);
2396            }
2397          }
2398        }
2399        return 0;
2400
2401      case CN_BEGINEDIT:
2402      case CN_REALLOCPSZ:
2403      case CN_ENDEDIT:
2404        {
2405          MRESULT mre;
2406
2407          mre = CnrDirectEdit(hwnd, msg, mp1, mp2);
2408          if (mre != (MRESULT) - 1)
2409            return mre;
2410        }
2411        break;
2412
2413      case CN_EMPHASIS:
2414        if (mp2) {
2415          PNOTIFYRECORDEMPHASIS pre = mp2;
2416          PCNRITEM pci;
2417          CHAR s[CCHMAXPATH + 91], tb[81], tf[81], *p;
2418
2419          pci = (PCNRITEM) ((pre) ? pre->pRecord : NULL);
2420          if (!pci) {
2421            if (hwndStatus2)
2422              WinSetWindowText(hwndStatus2, NullStr);
2423            if (fMoreButtons) {
2424              WinSetWindowText(hwndName, NullStr);
2425              WinSetWindowText(hwndDate, NullStr);
2426              WinSetWindowText(hwndAttr, NullStr);
2427            }
2428            if (hwndMain)
2429              WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
2430            break;
2431          }
2432          if (pre->fEmphasisMask & CRA_SELECTED) {
2433            if (pci->rc.flRecordAttr & CRA_SELECTED) {
2434              dcd->selectedbytes += (pci->cbFile + pci->easize);
2435              dcd->selectedfiles++;
2436            }
2437            else if (dcd->selectedfiles) {
2438              dcd->selectedbytes -= (pci->cbFile + pci->easize);
2439              dcd->selectedfiles--;
2440            }
2441            if (!dcd->suspendview) {
2442              commafmt(tf, sizeof(tf), dcd->selectedfiles);
2443              CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, ' ');
2444              sprintf(s, "%s / %s", tf, tb);
2445              WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
2446            }
2447          }
2448          if (!dcd->suspendview &&
2449              WinQueryActiveWindow(dcd->hwndParent) == dcd->hwndFrame) {
2450            if (pre->fEmphasisMask & CRA_CURSORED) {
2451              if (pci->rc.flRecordAttr & CRA_CURSORED) {
2452                if (fSplitStatus && hwndStatus2) {
2453                  if (pci->attrFile & FILE_DIRECTORY)
2454                    p = pci->pszFileName;
2455                  else {
2456                    p = strrchr(pci->pszFileName, '\\');
2457                    if (p) {
2458                      if (*(p + 1))
2459                        p++;
2460                      else
2461                        p = pci->pszFileName;
2462                    }
2463                    else
2464                      p = pci->pszFileName;
2465                  }
2466                  CommaFmtULL(tb, sizeof(tb), pci->cbFile + pci->easize, ' ');
2467                  if (!fMoreButtons)
2468                    sprintf(s, " %s  %04u/%02u/%02u %02u:%02u:%02u  [%s]  %s",
2469                            tb, pci->date.year,
2470                            pci->date.month, pci->date.day, pci->time.hours,
2471                            pci->time.minutes, pci->time.seconds,
2472                            pci->pszDispAttr, p);
2473                  else {
2474                    if (pci->cbFile + pci->easize > 1024)
2475                      CommaFmtULL(tf, sizeof(tf), pci->cbFile + pci->easize,
2476                                  ' ');
2477                    else
2478                      *tf = 0;
2479                    sprintf(s, GetPString(IDS_STATUSSIZETEXT),
2480                            tb,
2481                            *tf ? " (" : NullStr, tf, *tf ? ")" : NullStr);
2482                  }
2483                  WinSetWindowText(hwndStatus2, s);
2484                }
2485                if (fMoreButtons) {
2486                  WinSetWindowText(hwndName, pci->pszFileName);
2487                  sprintf(s, "%04u/%02u/%02u %02u:%02u:%02u",
2488                          pci->date.year, pci->date.month,
2489                          pci->date.day, pci->time.hours, pci->time.minutes,
2490                          pci->time.seconds);
2491                  WinSetWindowText(hwndDate, s);
2492                  WinSetWindowText(hwndAttr, pci->pszDispAttr);
2493                }
2494              }
2495            }
2496          }
2497          if (!dcd->suspendview && hwndMain &&
2498              (pre->fEmphasisMask & CRA_CURSORED) &&
2499              (pci->rc.flRecordAttr & CRA_CURSORED) &&
2500              WinQueryActiveWindow(dcd->hwndParent) == dcd->hwndFrame)
2501            WinSendMsg(hwndMain, UM_LOADFILE,
2502                       MPFROMP(((fComments
2503                                 || (pci->attrFile & FILE_DIRECTORY) ==
2504                                 0) ? pci->pszFileName : NULL)), MPVOID);
2505        }
2506        break;
2507
2508      case CN_ENTER:
2509        if (mp2) {
2510          PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
2511          FILEFINDBUF3 ffb;
2512          HDIR hDir = HDIR_CREATE;
2513          ULONG nm = 1;
2514          APIRET status = 0;
2515
2516          SetShiftState();
2517          if (pci) {
2518            if (pci->rc.flRecordAttr & CRA_INUSE)
2519              break;
2520            DosError(FERR_DISABLEHARDERR);
2521            status = DosFindFirst(pci->pszFileName, &hDir,
2522                                  FILE_NORMAL | FILE_DIRECTORY |
2523                                  FILE_ARCHIVED | FILE_READONLY |
2524                                  FILE_HIDDEN | FILE_SYSTEM,
2525                                  &ffb, sizeof(ffb), &nm, FIL_STANDARD);
2526            priority_bumped();
2527            if (!status) {
2528              DosFindClose(hDir);
2529              if (ffb.attrFile & FILE_DIRECTORY) {
2530                if ((shiftstate & (KC_CTRL | KC_ALT)) == (KC_CTRL | KC_ALT))
2531                  PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_SHOWALLFILES, 0),
2532                          MPVOID);
2533                else if ((shiftstate & (KC_CTRL | KC_SHIFT)) ==
2534                         (KC_CTRL | KC_SHIFT))
2535                  OpenObject(pci->pszFileName, Settings, dcd->hwndFrame);
2536                else if (shiftstate & KC_CTRL)
2537                  OpenObject(pci->pszFileName, Default, dcd->hwndFrame);
2538                else
2539                  OpenDirCnr(HWND_DESKTOP,
2540                             hwndMain,
2541                             dcd->hwndFrame, FALSE, pci->pszFileName);
2542              }
2543              else {
2544                SWP swp;
2545
2546                WinSendMsg(hwnd,
2547                           CM_SETRECORDEMPHASIS,
2548                           MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_INUSE));
2549                WinQueryWindowPos(dcd->hwndFrame, &swp);
2550                DefaultViewKeys(hwnd,
2551                                dcd->hwndFrame,
2552                                dcd->hwndParent, &swp, pci->pszFileName);
2553                WinSendMsg(hwnd,
2554                           CM_SETRECORDEMPHASIS,
2555                           MPFROMP(pci),
2556                           MPFROM2SHORT(FALSE, CRA_INUSE |
2557                                        ((fUnHilite) ? CRA_SELECTED : 0)));
2558              }
2559            }
2560            else
2561              RemoveCnrItems(hwnd, pci, 1, CMA_FREE | CMA_INVALIDATE | CMA_ERASE);
2562          }
2563        }
2564        break;
2565      }
2566    }
2567    return 0;
2568
2569  case UM_LOADFILE:
2570    if (dcd && mp2) {
2571      HWND ret;
2572
2573      ret = StartMLEEditor(dcd->hwndParent,
2574                           (INT) mp1, (CHAR *) mp2, dcd->hwndFrame);
2575      if (mp2)
2576        free((CHAR *) mp2);
2577      return MRFROMLONG(ret);
2578    }
2579    return 0;
2580
2581  case UM_CLOSE:
2582    WinDestroyWindow(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
2583                                    QW_PARENT));
2584    return 0;
2585
2586  case UM_FOLDUP:
2587    if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
2588      DosExit(EXIT_PROCESS, 1);
2589    return 0;
2590
2591  case WM_CLOSE:
2592    if (dcd) {
2593      dcd->namecanchange = TRUE;
2594      dcd->stopflag = 1;
2595      if (dcd->amextracted)
2596        return 0;                       // Can not close yet
2597    }
2598    WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
2599    if (dcd) {
2600      if (!dcd->dontclose && ParentIsDesktop(hwnd, dcd->hwndParent))
2601        PostMsg(hwnd, UM_FOLDUP, MPVOID, MPVOID);
2602      if (dcd->hwndObject) {
2603        DosSleep(64);
2604        if (!PostMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID))
2605          WinSendMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID);
2606      }
2607    }
2608    else
2609      WinSendMsg(hwnd, UM_CLOSE, MPVOID, MPVOID);
2610    return 0;
2611
2612  case WM_DESTROY:
2613    if (CollectorDirMenu)
2614      WinDestroyWindow(CollectorDirMenu);
2615    if (CollectorFileMenu)
2616      WinDestroyWindow(CollectorFileMenu);
2617    if (CollectorCnrMenu)
2618      WinDestroyWindow(CollectorCnrMenu);
2619    CollectorCnrMenu = CollectorFileMenu = CollectorDirMenu = (HWND) 0;
2620    Collector = (HWND) 0;
2621    EmptyCnr(hwnd);
2622    break;
2623  }
2624  if (dcd && dcd->oldproc){
2625      return dcd->oldproc(hwnd, msg, mp1, mp2);
2626  }
2627  else
2628      return PFNWPCnr(hwnd, msg, mp1, mp2);
2629}
2630
2631HWND StartCollector(HWND hwndParent, INT flags)
2632{
2633  HWND hwndFrame = (HWND) 0;
2634  HWND hwndClient;
2635  ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
2636    FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE;
2637  USHORT id;
2638  DIRCNRDATA *dcd;
2639
2640  static USHORT idinc = 0;
2641
2642  if (ParentIsDesktop(hwndParent, hwndParent))
2643    FrameFlags |= (FCF_TASKLIST | FCF_SHELLPOSITION | FCF_MENU);
2644  if (Collector) {
2645    WinSetWindowPos(WinQueryWindow(WinQueryWindow(Collector,
2646                                                  QW_PARENT),
2647                                   QW_PARENT),
2648                    HWND_TOP, 0, 0, 0, 0, SWP_SHOW | SWP_RESTORE);
2649    return WinQueryWindow(WinQueryWindow(Collector, QW_PARENT), QW_PARENT);
2650  }
2651  hwndFrame = WinCreateStdWindow(hwndParent,
2652                                 WS_VISIBLE,
2653                                 &FrameFlags,
2654                                 WC_COLLECTOR,
2655                                 NULL,
2656                                 WS_VISIBLE | fwsAnimate,
2657                                 FM3ModHandle, COLLECTOR_FRAME, &hwndClient);
2658  if (hwndFrame && hwndClient) {
2659    id = COLLECTOR_FRAME + idinc++;
2660    WinSetWindowUShort(hwndFrame, QWS_ID, id);
2661    dcd = xmallocz(sizeof(DIRCNRDATA), pszSrcFile, __LINE__);
2662    if (!dcd) {
2663      Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2664      PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
2665      hwndFrame = (HWND) 0;
2666    }
2667    else {
2668      dcd->size = sizeof(DIRCNRDATA);
2669      dcd->id = id;
2670      dcd->type = COLLECTOR_FRAME;
2671      dcd->hwndParent = (hwndParent) ? hwndParent : HWND_DESKTOP;
2672      dcd->hwndFrame = hwndFrame;
2673      dcd->hwndClient = hwndClient;
2674      if (flags & 4)
2675        dcd->dontclose = TRUE;
2676      {
2677        PFNWP oldproc;
2678
2679        oldproc = WinSubclassWindow(hwndFrame, (PFNWP) CollectorFrameWndProc);
2680        WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
2681      }
2682      dcd->hwndCnr = WinCreateWindow(hwndClient,
2683                                     WC_CONTAINER,
2684                                     NULL,
2685                                     CCS_AUTOPOSITION | CCS_MINIICONS |
2686                                     CCS_MINIRECORDCORE | ulCnrType |
2687                                     WS_VISIBLE,
2688                                     0,
2689                                     0,
2690                                     0,
2691                                     0,
2692                                     hwndClient,
2693                                     HWND_TOP,
2694                                     (ULONG) COLLECTOR_CNR, NULL, NULL);
2695      if (!dcd->hwndCnr) {
2696        Win_Error2(hwndClient, hwndClient, pszSrcFile, __LINE__,
2697                   IDS_WINCREATEWINDOW);
2698        PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
2699        free(dcd);
2700        hwndFrame = (HWND) 0;
2701      }
2702      else {
2703        Collector = dcd->hwndCnr;
2704        WinSetWindowPtr(dcd->hwndCnr, QWL_USER, (PVOID) dcd);
2705        WinSetWindowText(hwndFrame, GetPString(IDS_COLLECTORTITLETEXT));
2706        if (FrameFlags & FCF_MENU) {
2707          if (!fToolbar) {
2708            HWND hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
2709
2710            if (hwndMenu) {
2711              WinSendMsg(hwndMenu,
2712                         MM_DELETEITEM,
2713                         MPFROM2SHORT(IDM_SEEALL, FALSE), MPVOID);
2714              WinSendMsg(hwndMenu,
2715                         MM_DELETEITEM,
2716                         MPFROM2SHORT(IDM_GREP, FALSE), MPVOID);
2717              WinSendMsg(hwndMenu,
2718                         MM_DELETEITEM,
2719                         MPFROM2SHORT(IDM_CLEARCNR, FALSE), MPVOID);
2720              WinSendMsg(hwndMenu,
2721                         MM_DELETEITEM,
2722                         MPFROM2SHORT(IDM_REMOVE, FALSE), MPVOID);
2723            }
2724          }
2725        }
2726        dcd->oldproc = WinSubclassWindow(dcd->hwndCnr,
2727                                         (PFNWP) CollectorCnrWndProc);
2728        {
2729          USHORT ids[] = { DIR_TOTALS, DIR_SELECTED, DIR_VIEW, DIR_SORT,
2730            DIR_FILTER, 0
2731          };
2732
2733          CommonCreateTextChildren(dcd->hwndClient,
2734                                   WC_COLSTATUS, ids);
2735        }
2736        if (FrameFlags & FCF_SHELLPOSITION)
2737          PostMsg(hwndClient, UM_SIZE, MPVOID, MPVOID);
2738        if (!PostMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID))
2739          WinSendMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID);
2740      }
2741    }
2742  }
2743  return hwndFrame;
2744}
Note: See TracBrowser for help on using the repository browser.