source: trunk/dll/collect.c @ 672

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

Use dcd->ulItemsToUnHilite
Sync UnHilite? calls with arg mods

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