source: trunk/dll/collect.c @ 750

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

Minor clean up

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