source: trunk/dll/collect.c @ 618

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

Add more drag/drop error checking
Use FreeDragInfoData?
Sync with NumItemsToUnhilite? AcceptOneDrop? GetOneDrop? mods

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 70.5 KB
Line 
1
2/***********************************************************************
3
4  $Id: collect.c 618 2007-04-20 19:19:03Z stevenhl $
5
6  Collector
7
8  Copyright (c) 1993-98 M. Kimes
9  Copyright (c) 2003, 2006 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
37***********************************************************************/
38
39#define INCL_DOS
40#define INCL_WIN
41#define INCL_GPI
42#define INCL_DOSERRORS
43#define INCL_LONGLONG
44#include <os2.h>
45
46#include <stdarg.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <ctype.h>
51#include <time.h>
52#include <share.h>
53#include <limits.h>
54
55#include "fm3dll.h"
56#include "fm3dlg.h"
57#include "fm3str.h"
58#include "mle.h"
59#include "grep.h"
60
61#pragma data_seg(DATA1)
62
63static PSZ pszSrcFile = __FILE__;
64
65#pragma alloc_text(COLLECTOR,CollectorCnrWndProc,CollectorObjWndProc)
66#pragma alloc_text(COLLECTOR,CollectorClientWndProc,CollectorTextProc)
67#pragma alloc_text(COLLECTOR,CollectorFrameWndProc)
68#pragma alloc_text(STARTUP,StartCollector)
69
70MRESULT EXPENTRY CollectorFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
71                                       MPARAM mp2)
72{
73  return CommonFrameWndProc(COLLECTOR_CNR, hwnd, msg, mp1, mp2);
74}
75
76MRESULT EXPENTRY CollectorTextProc(HWND hwnd, ULONG msg, MPARAM mp1,
77                                   MPARAM mp2)
78{
79  DIRCNRDATA *dcd;
80
81  static BOOL emphasized = FALSE;
82  static HWND hwndButtonPopup = (HWND) 0;
83  static ULONG timestamp = ULONG_MAX;
84  static USHORT lastid = 0;
85
86  switch (msg) {
87  case WM_CREATE:
88    return CommonTextProc(hwnd, msg, mp1, mp2);
89
90  case UM_CONTEXTMENU:
91  case WM_CONTEXTMENU:
92    {
93      USHORT id;
94
95      id = WinQueryWindowUShort(hwnd, QWS_ID);
96      switch (id) {
97      case DIR_SELECTED:
98      case DIR_VIEW:
99      case DIR_SORT:
100        {
101          POINTL ptl = { 0, 0 };
102          SWP swp;
103
104          if (hwndButtonPopup)
105            WinDestroyWindow(hwndButtonPopup);
106          if (id == lastid) {
107            ULONG check;
108
109            DosQuerySysInfo(QSV_MS_COUNT,
110                            QSV_MS_COUNT, &check, sizeof(check));
111            if (check < timestamp + 500) {
112              lastid = 0;
113              goto MenuAbort;
114            }
115          }
116          hwndButtonPopup = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
117          if (hwndButtonPopup) {
118            WinSetWindowUShort(hwndButtonPopup, QWS_ID, id);
119            dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
120                                                                   QW_PARENT),
121                                                    COLLECTOR_CNR), QWL_USER);
122            if (id == DIR_VIEW) {
123              if (dcd) {
124                SetViewMenu(hwndButtonPopup, dcd->flWindowAttr);
125                SetDetailsSwitches(hwndButtonPopup, dcd);
126              }
127
128              /* don't have tree view in collector */
129              WinSendMsg(hwndButtonPopup,
130                         MM_DELETEITEM,
131                         MPFROM2SHORT(IDM_TREEVIEW, FALSE), MPVOID);
132
133            }
134            else if (id == DIR_SORT) {
135              if (dcd)
136                SetSortChecks(hwndButtonPopup, dcd->sortFlags);
137            }
138            ptl.x = 0;
139            if (WinPopupMenu(HWND_OBJECT,
140                             HWND_OBJECT,
141                             hwndButtonPopup, -32767, -32767, 0, 0)) {
142              WinQueryWindowPos(hwndButtonPopup, &swp);
143              ptl.y = -(swp.cy + 2);
144            }
145            else {
146              WinQueryWindowPos(hwnd, &swp);
147              ptl.y = swp.cy + 2;
148            }
149            if (WinPopupMenu(hwnd,
150                             hwnd,
151                             hwndButtonPopup,
152                             ptl.x,
153                             ptl.y,
154                             0,
155                             PU_HCONSTRAIN | PU_VCONSTRAIN |
156                             PU_KEYBOARD | PU_MOUSEBUTTON1)) {
157              CenterOverWindow(hwndButtonPopup);
158              PaintRecessedWindow(hwnd, NULLHANDLE, FALSE, FALSE);
159            }
160          }
161        }
162        break;
163      default:
164        PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
165                                COLLECTOR_CNR),
166                WM_CONTROL,
167                MPFROM2SHORT(COLLECTOR_CNR, CN_CONTEXTMENU), MPVOID);
168        break;
169      }
170    }
171  MenuAbort:
172    if (msg == UM_CONTEXTMENU)
173      return 0;
174    break;
175
176  case WM_MENUEND:
177    if (hwndButtonPopup == (HWND) mp2) {
178      lastid = WinQueryWindowUShort((HWND) mp2, QWS_ID);
179      WinDestroyWindow(hwndButtonPopup);
180      hwndButtonPopup = (HWND) 0;
181      DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &timestamp,
182                      sizeof(timestamp));
183      switch (lastid) {
184      case DIR_SELECTED:
185      case DIR_VIEW:
186      case DIR_SORT:
187        PaintRecessedWindow(hwnd, NULLHANDLE, TRUE, FALSE);
188        break;
189      }
190    }
191    break;
192
193  case WM_COMMAND:
194    {
195      DIRCNRDATA *dcd;
196      MRESULT mr;
197
198      mr = WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd,
199                                                     QW_PARENT),
200                                      COLLECTOR_CNR), msg, mp1, mp2);
201      if (hwndButtonPopup &&
202          SHORT1FROMMP(mp1) > IDM_DETAILSTITLES &&
203          SHORT1FROMMP(mp1) < IDM_DETAILSSETUP) {
204        dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
205                                                               QW_PARENT),
206                                                COLLECTOR_CNR), QWL_USER);
207        if (dcd)
208          SetDetailsSwitches(hwndButtonPopup, dcd);
209      }
210      return mr;
211    }
212
213  case WM_MOUSEMOVE:
214    {
215      USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
216      char *s = NULL;
217
218      if (fOtherHelp) {
219        if ((!hwndBubble ||
220             WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
221            !WinQueryCapture(HWND_DESKTOP)) {
222          switch (id) {
223          case DIR_SELECTED:
224            s = GetPString(IDS_COLSELECTEDHELP);
225            break;
226          case DIR_TOTALS:
227            s = GetPString(IDS_COLTOTALSHELP);
228            break;
229          case DIR_VIEW:
230            s = GetPString(IDS_DIRCNRVIEWHELP);
231            break;
232          case DIR_SORT:
233            s = GetPString(IDS_DIRCNRSORTHELP);
234            break;
235          case DIR_FILTER:
236            s = GetPString(IDS_DIRCNRFILTERHELP);
237            break;
238          default:
239            break;
240          }
241          if (s)
242            MakeBubble(hwnd, TRUE, s);
243          else if (hwndBubble)
244            WinDestroyWindow(hwndBubble);
245        }
246      }
247      switch (id) {
248      case DIR_FILTER:
249      case DIR_SORT:
250      case DIR_VIEW:
251      case DIR_SELECTED:
252        return CommonTextButton(hwnd, msg, mp1, mp2);
253      }
254    }
255    break;
256
257  case WM_BUTTON3UP:
258  case WM_BUTTON1UP:
259  case WM_BUTTON3DOWN:
260  case WM_BUTTON1DOWN:
261    {
262      USHORT id;
263
264      id = WinQueryWindowUShort(hwnd, QWS_ID);
265      switch (id) {
266      case DIR_FILTER:
267      case DIR_SORT:
268      case DIR_VIEW:
269      case DIR_SELECTED:
270        return CommonTextButton(hwnd, msg, mp1, mp2);
271      }
272    }
273    break;
274
275  case UM_CLICKED:
276  case UM_CLICKED3:
277    {
278      USHORT id, cmd = 0;
279
280      id = WinQueryWindowUShort(hwnd, QWS_ID);
281      switch (id) {
282      case DIR_VIEW:
283      case DIR_SORT:
284      case DIR_SELECTED:
285        PostMsg(hwnd, UM_CONTEXTMENU, MPVOID, MPVOID);
286        break;
287      case DIR_FILTER:
288        cmd = IDM_FILTER;
289        break;
290      default:
291        break;
292      }
293      if (cmd)
294        PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
295                                COLLECTOR_CNR),
296                WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
297    }
298    return 0;
299
300  case DM_DROP:
301  case DM_DRAGOVER:
302  case DM_DRAGLEAVE:
303  case DM_DROPHELP:
304    if (msg == DM_DRAGOVER) {
305      if (!emphasized) {
306        emphasized = TRUE;
307        DrawTargetEmphasis(hwnd, emphasized);
308      }
309    }
310    else {
311      if (emphasized) {
312        emphasized = FALSE;
313        DrawTargetEmphasis(hwnd, emphasized);
314      }
315    }
316    {
317      CNRDRAGINFO cnd;
318      USHORT dcmd;
319
320      switch (msg) {
321      case DM_DROP:
322        dcmd = CN_DROP;
323        break;
324      case DM_DRAGOVER:
325        dcmd = CN_DRAGOVER;
326        break;
327      case DM_DRAGLEAVE:
328        dcmd = CN_DRAGLEAVE;
329        break;
330      case DM_DROPHELP:
331        dcmd = CN_DROPHELP;
332        break;
333      }
334      memset(&cnd, 0, sizeof(cnd));
335      cnd.pDragInfo = (PDRAGINFO) mp1;
336      cnd.pRecord = NULL;
337      return WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_CONTROL,
338                        MPFROM2SHORT(COLLECTOR_CNR, dcmd), MPFROMP(&cnd));
339    }
340  }
341  return PFNWPStatic(hwnd, msg, mp1, mp2);
342}
343
344MRESULT EXPENTRY CollectorClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
345                                        MPARAM mp2)
346{
347  switch (msg) {
348  case UM_CONTAINERHWND:
349    return MRFROMLONG(WinWindowFromID(hwnd, COLLECTOR_CNR));
350
351  case UM_VIEWSMENU:
352    return MRFROMLONG(CheckMenu(&CollectorCnrMenu, COLLECTORCNR_POPUP));
353
354  case MM_PORTHOLEINIT:
355  case WM_INITMENU:
356  case UM_INITMENU:
357  case UM_CONTAINER_FILLED:
358  case UM_FILESMENU:
359  case UM_UPDATERECORD:
360  case UM_UPDATERECORDLIST:
361    return WinSendMsg(WinWindowFromID(hwnd, COLLECTOR_CNR), msg, mp1, mp2);
362
363  case WM_PSETFOCUS:
364  case WM_SETFOCUS:
365    if (mp2)
366      PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
367    break;
368
369  case UM_FOCUSME:
370    WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, COLLECTOR_CNR));
371    break;
372
373  case WM_PAINT:
374    {
375      HPS hps;
376      RECTL rcl;
377
378      hps = WinBeginPaint(hwnd, NULLHANDLE, NULL);
379      if (hps) {
380        WinQueryWindowRect(hwnd, &rcl);
381        WinFillRect(hps, &rcl, CLR_PALEGRAY);
382        CommonTextPaint(hwnd, hps);
383        WinEndPaint(hps);
384      }
385    }
386    break;
387
388  case UM_SIZE:
389  case WM_SIZE:
390    if (msg == UM_SIZE) {
391      SWP swp;
392
393      WinQueryWindowPos(hwnd, &swp);
394      mp1 = MPFROM2SHORT(swp.cx, swp.cy);
395      mp2 = MPFROM2SHORT(swp.cx, swp.cy);
396    }
397    {
398      USHORT cx, cy, bx;
399
400      cx = SHORT1FROMMP(mp2);
401      cy = SHORT2FROMMP(mp2);
402      WinSetWindowPos(WinWindowFromID(hwnd, COLLECTOR_CNR), HWND_TOP,
403                      0, 0, cx, cy - 24, SWP_SHOW | SWP_MOVE | SWP_SIZE);
404      WinSetWindowPos(WinWindowFromID(hwnd, DIR_TOTALS), HWND_TOP,
405                      2,
406                      cy - 22,
407                      (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
408      WinSetWindowPos(WinWindowFromID(hwnd, DIR_SELECTED), HWND_TOP,
409                      2 + (cx / 3) + 2,
410                      cy - 22,
411                      (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
412      bx = (cx - (2 + (((cx / 3) + 2) * 2))) / 3;
413      WinSetWindowPos(WinWindowFromID(hwnd, DIR_VIEW), HWND_TOP,
414                      2 + (((cx / 3) + 2) * 2),
415                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
416      WinSetWindowPos(WinWindowFromID(hwnd, DIR_SORT), HWND_TOP,
417                      2 + (((cx / 3) + 2) * 2) + bx,
418                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
419      WinSetWindowPos(WinWindowFromID(hwnd, DIR_FILTER), HWND_TOP,
420                      2 + (((cx / 3) + 2) * 2) + (bx * 2),
421                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
422    }
423    CommonTextPaint(hwnd, NULLHANDLE);
424    if (msg == UM_SIZE) {
425      WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
426                      SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE);
427      return 0;
428    }
429    break;
430
431  case UM_COMMAND:
432  case WM_COMMAND:
433  case WM_CONTROL:
434  case WM_CLOSE:
435    return WinSendMsg(WinWindowFromID(hwnd, COLLECTOR_CNR), msg, mp1, mp2);
436  }
437  return WinDefWindowProc(hwnd, msg, mp1, mp2);
438}
439
440MRESULT EXPENTRY CollectorObjWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
441                                     MPARAM mp2)
442{
443  ULONG size;
444  DIRCNRDATA *dcd;
445
446  switch (msg) {
447  case WM_CREATE:
448    break;
449
450  case DM_PRINTOBJECT:
451    return MRFROMLONG(DRR_TARGET);
452
453  case DM_DISCARDOBJECT:
454    dcd = INSTDATA(hwnd);
455    if (fFM2Deletes && dcd) {
456      LISTINFO *li;
457      CNRDRAGINFO cni;
458
459      cni.pRecord = NULL;
460      cni.pDragInfo = (PDRAGINFO) mp1;
461      li = DoFileDrop(dcd->hwndCnr, NULL, FALSE, MPVOID, MPFROMP(&cni));
462      if (NumItemsToUnhilite)
463        saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
464                             hwnd,
465                             GetPString(IDS_ERRORTEXT),
466                   GetPString(IDS_EXCEEDPMDRGLMT));
467      if (li) {
468        li->type = (fDefaultDeletePerm) ? IDM_PERMDELETE : IDM_DELETE;
469        if (!PostMsg(hwnd, UM_MASSACTION, MPFROMP(li), MPVOID))
470          FreeListInfo(li);
471        else
472          return MRFROMLONG(DRR_SOURCE);
473      }
474    }
475    return MRFROMLONG(DRR_TARGET);
476
477  case UM_UPDATERECORDLIST:
478    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
479    if (dcd && mp1) {
480      INT numentries = 0;
481      CHAR **list = (CHAR **) mp1;
482
483      while (list[numentries])
484        numentries++;
485      if (numentries)
486        UpdateCnrList(dcd->hwndCnr, list, numentries, FALSE, dcd);
487    }
488    return 0;
489
490  case UM_SETUP:
491    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
492    if (dcd) {
493      /* set unique id */
494      WinSetWindowUShort(hwnd,
495                         QWS_ID,
496                         COLLECTOROBJ_FRAME + (COLLECTOR_FRAME - dcd->id));
497      dcd->hwndObject = hwnd;
498      if (ParentIsDesktop(hwnd, dcd->hwndParent))
499        DosSleep(250L);
500    }
501    else
502      PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
503    return 0;
504
505  case UM_COMMAND:
506    if (mp1) {
507      LISTINFO *li = (LISTINFO *) mp1;
508
509      switch (li->type) {
510      case IDM_DOITYOURSELF:
511      case IDM_APPENDTOCLIP:
512      case IDM_SAVETOCLIP:
513      case IDM_ARCHIVE:
514      case IDM_ARCHIVEM:
515      case IDM_VIEW:
516      case IDM_VIEWTEXT:
517      case IDM_VIEWBINARY:
518      case IDM_VIEWARCHIVE:
519      case IDM_EDIT:
520      case IDM_EDITTEXT:
521      case IDM_EDITBINARY:
522      case IDM_OBJECT:
523      case IDM_SHADOW:
524      case IDM_SHADOW2:
525      case IDM_PRINT:
526      case IDM_ATTRS:
527      case IDM_DELETE:
528      case IDM_PERMDELETE:
529      case IDM_FAKEEXTRACT:
530      case IDM_FAKEEXTRACTM:
531      case IDM_MCIPLAY:
532      case IDM_UPDATE:
533        if (PostMsg(hwnd, UM_MASSACTION, mp1, mp2))
534          return (MRESULT) TRUE;
535        break;
536      default:
537        if (PostMsg(hwnd, UM_ACTION, mp1, mp2))
538          return (MRESULT) TRUE;
539      }
540    }
541    return 0;
542
543  case UM_COLLECT:
544    DosError(FERR_DISABLEHARDERR);
545    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
546    if (dcd) {
547      LISTINFO *li = (LISTINFO *) mp1;
548      INT x;
549      FILEFINDBUF4 fb4;
550      HDIR hdir;
551      ULONG nm;
552      PCNRITEM pci, pciFirst, pciT, pciP = NULL;
553      RECORDINSERT ri;
554      ULONG ulMaxFiles;
555      ULONGLONG ullTotalBytes;
556      CHAR fullname[CCHMAXPATH];
557
558      WinSetWindowText(WinWindowFromID(dcd->hwndClient, DIR_SELECTED),
559                       GetPString(IDS_COLLECTINGTEXT));
560      for (ulMaxFiles = 0; li->list[ulMaxFiles]; ulMaxFiles++) ;        // Count
561
562      if (ulMaxFiles) {
563        pci = WinSendMsg(dcd->hwndCnr, CM_ALLOCRECORD,
564                         MPFROMLONG(EXTRA_RECORD_BYTES),
565                         MPFROMLONG(ulMaxFiles));
566        if (!pci) {
567          Runtime_Error(pszSrcFile, __LINE__, "CM_ALLOCRECORD %u failed",
568                        ulMaxFiles);
569          break;
570        }
571        else {
572          pciFirst = pci;
573          for (x = 0; li->list[x]; x++) {
574            nm = 1L;
575            hdir = HDIR_CREATE;
576            DosError(FERR_DISABLEHARDERR);
577            if (*li->list[x] &&
578                !DosQueryPathInfo(li->list[x], FIL_QUERYFULLNAME,
579                                  fullname, sizeof(fullname)) &&
580                !IsRoot(fullname) &&
581                !FindCnrRecord(dcd->hwndCnr,
582                               fullname,
583                               NULL,
584                               FALSE,
585                               FALSE,
586                               TRUE) &&
587                !DosFindFirst(fullname,
588                              &hdir,
589                              FILE_NORMAL | FILE_DIRECTORY |
590                              FILE_ARCHIVED | FILE_SYSTEM |
591                              FILE_HIDDEN | FILE_READONLY,
592                              &fb4, sizeof(fb4), &nm, FIL_QUERYEASIZE)) {
593              DosFindClose(hdir);
594              priority_normal();
595              *fb4.achName = 0;
596              ullTotalBytes = FillInRecordFromFFB(dcd->hwndCnr,
597                                                  pci,
598                                                  fullname, &fb4, FALSE, dcd);
599              dcd->ullTotalBytes += ullTotalBytes;
600              pciP = pci;
601              pci = (PCNRITEM) pci->rc.preccNextRecord;
602            }
603            else {
604              pciT = pci;
605              pci = (PCNRITEM) pci->rc.preccNextRecord;
606              if (pciP)
607                pciP->rc.preccNextRecord = (PMINIRECORDCORE) pci;
608              else
609                pciFirst = pci;
610              WinSendMsg(hwnd, CM_FREERECORD, MPFROMP(&pciT),
611                         MPFROM2SHORT(1, 0));
612              ulMaxFiles--;
613            }
614            DosSleep(1L);
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 = 0L;
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(1L));
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 = 1L;
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->szFileName);
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(250L);
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 = WinQueryWindowPtr(hwnd, QWL_USER);
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->szFileName) - 'A'] & DRIVE_SLOW)))
1087          WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->szFileName), 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->szFileName), 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->szFileName, '\\');
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 = 12L;
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(64L);
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->szFileName);
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->szFileName);
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            WinSendMsg(hwnd,
1661                       CM_REMOVERECORD,
1662                       MPVOID, MPFROM2SHORT(0, CMA_FREE | CMA_INVALIDATE));
1663            dcd->ullTotalBytes = dcd->selectedbytes = dcd->selectedfiles =
1664              dcd->totalfiles = 0L;
1665            PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1666          }
1667        }
1668        break;
1669
1670      case DID_CANCEL:
1671        if (dcd->amextracted)
1672          dcd->stopflag = 1;            // Request cancel
1673        break;
1674
1675      case IDM_COLLECTOR:
1676        if (mp2) {
1677          LISTINFO *li;
1678
1679          li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
1680          if (li) {
1681            li->list = mp2;
1682            if (!li->list || !li->list[0])
1683              FreeListInfo(li);
1684            else {
1685              li->type = IDM_COLLECT;
1686              if (!PostMsg(dcd->hwndObject, UM_COLLECT, MPFROMP(li), MPVOID))
1687                FreeListInfo(li);
1688            }
1689          }
1690          else
1691            FreeList(mp2);
1692        }
1693        break;
1694
1695      case IDM_UNDELETE:
1696        {
1697          PCNRITEM pci;
1698          CHAR path[CCHMAXPATH];
1699
1700          pci = (PCNRITEM) CurrentRecord(hwnd);
1701          if (pci) {
1702            strcpy(path, pci->szFileName);
1703            MakeValidDir(path);
1704            WinDlgBox(HWND_DESKTOP, hwnd, UndeleteDlgProc, FM3ModHandle,
1705                      UNDEL_FRAME, MPFROMP(path));
1706          }
1707        }
1708        break;
1709
1710      case IDM_GREP:
1711        if (dcd->amextracted)
1712          Runtime_Error(pszSrcFile, __LINE__, "busy");
1713        else {
1714          if (WinDlgBox(HWND_DESKTOP, hwnd, GrepDlgProc,
1715                        FM3ModHandle, GREP_FRAME, (PVOID) & hwnd)) {
1716            dcd->amextracted = TRUE;    // Say busy scanning
1717            disable_menuitem(WinWindowFromID
1718                             (WinQueryWindow(hwndMain, QW_PARENT), FID_MENU),
1719                             IDM_GREP, TRUE);
1720            PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1721          }
1722        }
1723        break;
1724
1725      case IDM_RESORT:
1726        WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(SortCollectorCnr), MPVOID);
1727        break;
1728
1729      case IDM_FILTER:
1730        {
1731          BOOL empty = FALSE;
1732          PCNRITEM pci;
1733          CHAR *p;
1734
1735          if (!*dcd->mask.szMask) {
1736            empty = TRUE;
1737            pci = (PCNRITEM) CurrentRecord(hwnd);
1738            if (pci && !(pci->attrFile & FILE_DIRECTORY)) {
1739              p = strrchr(pci->szFileName, '\\');
1740              if (p) {
1741                p++;
1742                strcpy(dcd->mask.szMask, p);
1743              }
1744            }
1745          }
1746          *(dcd->mask.prompt) = 0;
1747
1748          if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
1749                        FM3ModHandle, MSK_FRAME, MPFROMP(&dcd->mask))) {
1750            size = sizeof(MASK);
1751            PrfWriteProfileData(fmprof, appname, "CollectorFilter",
1752                                &dcd->mask, size);
1753            dcd->suspendview = 1;
1754            WinSendMsg(hwnd, CM_FILTER, MPFROMP(Filter), MPFROMP(&dcd->mask));
1755            dcd->suspendview = 0;
1756            if (fAutoView && hwndMain) {
1757              pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1758                               MPFROMLONG(CMA_FIRST),
1759                               MPFROMSHORT(CRA_CURSORED));
1760              if (pci && (INT) pci != -1 &&
1761                  (!(driveflags[toupper(*pci->szFileName) - 'A'] &
1762                     DRIVE_SLOW)))
1763                WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->szFileName),
1764                           MPVOID);
1765              else
1766                WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1767            }
1768            PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1769          }
1770          else if (empty)
1771            *dcd->mask.szMask = 0;
1772          SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1773                                    DIR_FILTER), &dcd->mask, FALSE);
1774        }
1775        break;
1776
1777      case IDM_HIDEALL:
1778        if (fAutoView && hwndMain)
1779          PostMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1780        dcd->suspendview = 1;
1781        HideAll(hwnd);
1782        dcd->suspendview = 0;
1783        PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1784        break;
1785
1786      case IDM_SELECTLIST:
1787      case IDM_SELECTALL:
1788      case IDM_DESELECTALL:
1789      case IDM_SELECTALLFILES:
1790      case IDM_DESELECTALLFILES:
1791      case IDM_SELECTALLDIRS:
1792      case IDM_DESELECTALLDIRS:
1793      case IDM_SELECTMASK:
1794      case IDM_DESELECTMASK:
1795      case IDM_INVERT:
1796      case IDM_SELECTCLIP:
1797      case IDM_DESELECTCLIP:
1798        {
1799          PCNRITEM pci;
1800
1801          pci = (PCNRITEM) CurrentRecord(hwnd);
1802          if ((INT) pci == -1)
1803            pci = NULL;
1804          if (SHORT1FROMMP(mp1) == IDM_HIDEALL) {
1805            if (pci) {
1806              if (!(pci->rc.flRecordAttr & CRA_SELECTED))
1807                pci->rc.flRecordAttr |= CRA_FILTERED;
1808              WinSendMsg(hwnd, CM_INVALIDATERECORD, MPFROMP(&pci),
1809                         MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
1810              break;
1811            }
1812          }
1813          PostMsg(dcd->hwndObject, UM_SELECT, mp1, MPFROMP(pci));
1814        }
1815        break;
1816
1817      case IDM_RESCAN:
1818        PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPVOID);
1819        break;
1820
1821      case IDM_SHOWLNAMES:
1822      case IDM_SHOWSUBJECT:
1823      case IDM_SHOWEAS:
1824      case IDM_SHOWSIZE:
1825      case IDM_SHOWICON:
1826      case IDM_SHOWLWDATE:
1827      case IDM_SHOWLWTIME:
1828      case IDM_SHOWLADATE:
1829      case IDM_SHOWLATIME:
1830      case IDM_SHOWCRDATE:
1831      case IDM_SHOWCRTIME:
1832      case IDM_SHOWATTR:
1833        AdjustDetailsSwitches(hwnd, dcd->hwndLastMenu,
1834                              SHORT1FROMMP(mp1), NULL,
1835                              "Collector", dcd, FALSE);
1836        break;
1837
1838      case IDM_ICON:
1839      case IDM_TEXT:
1840      case IDM_DETAILS:
1841      case IDM_NAME:
1842      case IDM_MINIICONS:
1843      case IDM_DETAILSTITLES:
1844        {
1845          CNRINFO cnri;
1846
1847          memset(&cnri, 0, sizeof(CNRINFO));
1848          cnri.cb = sizeof(CNRINFO);
1849          WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
1850                     MPFROMLONG(sizeof(CNRINFO)));
1851          switch (SHORT1FROMMP(mp1)) {
1852          case IDM_ICON:
1853            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
1854                                    CV_DETAIL | CV_NAME));
1855            cnri.flWindowAttr |= CV_ICON;
1856            break;
1857          case IDM_NAME:
1858            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
1859                                    CV_DETAIL | CV_NAME));
1860            cnri.flWindowAttr |= CV_NAME;
1861            break;
1862          case IDM_TEXT:
1863            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
1864                                    CV_DETAIL | CV_NAME));
1865            cnri.flWindowAttr |= CV_TEXT;
1866            break;
1867          case IDM_DETAILS:
1868            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
1869                                    CV_DETAIL | CV_NAME));
1870            cnri.flWindowAttr |= CV_DETAIL;
1871            break;
1872          case IDM_MINIICONS:
1873            if (cnri.flWindowAttr & CV_MINI)
1874              cnri.flWindowAttr &= (~CV_MINI);
1875            else
1876              cnri.flWindowAttr |= CV_MINI;
1877            break;
1878          case IDM_DETAILSTITLES:
1879            if (cnri.flWindowAttr & CA_DETAILSVIEWTITLES)
1880              cnri.flWindowAttr &= (~CA_DETAILSVIEWTITLES);
1881            else
1882              cnri.flWindowAttr |= CA_DETAILSVIEWTITLES;
1883            break;
1884          }
1885          cnri.flWindowAttr &= (~(CA_ORDEREDTARGETEMPH | CA_MIXEDTARGETEMPH));
1886          cnri.flWindowAttr |= CV_FLOW;
1887          dcd->flWindowAttr = cnri.flWindowAttr;
1888          PrfWriteProfileData(fmprof, appname, "CollectorflWindowAttr",
1889                              &cnri.flWindowAttr, sizeof(ULONG));
1890          WinSendMsg(hwnd, CM_SETCNRINFO, MPFROMP(&cnri),
1891                     MPFROMLONG(CMA_FLWINDOWATTR));
1892          WinSendMsg(hwnd, CM_INVALIDATERECORD, MPVOID,
1893                     MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
1894          SayView(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1895                                  DIR_VIEW), dcd->flWindowAttr);
1896        }
1897        break;
1898
1899      case IDM_SAVETOLIST:
1900        WinDlgBox(HWND_DESKTOP, hwnd, SaveListDlgProc, FM3ModHandle,
1901                  SAV_FRAME, MPFROMP(&hwnd));
1902        break;
1903
1904      case IDM_SIZES:
1905        {
1906          PCNRITEM pci;
1907
1908          pci = (PCNRITEM) CurrentRecord(hwnd);
1909          if (pci && (INT) pci != -1)
1910            WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, DirSizeProc, FM3ModHandle,
1911                      DSZ_FRAME, pci->szFileName);
1912        }
1913        break;
1914
1915      case IDM_MKDIR:
1916        {
1917          PCNRITEM pci;
1918
1919          pci = (PCNRITEM) CurrentRecord(hwnd);
1920          PMMkDir(dcd->hwndParent, (pci && (INT) pci != -1) ?
1921                  pci->szFileName : NULL, FALSE);
1922        }
1923        break;
1924
1925      case IDM_DOITYOURSELF:
1926      case IDM_UPDATE:
1927      case IDM_COLLECTFROMFILE:
1928      case IDM_OPENWINDOW:
1929      case IDM_OPENSETTINGS:
1930      case IDM_OPENDEFAULT:
1931      case IDM_OPENICON:
1932      case IDM_OPENDETAILS:
1933      case IDM_OPENTREE:
1934      case IDM_OBJECT:
1935      case IDM_SHADOW:
1936      case IDM_SHADOW2:
1937      case IDM_DELETE:
1938      case IDM_PERMDELETE:
1939      case IDM_PRINT:
1940      case IDM_ATTRS:
1941      case IDM_INFO:
1942      case IDM_COPY:
1943      case IDM_MOVE:
1944      case IDM_WPSCOPY:
1945      case IDM_WPSMOVE:
1946      case IDM_COPYPRESERVE:
1947      case IDM_MOVEPRESERVE:
1948      case IDM_WILDCOPY:
1949      case IDM_WILDMOVE:
1950      case IDM_RENAME:
1951      case IDM_COMPARE:
1952      case IDM_EAS:
1953      case IDM_SUBJECT:
1954      case IDM_VIEW:
1955      case IDM_VIEWTEXT:
1956      case IDM_VIEWBINARY:
1957      case IDM_VIEWARCHIVE:
1958      case IDM_EDIT:
1959      case IDM_EDITTEXT:
1960      case IDM_EDITBINARY:
1961      case IDM_SAVETOCLIP:
1962      case IDM_APPENDTOCLIP:
1963      case IDM_ARCHIVE:
1964      case IDM_ARCHIVEM:
1965      case IDM_EXTRACT:
1966      case IDM_MCIPLAY:
1967      case IDM_UUDECODE:
1968      case IDM_MERGE:
1969        {
1970          LISTINFO *li;
1971          ULONG action = UM_ACTION;
1972
1973          li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
1974          if (li) {
1975            li->type = SHORT1FROMMP(mp1);
1976            li->hwnd = hwnd;
1977            li->list = BuildList(hwnd);
1978            if (li->list) {
1979              switch (SHORT1FROMMP(mp1)) {
1980              case IDM_DOITYOURSELF:
1981              case IDM_APPENDTOCLIP:
1982              case IDM_SAVETOCLIP:
1983              case IDM_ARCHIVE:
1984              case IDM_ARCHIVEM:
1985              case IDM_DELETE:
1986              case IDM_PERMDELETE:
1987              case IDM_ATTRS:
1988              case IDM_PRINT:
1989              case IDM_SHADOW:
1990              case IDM_SHADOW2:
1991              case IDM_OBJECT:
1992              case IDM_VIEW:
1993              case IDM_VIEWTEXT:
1994              case IDM_VIEWBINARY:
1995              case IDM_EDIT:
1996              case IDM_EDITTEXT:
1997              case IDM_EDITBINARY:
1998              case IDM_MCIPLAY:
1999              case IDM_UPDATE:
2000              case IDM_INFO:
2001              case IDM_EAS:
2002                action = UM_MASSACTION;
2003                break;
2004              }
2005              if (li->type == IDM_SHADOW || li->type == IDM_OBJECT ||
2006                  li->type == IDM_SHADOW2)
2007                *li->targetpath = 0;
2008              if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID)) {
2009                Runtime_Error(pszSrcFile, __LINE__, "PostMsg");
2010                FreeListInfo(li);
2011              }
2012              else if (fUnHilite)
2013                UnHilite(hwnd, TRUE, &dcd->lastselection);
2014            }
2015            else
2016              free(li);
2017          }
2018        }
2019        break;
2020
2021      default:
2022        if (!cmdloaded)
2023          load_commands();
2024        if (SHORT1FROMMP(mp1) >= IDM_COMMANDSTART &&
2025            SHORT1FROMMP(mp1) < IDM_QUICKTOOLSTART) {
2026          INT x;
2027
2028          x = SHORT1FROMMP(mp1) - IDM_COMMANDSTART;
2029          if (x >= 0) {
2030            x++;
2031            RunCommand(hwnd, x);
2032            if (fUnHilite)
2033              UnHilite(hwnd, TRUE, &dcd->lastselection);
2034          }
2035        }
2036        break;
2037      }
2038    }
2039    return 0;
2040
2041  case UM_FIXCNRMLE:
2042  case UM_FIXEDITNAME:
2043    return CommonCnrProc(hwnd, msg, mp1, mp2);
2044
2045  case UM_FILESMENU:
2046    {
2047      PCNRITEM pci;
2048      HWND menuHwnd = (HWND) 0;
2049
2050      pci = (PCNRITEM) CurrentRecord(hwnd);
2051      if (pci && (INT) pci != -1) {
2052        if (pci->attrFile & FILE_DIRECTORY)
2053          menuHwnd = CheckMenu(&CollectorDirMenu, COLLECTORDIR_POPUP);
2054        else
2055          menuHwnd = CheckMenu(&CollectorFileMenu, COLLECTORFILE_POPUP);
2056      }
2057      return MRFROMLONG(menuHwnd);
2058    }
2059
2060  case WM_CONTROL:
2061    DosError(FERR_DISABLEHARDERR);
2062    if (dcd) {
2063      switch (SHORT2FROMMP(mp1)) {
2064      case CN_CONTEXTMENU:
2065        {
2066          PCNRITEM pci = (PCNRITEM) mp2;
2067
2068          if (pci) {
2069            WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPFROMP(pci),
2070                       MPFROM2SHORT(TRUE, CRA_CURSORED));
2071            MarkAll(hwnd, FALSE, FALSE, TRUE);
2072            if (pci->attrFile & FILE_DIRECTORY)
2073              dcd->hwndLastMenu = CheckMenu(&CollectorDirMenu,
2074                                            COLLECTORDIR_POPUP);
2075            else
2076              dcd->hwndLastMenu = CheckMenu(&CollectorFileMenu,
2077                                            COLLECTORFILE_POPUP);
2078          }
2079          else {
2080            dcd->hwndLastMenu = CheckMenu(&CollectorCnrMenu,
2081                                          COLLECTORCNR_POPUP);
2082            if (dcd->hwndLastMenu && !dcd->cnremphasized) {
2083              WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
2084                         MPFROM2SHORT(TRUE, CRA_SOURCE));
2085              dcd->cnremphasized = TRUE;
2086            }
2087          }
2088          if (dcd->hwndLastMenu) {
2089            if (dcd->hwndLastMenu == CollectorCnrMenu) {
2090              SetViewMenu(dcd->hwndLastMenu, dcd->flWindowAttr);
2091              SetDetailsSwitches(dcd->hwndLastMenu, dcd);
2092              if (dcd->flWindowAttr & CV_MINI)
2093                WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
2094              disable_menuitem(dcd->hwndLastMenu, DID_CANCEL,
2095                               !dcd->amextracted);
2096              disable_menuitem(dcd->hwndLastMenu, IDM_GREP, dcd->amextracted);
2097            }
2098            if (!PopupMenu(hwnd, hwnd, dcd->hwndLastMenu)) {
2099              if (dcd->cnremphasized) {
2100                WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
2101                           MPFROM2SHORT(FALSE, CRA_SOURCE));
2102                dcd->cnremphasized = TRUE;
2103              }
2104              MarkAll(hwnd, TRUE, FALSE, TRUE);
2105            }
2106          }
2107        }
2108        break;
2109
2110      case CN_DROPHELP:
2111        if (mp2) {
2112          PDRAGINFO pDInfo;
2113          PCNRITEM pci;
2114          ULONG numitems;
2115          USHORT usOperation;
2116                APIRET rc;
2117
2118          pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2119          pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2120          if (!DrgAccessDraginfo(pDInfo)) {
2121            Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
2122                      "DrgAccessDraginfo");
2123            return 0;
2124          }
2125          numitems = DrgQueryDragitemCount(pDInfo);
2126          usOperation = pDInfo->usOperation;
2127          FreeDragInfoData(hwnd, pDInfo);
2128          saymsg(MB_ENTER | MB_ICONASTERISK,
2129                 hwnd,
2130                 GetPString(IDS_DROPHELPHDRTEXT),
2131                 GetPString(IDS_DROPHELPTEXT),
2132                 numitems,
2133                 &"s"[numitems == 1L],
2134                 (pci) ? NullStr : GetPString(IDS_NOTEXT),
2135                 (pci) ? NullStr : " ",
2136                 (pci) ? pci->szFileName : NullStr,
2137                 (pci) ? " " : NullStr,
2138                 GetPString((usOperation == DO_COPY) ?
2139                            IDS_COPYTEXT :
2140                            (usOperation == DO_LINK) ?
2141                            IDS_LINKTEXT : IDS_MOVETEXT));
2142        }
2143        return 0;
2144
2145      case CN_DRAGLEAVE:
2146        if (mp2) {
2147          PDRAGINFO pDInfo;
2148
2149          // fixme to know why needed
2150          pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2151          DrgAccessDraginfo(pDInfo);    /* Access DRAGINFO */
2152          DrgFreeDraginfo(pDInfo);      /* Free DRAGINFO */
2153        }
2154        return 0;
2155
2156      case CN_DRAGAFTER:
2157      case CN_DRAGOVER:
2158        if (mp2) {
2159          PDRAGITEM pDItem;     /* Pointer to DRAGITEM */
2160          PDRAGINFO pDInfo;     /* Pointer to DRAGINFO */
2161          PCNRITEM pci;
2162          USHORT uso;
2163
2164          pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2165          // if(SHORT1FROMMP(mp1) == CN_DRAGAFTER)
2166          //    pci = NULL;
2167          pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2168          if (!DrgAccessDraginfo(pDInfo)) {
2169            Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
2170                      "DrgAccessDraginfo");
2171            return (MRFROM2SHORT(DOR_NODROP, 0));       /* Drop not valid */
2172          }
2173          if (pci) {
2174            if (pci->rc.flRecordAttr & CRA_SOURCE) {
2175              DrgFreeDraginfo(pDInfo);
2176              return (MRFROM2SHORT(DOR_NODROP, 0));
2177            }
2178            uso = pDInfo->usOperation;
2179            if (uso == DO_DEFAULT)
2180              uso = (fCopyDefault) ? DO_COPY : DO_MOVE;
2181            if (!(pci->attrFile & FILE_DIRECTORY)) {
2182              if (uso != DO_LINK && uso != DO_MOVE && uso != DO_COPY) {
2183                DrgFreeDraginfo(pDInfo);
2184                return MRFROM2SHORT(DOR_NODROP, 0);
2185              }
2186              if (uso != DO_LINK &&
2187                  !(driveflags[toupper(*pci->szFileName) - 'A'] &
2188                    DRIVE_NOTWRITEABLE)) {
2189                ARC_TYPE *info = NULL;
2190
2191                if (!fQuickArcFind &&
2192                    !(driveflags[toupper(*pci->szFileName) - 'A'] &
2193                      DRIVE_SLOW))
2194                  info = find_type(pci->szFileName, NULL);
2195                else
2196                  info = quick_find_type(pci->szFileName, NULL);
2197                if (!info || ((uso == DO_MOVE && !info->move) ||
2198                              (uso == DO_COPY && !info->create))) {
2199                  DrgFreeDraginfo(pDInfo);
2200                  return MRFROM2SHORT(DOR_NODROP, 0);
2201                }
2202              }
2203            }
2204          }
2205          pDItem = DrgQueryDragitemPtr(pDInfo,  /* Access DRAGITEM */
2206                                       0);      /* Index to DRAGITEM */
2207          if (DrgVerifyRMF(pDItem,      /* Check valid rendering */
2208                           DRM_OS2FILE, /* mechanisms and data */
2209                           NULL)) {
2210            DrgFreeDraginfo(pDInfo);    /* Free DRAGINFO */
2211            if (pci) {
2212              if (driveflags[toupper(*pci->szFileName) - 'A'] &
2213                  DRIVE_NOTWRITEABLE)
2214                return MRFROM2SHORT(DOR_DROP, DO_LINK);
2215              if (toupper(*pci->szFileName) < 'C')
2216                return MRFROM2SHORT(DOR_DROP, DO_COPY);
2217              return MRFROM2SHORT(DOR_DROP,     /* Return okay to drop */
2218                                  ((fCopyDefault) ? DO_COPY : DO_MOVE));
2219            }
2220            else
2221              return MRFROM2SHORT(DOR_DROP,     /* Return okay to drop */
2222                                  DO_COPY);
2223          }
2224          DrgFreeDraginfo(pDInfo);      /* Free DRAGINFO */
2225        }
2226        return (MRFROM2SHORT(DOR_NODROP, 0));   /* Drop not valid */
2227
2228      case CN_INITDRAG:
2229        if (mp2) {
2230          BOOL wasemphasized = FALSE;
2231          PCNRDRAGINIT pcd = (PCNRDRAGINIT) mp2;
2232          PCNRITEM pci;
2233
2234          if (pcd) {
2235            pci = (PCNRITEM) pcd->pRecord;
2236            if (pci) {
2237              if (pci->rc.flRecordAttr & CRA_SELECTED)
2238                wasemphasized = TRUE;
2239              if (IsRoot(pci->szFileName))
2240                break;
2241              if (hwndStatus2)
2242                WinSetWindowText(hwndStatus2,
2243                                 GetPString(IDS_DRAGFILEOBJTEXT));
2244              if (DoFileDrag(hwnd, dcd->hwndObject, mp2, NULL, NULL, TRUE)) {
2245                if ((fUnHilite && wasemphasized) || NumItemsToUnhilite)
2246                  UnHilite(hwnd, TRUE, &dcd->lastselection);
2247              }
2248              if (hwndStatus2)
2249                PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2250            }
2251          }
2252        }
2253        return 0;
2254
2255      case CN_DROP:
2256        if (mp2) {
2257          LISTINFO *li;
2258          ULONG action = UM_ACTION;
2259
2260          li = DoFileDrop(hwnd, NULL, TRUE, mp1, mp2);
2261          if (NumItemsToUnhilite)
2262            saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
2263                                 hwnd,
2264                                 GetPString(IDS_ERRORTEXT),
2265                       GetPString(IDS_EXCEEDPMDRGLMT));
2266          if (li) {
2267            if (!*li->targetpath) {
2268              li->type = IDM_COLLECT;
2269              action = UM_COLLECT;
2270            }
2271            else {
2272              if (li->list && li->list[0] && IsRoot(li->list[0]))
2273                li->type = DO_LINK;
2274              else if (fDragndropDlg && (!*li->arcname || !li->info)) {
2275                CHECKLIST cl;
2276
2277                memset(&cl, 0, sizeof(cl));
2278                cl.size = sizeof(cl);
2279                cl.flags = li->type;
2280                cl.list = li->list;
2281                cl.cmd = li->type;
2282                cl.prompt = li->targetpath;
2283                li->type = WinDlgBox(HWND_DESKTOP, dcd->hwndParent,
2284                                     DropListProc, FM3ModHandle,
2285                                     DND_FRAME, MPFROMP(&cl));
2286                if (li->type == DID_ERROR)
2287                  Win_Error(DND_FRAME, HWND_DESKTOP, pszSrcFile, __LINE__,
2288                            "Drag & Drop Dialog");
2289                if (!li->type) {
2290                  FreeListInfo(li);
2291                  return 0;
2292                }
2293                li->list = cl.list;
2294                if (!li->list || !li->list[0]) {
2295                  FreeListInfo(li);
2296                  return 0;
2297                }
2298              }
2299              switch (li->type) {
2300              case DND_LAUNCH:
2301                strcat(li->targetpath, " %a");
2302                ExecOnList(dcd->hwndParent, li->targetpath,
2303                           PROMPT | WINDOWED, NULL, li->list, NULL);
2304                FreeList(li->list);
2305                li->list = NULL;
2306                break;
2307              case DO_LINK:
2308                if (fLinkSetsIcon) {
2309                  li->type = IDM_SETICON;
2310                  action = UM_MASSACTION;
2311                }
2312                else
2313                  li->type = IDM_COMPARE;
2314                break;
2315              case DND_EXTRACT:
2316                if (*li->targetpath && !IsFile(li->targetpath))
2317                  li->type = IDM_EXTRACT;
2318                break;
2319              case DND_MOVE:
2320                li->type = IDM_MOVE;
2321                if (*li->targetpath && IsFile(li->targetpath) == 1) {
2322                  action = UM_MASSACTION;
2323                  li->type = IDM_ARCHIVEM;
2324                }
2325                break;
2326              case DND_WILDMOVE:
2327                li->type = IDM_WILDMOVE;
2328                if (*li->targetpath && IsFile(li->targetpath) == 1) {
2329                  action = UM_MASSACTION;
2330                  li->type = IDM_ARCHIVEM;
2331                }
2332                break;
2333              case DND_OBJECT:
2334                li->type = IDM_OBJECT;
2335                action = UM_MASSACTION;
2336                break;
2337              case DND_SHADOW:
2338                li->type = IDM_SHADOW;
2339                action = UM_MASSACTION;
2340                break;
2341              case DND_COMPARE:
2342                li->type = IDM_COMPARE;
2343                break;
2344              case DND_SETICON:
2345                action = UM_MASSACTION;
2346                li->type = IDM_SETICON;
2347                break;
2348              case DND_WILDCOPY:
2349                li->type = IDM_WILDCOPY;
2350                if (*li->targetpath && IsFile(li->targetpath) == 1) {
2351                  action = UM_MASSACTION;
2352                  li->type = IDM_ARCHIVE;
2353                }
2354                break;
2355              case DND_COPY:
2356                li->type = IDM_COPY;
2357                if (*li->targetpath && IsFile(li->targetpath) == 1) {
2358                  action = UM_MASSACTION;
2359                  li->type = IDM_ARCHIVE;
2360                }
2361                break;
2362              default:
2363                if (*li->arcname && li->info) {
2364                  action = UM_MASSACTION;
2365                  li->type =
2366                    (li->type ==
2367                     DO_MOVE) ? IDM_FAKEEXTRACTM : IDM_FAKEEXTRACT;
2368                }
2369                else if (*li->targetpath && IsFile(li->targetpath) == 1) {
2370                  action = UM_MASSACTION;
2371                  li->type =
2372                    (li->type == DO_MOVE) ? IDM_ARCHIVEM : IDM_ARCHIVE;
2373                }
2374                else
2375                  li->type = (li->type == DO_MOVE) ? IDM_MOVE : IDM_COPY;
2376                break;
2377              }
2378            }
2379            if (!li->list || !li->list[0])
2380              FreeListInfo(li);
2381            else if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID))
2382              FreeListInfo(li);
2383            else {
2384              USHORT usop = 0;
2385
2386              switch (li->type) {
2387              case IDM_COPY:
2388              case IDM_WILDCOPY:
2389                usop = DO_COPY;
2390                break;
2391              case IDM_MOVE:
2392              case IDM_WILDMOVE:
2393              case IDM_ARCHIVEM:
2394                usop = DO_MOVE;
2395                break;
2396              }
2397              if (usop)
2398                return MRFROM2SHORT(DOR_DROP, usop);
2399            }
2400          }
2401        }
2402        return 0;
2403
2404      case CN_BEGINEDIT:
2405      case CN_REALLOCPSZ:
2406      case CN_ENDEDIT:
2407        {
2408          MRESULT mre;
2409
2410          mre = CnrDirectEdit(hwnd, msg, mp1, mp2);
2411          if (mre != (MRESULT) - 1)
2412            return mre;
2413        }
2414        break;
2415
2416      case CN_EMPHASIS:
2417        if (mp2) {
2418          PNOTIFYRECORDEMPHASIS pre = mp2;
2419          PCNRITEM pci;
2420          CHAR s[CCHMAXPATH + 91], tb[81], tf[81], *p;
2421
2422          pci = (PCNRITEM) ((pre) ? pre->pRecord : NULL);
2423          if (!pci) {
2424            if (hwndStatus2)
2425              WinSetWindowText(hwndStatus2, NullStr);
2426            if (fMoreButtons) {
2427              WinSetWindowText(hwndName, NullStr);
2428              WinSetWindowText(hwndDate, NullStr);
2429              WinSetWindowText(hwndAttr, NullStr);
2430            }
2431            if (hwndMain)
2432              WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
2433            break;
2434          }
2435          if (pre->fEmphasisMask & CRA_SELECTED) {
2436            if (pci->rc.flRecordAttr & CRA_SELECTED) {
2437              dcd->selectedbytes += (pci->cbFile + pci->easize);
2438              dcd->selectedfiles++;
2439            }
2440            else if (dcd->selectedfiles) {
2441              dcd->selectedbytes -= (pci->cbFile + pci->easize);
2442              dcd->selectedfiles--;
2443            }
2444            if (!dcd->suspendview) {
2445              commafmt(tf, sizeof(tf), dcd->selectedfiles);
2446              CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, ' ');
2447              sprintf(s, "%s / %s", tf, tb);
2448              WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
2449            }
2450          }
2451          if (!dcd->suspendview &&
2452              WinQueryActiveWindow(dcd->hwndParent) == dcd->hwndFrame) {
2453            if (pre->fEmphasisMask & CRA_CURSORED) {
2454              if (pci->rc.flRecordAttr & CRA_CURSORED) {
2455                if (fSplitStatus && hwndStatus2) {
2456                  if (pci->attrFile & FILE_DIRECTORY)
2457                    p = pci->pszFileName;
2458                  else {
2459                    p = strrchr(pci->szFileName, '\\');
2460                    if (p) {
2461                      if (*(p + 1))
2462                        p++;
2463                      else
2464                        p = pci->pszFileName;
2465                    }
2466                    else
2467                      p = pci->pszFileName;
2468                  }
2469                  CommaFmtULL(tb, sizeof(tb), pci->cbFile + pci->easize, ' ');
2470                  if (!fMoreButtons)
2471                    sprintf(s, " %s  %04u/%02u/%02u %02u:%02u:%02u  [%s]  %s",
2472                            tb, pci->date.year,
2473                            pci->date.month, pci->date.day, pci->time.hours,
2474                            pci->time.minutes, pci->time.seconds,
2475                            pci->pszDispAttr, p);
2476                  else {
2477                    if (pci->cbFile + pci->easize > 1024)
2478                      CommaFmtULL(tf, sizeof(tf), pci->cbFile + pci->easize,
2479                                  ' ');
2480                    else
2481                      *tf = 0;
2482                    sprintf(s, GetPString(IDS_STATUSSIZETEXT),
2483                            tb,
2484                            *tf ? " (" : NullStr, tf, *tf ? ")" : NullStr);
2485                  }
2486                  WinSetWindowText(hwndStatus2, s);
2487                }
2488                if (fMoreButtons) {
2489                  WinSetWindowText(hwndName, pci->pszFileName);
2490                  sprintf(s, "%04u/%02u/%02u %02u:%02u:%02u",
2491                          pci->date.year, pci->date.month,
2492                          pci->date.day, pci->time.hours, pci->time.minutes,
2493                          pci->time.seconds);
2494                  WinSetWindowText(hwndDate, s);
2495                  WinSetWindowText(hwndAttr, pci->pszDispAttr);
2496                }
2497              }
2498            }
2499          }
2500          if (!dcd->suspendview && hwndMain &&
2501              (pre->fEmphasisMask & CRA_CURSORED) &&
2502              (pci->rc.flRecordAttr & CRA_CURSORED) &&
2503              WinQueryActiveWindow(dcd->hwndParent) == dcd->hwndFrame)
2504            WinSendMsg(hwndMain, UM_LOADFILE,
2505                       MPFROMP(((fComments
2506                                 || (pci->attrFile & FILE_DIRECTORY) ==
2507                                 0) ? pci->szFileName : NULL)), MPVOID);
2508        }
2509        break;
2510
2511      case CN_ENTER:
2512        if (mp2) {
2513          PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
2514          FILEFINDBUF3 ffb;
2515          HDIR hDir = HDIR_CREATE;
2516          ULONG nm = 1L;
2517          APIRET status = 0;
2518
2519          SetShiftState();
2520          if (pci) {
2521            if (pci->rc.flRecordAttr & CRA_INUSE)
2522              break;
2523            DosError(FERR_DISABLEHARDERR);
2524            status = DosFindFirst(pci->szFileName, &hDir,
2525                                  FILE_NORMAL | FILE_DIRECTORY |
2526                                  FILE_ARCHIVED | FILE_READONLY |
2527                                  FILE_HIDDEN | FILE_SYSTEM,
2528                                  &ffb, sizeof(ffb), &nm, FIL_STANDARD);
2529            priority_bumped();
2530            if (!status) {
2531              DosFindClose(hDir);
2532              if (ffb.attrFile & FILE_DIRECTORY) {
2533                if ((shiftstate & (KC_CTRL | KC_ALT)) == (KC_CTRL | KC_ALT))
2534                  PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_SHOWALLFILES, 0),
2535                          MPVOID);
2536                else if ((shiftstate & (KC_CTRL | KC_SHIFT)) ==
2537                         (KC_CTRL | KC_SHIFT))
2538                  OpenObject(pci->szFileName, Settings, dcd->hwndFrame);
2539                else if (shiftstate & KC_CTRL)
2540                  OpenObject(pci->szFileName, Default, dcd->hwndFrame);
2541                else
2542                  OpenDirCnr(HWND_DESKTOP,
2543                             hwndMain,
2544                             dcd->hwndFrame, FALSE, pci->szFileName);
2545              }
2546              else {
2547                SWP swp;
2548
2549                WinSendMsg(hwnd,
2550                           CM_SETRECORDEMPHASIS,
2551                           MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_INUSE));
2552                WinQueryWindowPos(dcd->hwndFrame, &swp);
2553                DefaultViewKeys(hwnd,
2554                                dcd->hwndFrame,
2555                                dcd->hwndParent, &swp, pci->szFileName);
2556                WinSendMsg(hwnd,
2557                           CM_SETRECORDEMPHASIS,
2558                           MPFROMP(pci),
2559                           MPFROM2SHORT(FALSE, CRA_INUSE |
2560                                        ((fUnHilite) ? CRA_SELECTED : 0)));
2561              }
2562            }
2563            else
2564              WinSendMsg(hwnd,
2565                         CM_REMOVERECORD,
2566                         MPFROMP(&pci),
2567                         MPFROM2SHORT(1,
2568                                      CMA_FREE | CMA_INVALIDATE | CMA_ERASE));
2569          }
2570        }
2571        break;
2572      }
2573    }
2574    return 0;
2575
2576  case UM_LOADFILE:
2577    if (dcd && mp2) {
2578      HWND ret;
2579
2580      ret = StartMLEEditor(dcd->hwndParent,
2581                           (INT) mp1, (CHAR *) mp2, dcd->hwndFrame);
2582      if (mp2)
2583        free((CHAR *) mp2);
2584      return MRFROMLONG(ret);
2585    }
2586    return 0;
2587
2588  case UM_CLOSE:
2589    WinDestroyWindow(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
2590                                    QW_PARENT));
2591    return 0;
2592
2593  case UM_FOLDUP:
2594    if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
2595      DosExit(EXIT_PROCESS, 1);
2596    return 0;
2597
2598  case WM_CLOSE:
2599    if (dcd) {
2600      dcd->namecanchange = TRUE;
2601      dcd->stopflag = 1;
2602      if (dcd->amextracted)
2603        return 0;                       // Can not close yet
2604    }
2605    WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
2606    if (dcd) {
2607      if (!dcd->dontclose && ParentIsDesktop(hwnd, dcd->hwndParent))
2608        PostMsg(hwnd, UM_FOLDUP, MPVOID, MPVOID);
2609      if (dcd->hwndObject) {
2610        DosSleep(64L);
2611        if (!PostMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID))
2612          WinSendMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID);
2613      }
2614    }
2615    else
2616      WinSendMsg(hwnd, UM_CLOSE, MPVOID, MPVOID);
2617    return 0;
2618
2619  case WM_DESTROY:
2620    if (CollectorDirMenu)
2621      WinDestroyWindow(CollectorDirMenu);
2622    if (CollectorFileMenu)
2623      WinDestroyWindow(CollectorFileMenu);
2624    if (CollectorCnrMenu)
2625      WinDestroyWindow(CollectorCnrMenu);
2626    CollectorCnrMenu = CollectorFileMenu = CollectorDirMenu = (HWND) 0;
2627    Collector = (HWND) 0;
2628    EmptyCnr(hwnd);
2629    break;
2630  }
2631  return (dcd && dcd->oldproc) ? dcd->oldproc(hwnd, msg, mp1, mp2) :
2632    PFNWPCnr(hwnd, msg, mp1, mp2);
2633}
2634
2635HWND StartCollector(HWND hwndParent, INT flags)
2636{
2637  HWND hwndFrame = (HWND) 0;
2638  HWND hwndClient;
2639  ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
2640    FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE;
2641  USHORT id;
2642  DIRCNRDATA *dcd;
2643
2644  static USHORT idinc = 0;
2645
2646  if (ParentIsDesktop(hwndParent, hwndParent))
2647    FrameFlags |= (FCF_TASKLIST | FCF_SHELLPOSITION | FCF_MENU);
2648  if (Collector) {
2649    WinSetWindowPos(WinQueryWindow(WinQueryWindow(Collector,
2650                                                  QW_PARENT),
2651                                   QW_PARENT),
2652                    HWND_TOP, 0, 0, 0, 0, SWP_SHOW | SWP_RESTORE);
2653    return WinQueryWindow(WinQueryWindow(Collector, QW_PARENT), QW_PARENT);
2654  }
2655  hwndFrame = WinCreateStdWindow(hwndParent,
2656                                 WS_VISIBLE,
2657                                 &FrameFlags,
2658                                 WC_COLLECTOR,
2659                                 NULL,
2660                                 WS_VISIBLE | fwsAnimate,
2661                                 FM3ModHandle, COLLECTOR_FRAME, &hwndClient);
2662  if (hwndFrame && hwndClient) {
2663    id = COLLECTOR_FRAME + idinc++;
2664    WinSetWindowUShort(hwndFrame, QWS_ID, id);
2665    dcd = xmallocz(sizeof(DIRCNRDATA), pszSrcFile, __LINE__);
2666    if (!dcd) {
2667      Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2668      PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
2669      hwndFrame = (HWND) 0;
2670    }
2671    else {
2672      dcd->size = sizeof(DIRCNRDATA);
2673      dcd->id = id;
2674      dcd->type = COLLECTOR_FRAME;
2675      dcd->hwndParent = (hwndParent) ? hwndParent : HWND_DESKTOP;
2676      dcd->hwndFrame = hwndFrame;
2677      dcd->hwndClient = hwndClient;
2678      if (flags & 4)
2679        dcd->dontclose = TRUE;
2680      {
2681        PFNWP oldproc;
2682
2683        oldproc = WinSubclassWindow(hwndFrame, (PFNWP) CollectorFrameWndProc);
2684        WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
2685      }
2686      dcd->hwndCnr = WinCreateWindow(hwndClient,
2687                                     WC_CONTAINER,
2688                                     NULL,
2689                                     CCS_AUTOPOSITION | CCS_MINIICONS |
2690                                     CCS_MINIRECORDCORE | ulCnrType |
2691                                     WS_VISIBLE,
2692                                     0,
2693                                     0,
2694                                     0,
2695                                     0,
2696                                     hwndClient,
2697                                     HWND_TOP,
2698                                     (ULONG) COLLECTOR_CNR, NULL, NULL);
2699      if (!dcd->hwndCnr) {
2700        Win_Error2(hwndClient, hwndClient, pszSrcFile, __LINE__,
2701                   IDS_WINCREATEWINDOW);
2702        PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
2703        free(dcd);
2704        hwndFrame = (HWND) 0;
2705      }
2706      else {
2707        Collector = dcd->hwndCnr;
2708        WinSetWindowPtr(dcd->hwndCnr, QWL_USER, (PVOID) dcd);
2709        WinSetWindowText(hwndFrame, GetPString(IDS_COLLECTORTITLETEXT));
2710        if (FrameFlags & FCF_MENU) {
2711          if (!fToolbar) {
2712            HWND hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
2713
2714            if (hwndMenu) {
2715              WinSendMsg(hwndMenu,
2716                         MM_DELETEITEM,
2717                         MPFROM2SHORT(IDM_SEEALL, FALSE), MPVOID);
2718              WinSendMsg(hwndMenu,
2719                         MM_DELETEITEM,
2720                         MPFROM2SHORT(IDM_GREP, FALSE), MPVOID);
2721              WinSendMsg(hwndMenu,
2722                         MM_DELETEITEM,
2723                         MPFROM2SHORT(IDM_CLEARCNR, FALSE), MPVOID);
2724              WinSendMsg(hwndMenu,
2725                         MM_DELETEITEM,
2726                         MPFROM2SHORT(IDM_REMOVE, FALSE), MPVOID);
2727            }
2728          }
2729        }
2730        dcd->oldproc = WinSubclassWindow(dcd->hwndCnr,
2731                                         (PFNWP) CollectorCnrWndProc);
2732        {
2733          USHORT ids[] = { DIR_TOTALS, DIR_SELECTED, DIR_VIEW, DIR_SORT,
2734            DIR_FILTER, 0
2735          };
2736
2737          CommonCreateTextChildren(dcd->hwndClient,
2738                                   WC_COLSTATUS, ids);
2739        }
2740        if (FrameFlags & FCF_SHELLPOSITION)
2741          PostMsg(hwndClient, UM_SIZE, MPVOID, MPVOID);
2742        if (!PostMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID))
2743          WinSendMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID);
2744      }
2745    }
2746  }
2747  return hwndFrame;
2748}
Note: See TracBrowser for help on using the repository browser.