source: trunk/dll/arccnrs.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: 91.4 KB
Line 
1
2/***********************************************************************
3
4  $Id: arccnrs.c 672 2007-05-13 05:57:48Z stevenhl $
5
6  Archive containers
7
8  Copyright (c) 1993-98 M. Kimes
9  Copyright (c) 2001, 2007 Steven H. Levine
10
11  11 Jun 02 SHL Ensure archive name not garbage
12  22 May 03 SHL ArcObjWndProc: fix UM_RESCAN now that we understand it
13  01 Aug 04 SHL Rework lstrip/rstrip usage
14  23 May 05 SHL Use QWL_USER
15  25 May 05 SHL Rename comnam to szCommonName and fix typo
16  25 May 05 SHL Use ULONGLONG and CommaFmtULL
17  05 Jun 05 SHL Drop obsolete, localize
18  05 Jun 05 SHL Correct last sort logic
19  05 Jun 05 SHL Use QWL_USER
20  22 Jun 05 SHL ArcSort: correct typo in last sort fix
21  13 Aug 05 SHL FillArcCnr: optimize
22  08 Dec 05 SHL FillArcCnr: allow list start and end markers to be empty (i.e. tar)
23  08 Dec 05 SHL ArcCnrWndProc: suppress IDM_EXTRACT if no simple extract (i.e. tar)
24  30 Dec 05 SHL ArcCnrWndProc: correct date/time column display setup
25  29 May 06 SHL Comments
26  14 Jul 06 SHL Use Runtime_Error
27  26 Jul 06 SHL Correct SelectAll usage
28  29 Jul 06 SHL Use xfgets_bstripcr
29  31 Jul 06 SHL Lower priority for archives with more than 1000 entries
30  02 Aug 06 SHL Add logic to stop processing large archives
31  23 Aug 06 SHL Integrate John Small's switch list title logic
32  03 Nov 06 SHL Renames
33  14 Mar 07 SHL ArcObjWndProc/UM_ENTER: delay before starting viewer
34  30 Mar 07 GKY Remove GetPString for window class names
35  06 Apr 07 GKY Work around PM DragInfo and DrgFreeISH limit
36  06 Apr 07 GKY Add some error checking in drag/drop
37  20 Apr 07 SHL Sync with NumItemsToUnhilite mods
38  21 Apr 07 GKY Find FM2Utils by path or utils directory
39  12 May 07 SHL Use dcd->ulItemsToUnHilite; sync with UnHilite arg mods
40
41***********************************************************************/
42
43#define INCL_DOS
44#define INCL_DOSERRORS
45#define INCL_WIN
46#define INCL_GPI
47#define INCL_LONGLONG
48#include <os2.h>
49
50#include <stdarg.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <ctype.h>
55#include <time.h>
56#include <direct.h>
57#include <share.h>
58#include <limits.h>
59
60#include "fm3dll.h"
61#include "fm3dlg.h"
62#include "fm3str.h"
63#include "mle.h"
64
65#pragma data_seg(DATA1)
66
67static INT DefArcSortFlags;
68static PSZ pszSrcFile = __FILE__;
69
70#pragma alloc_text(ARCCNRS,ArcCnrWndProc,ArcObjWndProc,ArcClientWndProc)
71#pragma alloc_text(ARCCNRS,ArcTextProc,FillArcCnr,ArcFilter)
72#pragma alloc_text(ARCCNRS,ArcSort,ArcFrameWndProc,IsArcThere,ArcErrProc)
73#pragma alloc_text(STARTUP,StartArcCnr)
74
75static MRESULT EXPENTRY ArcErrProc(HWND hwnd, ULONG msg, MPARAM mp1,
76                                   MPARAM mp2)
77{
78  ARCDUMP *ad;
79
80  switch (msg) {
81  case WM_INITDLG:
82    if (!mp2)
83      WinDismissDlg(hwnd, 0);
84    else {
85      ad = (ARCDUMP *) mp2;
86      WinSetWindowPtr(hwnd, QWL_USER, ad);
87      if (ad->errmsg)
88        WinSetDlgItemText(hwnd, ARCERR_TEXT, ad->errmsg);
89      if (!ad->info->test)
90        WinEnableWindow(WinWindowFromID(hwnd, ARCERR_TEST), FALSE);
91      if (ad->listname) {
92        MLEsetlimit(WinWindowFromID(hwnd, ARCERR_MLE), -1L);
93        MLEsetformat(WinWindowFromID(hwnd, ARCERR_MLE), MLFIE_NOTRANS);
94        MLEsetcurpos(WinWindowFromID(hwnd, ARCERR_MLE),
95                     MLEgetlen(WinWindowFromID(hwnd, ARCERR_MLE)));
96        MLEinsert(WinWindowFromID(hwnd, ARCERR_MLE),
97                  GetPString(IDS_ARCHIVERREPORTTEXT));
98        MLEinsertfile(WinWindowFromID(hwnd, ARCERR_MLE), ad->listname);
99      }
100    }
101    break;
102
103  case WM_COMMAND:
104    switch (SHORT1FROMMP(mp1)) {
105    case DID_CANCEL:
106      WinDismissDlg(hwnd, 0);
107      break;
108
109    case IDM_HELP:
110      if (hwndHelp) {
111        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
112                   MPFROM2SHORT(HELP_ARCERR, 0), MPFROMSHORT(HM_RESOURCEID));
113      }
114      break;
115
116    case DID_OK:
117      ad = WinQueryWindowPtr(hwnd, QWL_USER);
118      WinDlgBox(HWND_DESKTOP, hwnd, ArcReviewDlgProc, FM3ModHandle,
119                AD_FRAME, MPFROMP(ad));
120      WinDismissDlg(hwnd, 0);
121      break;
122
123    case ARCERR_VIEW:
124      ad = WinQueryWindowPtr(hwnd, QWL_USER);
125      {
126        CHAR *list[2];
127
128        list[0] = ad->arcname;
129        list[1] = NULL;
130        if (TestBinary(ad->arcname)) {
131          if (*binview)
132            ExecOnList((HWND) 0, binview, WINDOWED | SEPARATE, NULL, list,
133                       NULL);
134          else
135            StartMLEEditor(HWND_DESKTOP, 16 + 4 + 1, ad->arcname, hwnd);
136        }
137        else {
138          if (*viewer) {
139            ExecOnList((HWND) 0, viewer, WINDOWED | SEPARATE |
140                         (fViewChild ? CHILD : 0),
141                       NULL, list, NULL);
142          }
143          else
144            StartMLEEditor(HWND_DESKTOP, 8 + 4 + 1, ad->arcname, hwnd);
145        }
146      }
147      break;
148
149    case ARCERR_TEST:
150      ad = WinQueryWindowPtr(hwnd, QWL_USER);
151      runemf2(SEPARATEKEEP | WINDOWED | MAXIMIZED,
152              hwnd, NULL, NULL, "%s %s%s%s", ad->info->test,
153              needs_quoting(ad->arcname) ? "\"" : NullStr,
154              ad->arcname,
155              needs_quoting(ad->arcname) ? "\"" : NullStr);
156      break;
157    }
158    return 0;
159  }
160  return WinDefDlgProc(hwnd, msg, mp1, mp2);
161}
162
163static SHORT APIENTRY ArcSort(PMINIRECORDCORE pmrc1, PMINIRECORDCORE pmrc2,
164                              PVOID pStorage)
165{
166  PARCITEM pai1 = (PARCITEM) pmrc1;
167  PARCITEM pai2 = (PARCITEM) pmrc2;
168  DIRCNRDATA *pdcd = (DIRCNRDATA *) pStorage;
169  SHORT ret = 0;
170  CHAR *pext, *ppext;
171  INT sortFlags;
172
173  if (!pdcd) {
174    HWND hwndCnr = pai1->hwndCnr;
175
176    pdcd = WinQueryWindowPtr(hwndCnr, QWL_USER);
177    if (!pdcd) {
178      Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
179      return ret;
180    }
181  }
182
183  sortFlags = pdcd->sortFlags;          // Optimize
184
185  if (sortFlags) {
186    switch (sortFlags & (~SORT_REVERSE)) {
187    case SORT_FIRSTEXTENSION:
188      pext = strchr(pai1->szFileName, '.');
189      ppext = strchr(pai2->szFileName, '.');
190      if (!pext)
191        pext = NullStr;
192      if (!ppext)
193        ppext = NullStr;
194      ret = stricmp(pext, ppext);
195      break;
196
197    case SORT_LASTEXTENSION:
198      pext = strrchr(pai1->szFileName, '.');
199      ppext = strrchr(pai2->szFileName, '.');
200      if (!pext)
201        pext = NullStr;
202      if (!ppext)
203        ppext = NullStr;
204      ret = stricmp(pext, ppext);
205      break;
206
207    case SORT_LWDATE:
208      ret = (pai1->date.year < pai2->date.year) ? 1 :
209        (pai1->date.year > pai2->date.year) ? -1 :
210        (pai1->date.month < pai2->date.month) ? 1 :
211        (pai1->date.month > pai2->date.month) ? -1 :
212        (pai1->date.day < pai2->date.day) ? 1 :
213        (pai1->date.day > pai2->date.day) ? -1 :
214        (pai1->time.hours < pai2->time.hours) ? 1 :
215        (pai1->time.hours > pai2->time.hours) ? -1 :
216        (pai1->time.minutes < pai2->time.minutes) ? 1 :
217        (pai1->time.minutes > pai2->time.minutes) ? -1 :
218        (pai1->time.seconds < pai2->time.seconds) ? 1 :
219        (pai1->time.seconds > pai2->time.seconds) ? -1 : 0;
220      break;
221
222    case SORT_SIZE:
223      ret =
224        (pai1->cbFile < pai2->cbFile) ? 1 : (pai1->cbFile ==
225                                             pai2->cbFile) ? 0 : -1;
226      if (!ret)
227        ret =
228          (pai1->cbComp < pai2->cbComp) ? 1 : (pai1->cbComp ==
229                                               pai2->cbComp) ? 0 : -1;
230      break;
231
232    case SORT_EASIZE:
233      ret =
234        (pai1->cbComp < pai2->cbComp) ? 1 : (pai1->cbComp ==
235                                             pai2->cbComp) ? 0 : -1;
236      if (!ret)
237        ret =
238          (pai1->cbFile < pai2->cbFile) ? 1 : (pai1->cbFile ==
239                                               pai2->cbFile) ? 0 : -1;
240      break;
241    }
242    if (!ret)
243      ret = (SHORT) stricmp(pai1->szFileName, pai2->szFileName);
244    if (ret && (sortFlags & SORT_REVERSE))
245      ret = ret > 0 ? -1 : 1;
246    return ret;
247  }
248  return (SHORT) stricmp(pai1->szFileName, pai2->szFileName);
249}
250
251static INT APIENTRY ArcFilter(PMINIRECORDCORE rmini, PVOID arg)
252{
253  DIRCNRDATA *dcd = (DIRCNRDATA *) arg;
254  PARCITEM r;
255  register INT x;
256  INT ret = FALSE;
257
258  if (dcd && *dcd->mask.szMask) {
259    r = (PARCITEM) rmini;
260    if (dcd->mask.pszMasks[1]) {
261      for (x = 0; dcd->mask.pszMasks[x]; x++) {
262        if (*dcd->mask.pszMasks[x]) {
263          if (*dcd->mask.pszMasks[x] != '/') {
264            if (wildcard(r->szFileName, dcd->mask.pszMasks[x], FALSE))
265              ret = TRUE;
266          }
267          else {
268            if (wildcard(r->szFileName, dcd->mask.pszMasks[x] + 1, FALSE)) {
269              ret = FALSE;
270              break;
271            }
272          }
273        }
274      }
275    }
276    else {
277      if (wildcard(r->szFileName, dcd->mask.szMask, FALSE))
278        ret = TRUE;
279    }
280  }
281  else
282    ret = TRUE;
283  return ret;
284}
285
286static MRESULT EXPENTRY ArcFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
287                                        MPARAM mp2)
288{
289  return CommonFrameWndProc(ARC_CNR, hwnd, msg, mp1, mp2);
290}
291
292static BOOL IsArcThere(HWND hwnd, CHAR * arcname)
293{
294  if (arcname) {
295    if (IsFile(arcname) != 1) {
296      saymsg(MB_CANCEL, hwnd,
297             GetPString(IDS_SAYWHATTEXT),
298             GetPString(IDS_ARCNOTTHERETEXT), arcname);
299      return FALSE;
300    }
301    return TRUE;
302  }
303  return FALSE;
304}
305
306//== FillArcCnr() generate archive content list and fill container window ==
307
308static INT FillArcCnr(HWND hwndCnr, CHAR * arcname, ARC_TYPE ** arcinfo,
309                      ULONGLONG * pullTotalBytes, volatile PCHAR pStopFlag)
310{
311  FILE *fp;
312  HFILE oldstdout;
313  HFILE newstdout;
314  CHAR s[CCHMAXPATH * 2], lonename[CCHMAXPATH + 2],
315    *nsize, *osize, *fdate, *fname, *p, *pp, arctemp[33];
316  BOOL gotstart;
317  BOOL gotend;
318  BOOL wasquote;
319  BOOL nomove = FALSE;          // fixme to be gone?
320  INT highest = 0, x, counter = 0, numarcfiles = 0;
321  PARCITEM lastpai;
322  ARC_TYPE *info;
323  ARC_TYPE *tinfo;
324  ULONG apptype;
325  APIRET rc;
326
327  if (!arcname || !arcinfo)
328    return 0;
329
330  info = *arcinfo;
331  if (!info)
332    info = find_type(arcname, NULL);
333  for (x = 0; x < 99; x++) {
334    sprintf(arctemp, "%s.%03x", ArcTempRoot, (clock() & 4095L));
335    if (IsFile(arctemp) == 1)
336      DosSleep(rand() % 100);
337    else
338      break;
339  }
340
341ReTry:
342
343#ifdef DEBUG
344  if (info && info->id)
345    WinSetWindowText(WinQueryWindow
346                     (WinQueryWindow(hwndCnr, QW_PARENT), QW_PARENT),
347                     info->id);
348#endif
349
350  tinfo = NULL;
351  numarcfiles = counter = highest = 0;
352  gotstart = gotend = FALSE;
353  lastpai = NULL;
354  *pullTotalBytes = 0;
355  if (!info || !info->list)
356    Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
357  else {
358    WinSendMsg(hwndCnr,
359               CM_REMOVERECORD,
360               MPVOID,
361               MPFROM2SHORT(0, CMA_FREE | CMA_INVALIDATE | CMA_ERASE));
362    *arcinfo = info;
363    highest = info->osizepos;
364    if (info->nsizepos > highest)
365      highest = info->nsizepos;
366    if (info->fdpos > highest)
367      highest = info->fdpos;
368    if (info->fnpos > highest)
369      highest = info->fnpos;
370    if (highest > 50) {
371      saymsg(MB_ENTER | MB_ICONEXCLAMATION, HWND_DESKTOP,
372             GetPString(IDS_SHAMETEXT), "%s", GetPString(IDS_BUNGEDUPTEXT));
373    }
374    if (info->fnpos == -1)
375      highest = 32767;
376
377    DosError(FERR_DISABLEHARDERR);
378    DosForceDelete(arctemp);
379    DosError(FERR_DISABLEHARDERR);
380
381    strcpy(s, info->list);
382    p = strchr(s, ' ');
383    if (p)
384      *p = 0;
385    DosError(FERR_DISABLEHARDERR);
386    if (!DosQAppType(s, &apptype) &&
387        (apptype & FAPPTYP_DOS ||
388         apptype & FAPPTYP_WINDOWSREAL ||
389         apptype & FAPPTYP_WINDOWSPROT ||
390         apptype & FAPPTYP_WINDOWSPROT31)) {
391      p = GetCmdSpec(TRUE);
392      runemf2(SEPARATE | INVISIBLE | MINIMIZED | BACKGROUND | WAIT,
393              hwndCnr,
394              NULL,
395              "DOS_BACKGROUND_EXECUTION=1",
396              "%s /C %s %s%s%s > %s",
397              p,
398              info->list,
399              needs_quoting(arcname) ? "\"" : NullStr,
400              arcname,
401              needs_quoting(arcname) ? "\"" : NullStr,
402              arctemp);
403    }
404    else {
405      fp = xfopen(arctemp, "w", pszSrcFile, __LINE__);
406      if (!fp)
407        return 0;
408      else {
409        newstdout = -1;
410        DosError(FERR_DISABLEHARDERR);
411        rc = DosDupHandle(fileno(stdout), &newstdout);
412        if (rc) {
413          Dos_Error(MB_CANCEL, rc, hwndCnr, pszSrcFile, __LINE__,
414                    "DosDupHandle");
415          return 0;
416        }
417        else {
418          oldstdout = fileno(stdout);
419          DosError(FERR_DISABLEHARDERR);
420          rc = DosDupHandle(fileno(fp), &oldstdout);
421          if (rc) {
422            Dos_Error(MB_CANCEL, rc, hwndCnr, pszSrcFile, __LINE__,
423                      "DosDupHandle");
424            return 0;
425          }
426          else {
427            runemf2(SEPARATE | INVISIBLE | FULLSCREEN | BACKGROUND | WAIT,
428                    hwndCnr, NULL, NULL, "%s %s%s%s", info->list,
429                    needs_quoting(arcname) ? "\"" : NullStr,
430                    arcname,
431                    needs_quoting(arcname) ? "\"" : NullStr);
432            oldstdout = fileno(stdout);
433            DosError(FERR_DISABLEHARDERR);
434            DosDupHandle(newstdout, &oldstdout);
435            DosClose(newstdout);
436            fclose(fp);
437          }
438        }
439      }
440    }
441
442    DosError(FERR_DISABLEHARDERR);
443    fp = _fsopen(arctemp, "r", SH_DENYWR);
444
445    if (fp) {
446      gotstart = !info->startlist || !*info->startlist; // If list has no start marker
447
448      while (!feof(fp) && !gotend && !*pStopFlag) {
449        if (!xfgets_bstripcr(s, sizeof(s), fp, pszSrcFile, __LINE__))
450          break;
451        if (!gotstart) {
452          if (!strcmp(s, info->startlist))
453            gotstart = TRUE;
454        }
455        else if (info->endlist && !strcmp(s, info->endlist))
456          gotend = TRUE;
457        else {
458          /* add to container */
459          fname = NULL;
460          bstrip(s);
461          if (info->nameisfirst) {
462            strncpy(lonename, s, CCHMAXPATH + 2);
463            lonename[CCHMAXPATH + 1] = 0;
464            fname = lonename;
465            if (!xfgets_bstripcr(s, sizeof(s), fp, pszSrcFile, __LINE__))
466              break;
467            if (*fname == '\"') {
468              memmove(fname, fname + 1, strlen(fname) + 1);
469              p = strchr(fname, '\"');
470              if (p)
471                *p = 0;
472            }
473          }
474          nsize = NULL;
475          osize = fdate = NullStr;
476          p = s;
477          for (x = 0; x <= highest; x++) {
478            pp = p;
479            while (*pp && (*pp == ' ' || *pp == '\t'))  /* skip leading */
480              pp++;
481            if (!*pp)
482              break;
483            wasquote = FALSE;
484            p = pp;
485            while (*p && (wasquote ||
486                          ((x != info->fnpos || !info->nameislast) ?
487                           (*p != ' ' && *p != '\t') : TRUE))) {
488              if (*p == '\"') {
489                if (!wasquote) {
490                  wasquote = TRUE;
491                  memmove(p, p + 1, strlen(p));
492                  while (*p == ' ' || *p == '\t')
493                    p++;
494                }
495                else {
496                  memmove(p, p + 1, strlen(p));
497                  break;
498                }
499              }
500              else if (*p)
501                p++;
502            }
503            if (*p) {
504              *p = 0;
505              p++;
506            }
507            if (x == info->nsizepos)
508              nsize = pp;
509            else if (x == info->osizepos)
510              osize = pp;
511            else if (x == info->fdpos) {
512              fdate = pp;
513              if (info->fdflds > 1 && info->fdflds < 24) {
514                INT y;
515
516                if (*p) {
517                  p--;
518                  *p = ' ';
519                  for (y = 0; y < info->fdflds - 1; y++) {
520                    while (*p && (*p == ' ' || *p == '\t'))
521                      p++;
522                    while (*p && (*p != ' ' && *p != '\t'))
523                      p++;
524                    x++;
525                  }
526                  if (*p) {
527                    *p = 0;
528                    p++;
529                  }
530                }
531              }
532            }
533            else if (x == info->fnpos) {
534              fname = pp;
535              if (pp && *pp == '*' && !*(pp + 1))       /* workaround for LH.EXE */
536                fname = NULL;
537              if (info->nameislast)
538                break;
539            }
540            else if ((!p || !*p) && info->fnpos == -1) {
541              fname = pp;
542              break;
543            }
544          }
545          if (info->nameisnext) {
546            if (!xfgets_bstripcr
547                (lonename, sizeof(lonename), fp, pszSrcFile, __LINE__))
548              break;
549            fname = lonename;
550          }
551          // fixme to complain?
552          if (fname && *fname) {
553
554            RECORDINSERT ri;
555            PARCITEM pai;
556
557#ifdef DEBUG
558            saymsg(MB_ENTER, hwndCnr, DEBUG_STRING,
559                   "fname: %s\r\rpp: %s\r\rp: %s\r\rlonename: %s\r\rhighest: %ld\r\rx: %ld\r\rfdate: %s",
560                   fname ? fname : "NULL",
561                   pp ? pp : "NULL",
562                   p ? p : "NULL",
563                   lonename, highest, x, (fdate) ? fdate : "NULL");
564#endif
565
566            pai = WinSendMsg(hwndCnr,
567                             CM_ALLOCRECORD,
568                             MPFROMLONG(EXTRA_ARCRECORD_BYTES),
569                             MPFROMLONG(1L));
570            if (!pai) {
571              Runtime_Error(pszSrcFile, __LINE__, "CM_ALLOCRECORD");
572              break;
573            }
574            else {
575              memset(pai, 0, sizeof(ARCITEM));
576              pai->hwndCnr = hwndCnr;
577              if (*fname == '*') {
578                fname++;
579                pai->flags = ARCFLAGS_REALDIR;
580              }
581              if (fname[strlen(fname) - 1] == '\\' ||
582                  fname[strlen(fname) - 1] == '/')
583                pai->flags = ARCFLAGS_REALDIR;
584              strcpy(pai->szFileName, fname);
585              if (fdate)
586                strcpy(pai->szDate, fdate);
587              pai->pszFileName = pai->szFileName;
588              pai->rc.pszIcon = pai->pszFileName;
589              pai->rc.hptrIcon = (pai->flags & ARCFLAGS_REALDIR) != 0 ?
590                hptrDir : hptrFile;
591              pai->pszDate = pai->szDate;
592              if (osize)
593                pai->cbFile = atol(osize);
594              if (nsize)
595                pai->cbComp = atol(nsize);
596              if (info->datetype && fdate && *fdate)
597                ArcDateTime(fdate, info->datetype, &pai->date, &pai->time);
598              memset(&ri, 0, sizeof(RECORDINSERT));
599              ri.cb = sizeof(RECORDINSERT);
600              ri.pRecordOrder = (PRECORDCORE) CMA_END;
601              ri.pRecordParent = (PRECORDCORE) NULL;
602              ri.zOrder = (USHORT) CMA_TOP;
603              ri.cRecordsInsert = 1L;
604              ri.fInvalidateRecord = FALSE;
605              if (WinSendMsg(hwndCnr,
606                             CM_INSERTRECORD, MPFROMP(pai), MPFROMP(&ri))) {
607                *pullTotalBytes += pai->cbFile;
608              }
609              numarcfiles++;
610              if (!(++counter % 50)) {
611                if (!lastpai)
612                  lastpai = pai;
613                WinSendMsg(hwndCnr,
614                           CM_INVALIDATERECORD,
615                           lastpai,
616                           MPFROM2SHORT(10, CMA_ERASE | CMA_REPOSITION));
617                lastpai = pai;
618              }
619              // Avoid hogging system for large archive
620              if (numarcfiles == 100)
621                priority_idle();
622            }
623          }
624        }
625      }                                 // while !eof
626
627      fclose(fp);
628
629      if (*pStopFlag)
630        numarcfiles = 0;                // Request close
631      else if (!numarcfiles || !gotstart
632               || (!gotend && info->endlist && *info->endlist)) {
633        // Oops
634        ARCDUMP ad;
635        CHAR errstr[CCHMAXPATH + 256];
636
637        // Try for alternate archiver
638        tinfo = info;
639        do {
640          tinfo = tinfo->next;
641          if (tinfo)
642            tinfo = find_type(arcname, tinfo);
643          if (tinfo) {
644            DosError(FERR_DISABLEHARDERR);
645            DosForceDelete(arctemp);
646            info = tinfo;
647            goto ReTry;
648          }
649        } while (tinfo);
650        DosBeep(750, 50);               // wake up user
651        sprintf(errstr, GetPString(IDS_ARCERRORINFOTEXT),
652                arcname,
653                !gotstart ? GetPString(IDS_NOGOTSTARTTEXT) : NullStr,
654                !numarcfiles ? GetPString(IDS_NOARCFILESFOUNDTEXT) :
655                NullStr,
656                !gotend ? GetPString(IDS_NOENDOFLISTTEXT) : NullStr);
657        memset(&ad, 0, sizeof(ARCDUMP));
658        ad.info = info;
659        strcpy(ad.listname, arctemp);
660        strcpy(ad.arcname, arcname);
661        ad.errmsg = errstr;
662        WinDlgBox(HWND_DESKTOP,
663                  hwndCnr,
664                  ArcErrProc, FM3ModHandle, ARCERR_FRAME, MPFROMP(&ad));
665      }
666      else if (!nomove && tinfo) {
667        /* if we got a false hit, move working hit to top */
668        tinfo = info->next;
669        info->next = arcsighead;
670        arcsighead->prev = info;
671        if (tinfo)
672          tinfo->next->prev = info->prev;
673        info->prev->next = tinfo;
674        info->prev = NULL;
675        arcsighead = info;
676        rewrite_archiverbb2(NULL);      // Rewrite with warning
677      }
678    }                                   // if opened
679
680    DosError(FERR_DISABLEHARDERR);
681    DosForceDelete(arctemp);
682  }
683
684  if (numarcfiles)
685    priority_normal();
686
687  return numarcfiles;
688}
689
690MRESULT EXPENTRY ArcTextProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
691{
692  static BOOL emphasized = FALSE;
693  static HWND hwndButtonPopup = (HWND) 0;
694  static ULONG timestamp = ULONG_MAX;
695  static USHORT lastid = 0;
696
697  switch (msg) {
698  case WM_CREATE:
699    return CommonTextProc(hwnd, msg, mp1, mp2);
700
701  case WM_COMMAND:
702    return WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
703                                      ARC_CNR), msg, mp1, mp2);
704
705  case UM_CONTEXTMENU:
706  case WM_CONTEXTMENU:
707    {
708      USHORT id;
709
710      id = WinQueryWindowUShort(hwnd, QWS_ID);
711      switch (id) {
712      case DIR_SELECTED:
713      case DIR_VIEW:
714      case DIR_SORT:
715        {
716          POINTL ptl = { 0, 0 };
717          SWP swp;
718          DIRCNRDATA *dcd;
719
720          if (hwndButtonPopup)
721            WinDestroyWindow(hwndButtonPopup);
722          if (id == DIR_SELECTED)
723            id = DIR_RESTORE;
724          if (id == lastid) {
725
726            ULONG check;
727
728            DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &check,
729                            sizeof(check));
730            if (check < timestamp + 500) {
731              lastid = 0;
732              goto MenuAbort;
733            }
734          }
735          hwndButtonPopup = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
736          if (hwndButtonPopup) {
737            WinSetWindowUShort(hwndButtonPopup, QWS_ID, id);
738            dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
739                                                                   QW_PARENT),
740                                                    ARC_CNR), QWL_USER);
741            if (id == DIR_SORT) {
742              if (dcd)
743                SetSortChecks(hwndButtonPopup, dcd->sortFlags);
744              WinSendMsg(hwndButtonPopup,
745                         MM_DELETEITEM,
746                         MPFROM2SHORT(IDM_SORTNONE, FALSE), MPVOID);
747              WinSendMsg(hwndButtonPopup,
748                         MM_DELETEITEM,
749                         MPFROM2SHORT(IDM_SORTNAME, FALSE), MPVOID);
750              WinSendMsg(hwndButtonPopup,
751                         MM_DELETEITEM,
752                         MPFROM2SHORT(IDM_SORTLADATE, FALSE), MPVOID);
753              WinSendMsg(hwndButtonPopup,
754                         MM_DELETEITEM,
755                         MPFROM2SHORT(IDM_SORTCRDATE, FALSE), MPVOID);
756              WinSendMsg(hwndButtonPopup,
757                         MM_DELETEITEM,
758                         MPFROM2SHORT(IDM_SORTDIRSFIRST, FALSE), MPVOID);
759              WinSendMsg(hwndButtonPopup,
760                         MM_DELETEITEM,
761                         MPFROM2SHORT(IDM_SORTDIRSLAST, FALSE), MPVOID);
762              WinSendMsg(hwndButtonPopup,
763                         MM_DELETEITEM,
764                         MPFROM2SHORT(IDM_SORTSUBJECT, FALSE), MPVOID);
765              WinSendMsg(hwndButtonPopup,
766                         MM_SETITEMTEXT,
767                         MPFROM2SHORT(IDM_SORTEASIZE, 0),
768                         MPFROMP(GetPString(IDS_COMPRESSEDSIZEMENUTEXT)));
769              WinSendMsg(hwndButtonPopup,
770                         MM_SETITEMTEXT,
771                         MPFROM2SHORT(IDM_SORTLWDATE, 0),
772                         MPFROMP(GetPString(IDS_DATEMENUTEXT)));
773            }
774            ptl.x = 0;
775            if (WinPopupMenu(HWND_OBJECT,
776                             HWND_OBJECT,
777                             hwndButtonPopup, -32767, -32767, 0, 0)) {
778              WinQueryWindowPos(hwndButtonPopup, &swp);
779              ptl.y = -(swp.cy + 2);
780            }
781            else {
782              WinQueryWindowPos(hwnd, &swp);
783              ptl.y = swp.cy + 2;
784            }
785            if (WinPopupMenu(hwnd,
786                             hwnd,
787                             hwndButtonPopup,
788                             ptl.x,
789                             ptl.y,
790                             0,
791                             PU_HCONSTRAIN | PU_VCONSTRAIN |
792                             PU_KEYBOARD | PU_MOUSEBUTTON1)) {
793              CenterOverWindow(hwndButtonPopup);
794              PaintRecessedWindow(hwnd, (HPS) 0, FALSE, FALSE);
795            }
796          }
797        }
798        break;
799      default:
800        PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
801                                ARC_CNR),
802                WM_CONTROL, MPFROM2SHORT(ARC_CNR, CN_CONTEXTMENU), MPVOID);
803        break;
804      }
805    }
806  MenuAbort:
807    if (msg == UM_CONTEXTMENU)
808      return 0;
809    break;
810
811  case WM_MENUEND:
812    if (hwndButtonPopup == (HWND) mp2) {
813      lastid = WinQueryWindowUShort((HWND) mp2, QWS_ID);
814      WinDestroyWindow(hwndButtonPopup);
815      hwndButtonPopup = (HWND) 0;
816      DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &timestamp,
817                      sizeof(timestamp));
818      switch (lastid) {
819      case DIR_VIEW:
820      case DIR_SORT:
821      case DIR_RESTORE:
822      case DIR_SELECTED:
823        PaintRecessedWindow(hwnd, (HPS) 0, TRUE, FALSE);
824        break;
825      }
826    }
827    break;
828
829  case WM_MOUSEMOVE:
830    {
831      USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
832      char *s = NULL;
833
834      if (fOtherHelp) {
835        if ((!hwndBubble ||
836             WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
837            !WinQueryCapture(HWND_DESKTOP)) {
838          switch (id) {
839          case DIR_TOTALS:
840            s = GetPString(IDS_ARCCNRTOTALSHELPTEXT);
841            break;
842          case DIR_SELECTED:
843            s = GetPString(IDS_ARCCNRSELECTEDHELPTEXT);
844            break;
845          case DIR_VIEW:
846            s = GetPString(IDS_ARCCNRVIEWHELPTEXT);
847            break;
848          case DIR_SORT:
849            s = GetPString(IDS_DIRCNRSORTHELP);
850            break;
851          case DIR_FILTER:
852            s = GetPString(IDS_DIRCNRFILTERHELP);
853            break;
854          case DIR_FOLDERICON:
855            s = GetPString(IDS_ARCCNRFOLDERHELPTEXT);
856            break;
857          default:
858            break;
859          }
860          if (s)
861            MakeBubble(hwnd, TRUE, s);
862          else if (hwndBubble)
863            WinDestroyWindow(hwndBubble);
864        }
865      }
866      switch (id) {
867      case DIR_FILTER:
868      case DIR_SORT:
869      case DIR_VIEW:
870      case DIR_SELECTED:
871      case DIR_FOLDERICON:
872        return CommonTextButton(hwnd, msg, mp1, mp2);
873      }
874    }
875    break;
876
877  case WM_BUTTON3UP:
878  case WM_BUTTON1UP:
879  case WM_BUTTON1DOWN:
880  case WM_BUTTON3DOWN:
881    {
882      USHORT id;
883
884      id = WinQueryWindowUShort(hwnd, QWS_ID);
885      switch (id) {
886      case DIR_FILTER:
887      case DIR_SORT:
888      case DIR_VIEW:
889      case DIR_SELECTED:
890      case DIR_FOLDERICON:
891        return CommonTextButton(hwnd, msg, mp1, mp2);
892      }
893    }
894    break;
895
896  case UM_CLICKED:
897  case UM_CLICKED3:
898    {
899      USHORT id, cmd = 0;
900
901      id = WinQueryWindowUShort(hwnd, QWS_ID);
902      switch (id) {
903      case DIR_FOLDERICON:
904        switch (msg) {
905        case WM_BUTTON3CLICK:
906        case WM_CHORD:
907          cmd = IDM_RESCAN;
908          break;
909        default:
910          if ((SHORT2FROMMP(mp2) & KC_ALT) != 0)
911            cmd = IDM_WINDOWDLG;
912          else
913            cmd = IDM_WALKDIR;
914          break;
915        }
916        break;
917      case DIR_VIEW:
918      case DIR_SORT:
919      case DIR_SELECTED:
920        PostMsg(hwnd, UM_CONTEXTMENU, MPVOID, MPVOID);
921        break;
922      case DIR_FILTER:
923        cmd = IDM_FILTER;
924        break;
925      default:
926        break;
927      }
928      if (cmd)
929        PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
930                                ARC_CNR),
931                WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
932    }
933    return 0;
934
935  case WM_BEGINDRAG:
936  case DM_DROP:
937  case DM_DRAGOVER:
938  case DM_DRAGLEAVE:
939  case DM_DROPHELP:
940    if (msg == DM_DRAGOVER) {
941      if (!emphasized) {
942        emphasized = TRUE;
943        DrawTargetEmphasis(hwnd, emphasized);
944      }
945    }
946    else if (msg != WM_BEGINDRAG) {
947      if (emphasized) {
948        emphasized = FALSE;
949        DrawTargetEmphasis(hwnd, emphasized);
950      }
951    }
952    switch (WinQueryWindowUShort(hwnd, QWS_ID)) {
953    case DIR_FOLDERICON:
954      switch (msg) {
955      case DM_DRAGOVER:
956        if (AcceptOneDrop(hwnd, mp1, mp2))
957          return MRFROM2SHORT(DOR_DROP, DO_MOVE);
958        return MRFROM2SHORT(DOR_NODROP, 0);     /* Drop not valid */
959      case DM_DROPHELP:
960        DropHelp(mp1, mp2, hwnd, GetPString(IDS_ARCCNRFOLDERDROPHELPTEXT));
961        return 0;
962      case DM_DROP:
963        {
964          char szFrom[CCHMAXPATH + 2];
965
966          if (emphasized) {
967            emphasized = FALSE;
968            DrawTargetEmphasis(hwnd, emphasized);
969          }
970          if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom)))
971            WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
972                                       ARC_CNR),
973                       WM_COMMAND,
974                       MPFROM2SHORT(IDM_SWITCH, 0), MPFROMP(szFrom));
975        }
976        return 0;
977      default:
978        return PFNWPStatic(hwnd, msg, mp1, mp2);
979      }
980    default:
981      {
982        CNRDRAGINFO cnd;
983        USHORT dcmd;
984
985        switch (msg) {
986        case DM_DROP:
987          dcmd = CN_DROP;
988          break;
989        case DM_DRAGOVER:
990          dcmd = CN_DRAGOVER;
991          break;
992        case DM_DRAGLEAVE:
993          dcmd = CN_DRAGLEAVE;
994          break;
995        case DM_DROPHELP:
996          dcmd = CN_DROPHELP;
997          break;
998        case WM_BEGINDRAG:
999          dcmd = CN_INITDRAG;
1000          break;
1001        }
1002        cnd.pDragInfo = (PDRAGINFO) mp1;
1003        cnd.pRecord = NULL;
1004        return WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
1005                          WM_CONTROL,
1006                          MPFROM2SHORT(ARC_CNR, dcmd), MPFROMP(&cnd));
1007      }
1008    }
1009  }
1010  return PFNWPStatic(hwnd, msg, mp1, mp2);
1011}
1012
1013MRESULT EXPENTRY ArcClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
1014                                  MPARAM mp2)
1015{
1016
1017  switch (msg) {
1018  case UM_CONTAINERHWND:
1019    return MRFROMLONG(WinWindowFromID(hwnd, ARC_CNR));
1020
1021  case UM_VIEWSMENU:
1022    // fixme to disble menu items as needed
1023    return MRFROMLONG(CheckMenu(&ArcCnrMenu, ARCCNR_POPUP));
1024
1025  case UM_FILESMENU:
1026    // fixme to disble menu items as needed
1027    return MRFROMLONG(CheckMenu(&ArcMenu, ARC_POPUP));
1028
1029  case MM_PORTHOLEINIT:
1030  case WM_INITMENU:
1031  case UM_INITMENU:
1032  case UM_COMMAND:
1033  case UM_LOADFILE:
1034  case UM_UPDATERECORD:
1035  case UM_UPDATERECORDLIST:
1036  case WM_COMMAND:
1037  case WM_CONTROL:
1038  case WM_CLOSE:
1039    return WinSendMsg(WinWindowFromID(hwnd, ARC_CNR), msg, mp1, mp2);
1040
1041  case WM_PSETFOCUS:
1042  case WM_SETFOCUS:
1043    if (mp2)
1044      PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
1045    break;
1046
1047  case UM_FOCUSME:
1048    WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, ARC_CNR));
1049    break;
1050
1051  case WM_PAINT:
1052    {
1053      HPS hps;
1054      RECTL rcl;
1055
1056      hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
1057      if (hps) {
1058        WinQueryWindowRect(hwnd, &rcl);
1059        WinFillRect(hps, &rcl, CLR_PALEGRAY);
1060        CommonTextPaint(hwnd, hps);
1061        WinEndPaint(hps);
1062      }
1063    }
1064    break;
1065
1066  case UM_SIZE:
1067  case WM_SIZE:
1068    if (msg == UM_SIZE) {
1069
1070      SWP swp;
1071
1072      WinQueryWindowPos(hwnd, &swp);
1073      mp1 = MPFROM2SHORT(swp.cx, swp.cy);
1074      mp2 = MPFROM2SHORT(swp.cx, swp.cy);
1075    }
1076    {
1077      USHORT cx, cy, bx;
1078
1079      cx = SHORT1FROMMP(mp2);
1080      cy = SHORT2FROMMP(mp2);
1081      WinSetWindowPos(WinWindowFromID(hwnd, ARC_CNR), HWND_TOP,
1082                      0,
1083                      22, cx, cy - (24 + 22), SWP_SHOW | SWP_MOVE | SWP_SIZE);
1084      WinSetWindowPos(WinWindowFromID(hwnd, ARC_EXTRACTDIR), HWND_TOP,
1085                      0, 0, cx, 22, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1086      WinSetWindowPos(WinWindowFromID(hwnd, DIR_FOLDERICON), HWND_TOP,
1087                      2, cy - 22, 24, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1088      WinSetWindowPos(WinWindowFromID(hwnd, DIR_TOTALS), HWND_TOP,
1089                      29,
1090                      cy - 22,
1091                      (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1092      WinSetWindowPos(WinWindowFromID(hwnd, DIR_SELECTED), HWND_TOP,
1093                      29 + (cx / 3) + 2,
1094                      cy - 22,
1095                      (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1096      bx = (cx - (29 + (((cx / 3) + 2) * 2))) / 3;
1097      WinSetWindowPos(WinWindowFromID(hwnd, DIR_VIEW), HWND_TOP,
1098                      29 + (((cx / 3) + 2) * 2),
1099                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1100      WinSetWindowPos(WinWindowFromID(hwnd, DIR_SORT), HWND_TOP,
1101                      29 + (((cx / 3) + 2) * 2) + bx,
1102                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1103      WinSetWindowPos(WinWindowFromID(hwnd, DIR_FILTER), HWND_TOP,
1104                      29 + (((cx / 3) + 2) * 2) + (bx * 2),
1105                      cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
1106    }
1107    CommonTextPaint(hwnd, (HPS) 0);
1108    if (msg == UM_SIZE) {
1109      WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
1110                      SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE);
1111      return 0;
1112    }
1113    break;
1114  }
1115  return WinDefWindowProc(hwnd, msg, mp1, mp2);
1116}
1117
1118MRESULT EXPENTRY ArcObjWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1119{
1120  DIRCNRDATA *dcd;
1121  DIRCNRDATA *dcdsrc;
1122  PSZ psz;
1123
1124  switch (msg) {
1125  case DM_PRINTOBJECT:
1126  case DM_DISCARDOBJECT:
1127    dcd = INSTDATA(hwnd);
1128    if (dcd) {
1129
1130      LISTINFO *li;
1131      CNRDRAGINFO cni;
1132
1133      cni.pRecord = NULL;
1134      cni.pDragInfo = (PDRAGINFO) mp1;
1135      li = DoFileDrop(dcd->hwndCnr,
1136                      dcd->directory, FALSE, MPVOID, MPFROMP(&cni));
1137      dcdsrc = INSTDATA(cni.pDragInfo->hwndSource);
1138      if (dcdsrc->ulItemsToUnHilite) {
1139        saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
1140               hwnd,
1141               GetPString(IDS_ERRORTEXT),
1142               GetPString(IDS_EXCEEDPMDRGLMT));
1143      }
1144
1145      if (li) {
1146        li->type = (msg == DM_DISCARDOBJECT) ? IDM_DELETE : IDM_PRINT;
1147        if (!li->list ||
1148            !li->list[0] || !PostMsg(hwnd, UM_ACTION, MPFROMP(li), MPVOID))
1149          FreeListInfo(li);
1150        else
1151          return MRFROMLONG(DRR_SOURCE);
1152      }
1153    }
1154    return MRFROMLONG(DRR_TARGET);
1155
1156  case DM_RENDERPREPARE:
1157    return (MRESULT) TRUE;
1158
1159  case DM_RENDER:
1160    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1161    if (dcd && dcd->info && dcd->info->extract && dcd->arcname) {
1162
1163      PDRAGTRANSFER pdt = (PDRAGTRANSFER) mp1;
1164      CHAR filename[CCHMAXPATH];
1165      ULONG len;
1166
1167      if (pdt->hwndClient && pdt->pditem && pdt->hstrSelectedRMF &&
1168          pdt->hstrRenderToName) {
1169        if (pdt->usOperation == DO_COPY || pdt->usOperation == DO_MOVE) {
1170          *filename = 0;
1171          len = DrgQueryStrName(pdt->hstrSelectedRMF, CCHMAXPATH, filename);
1172          filename[len] = 0;
1173          if (!strnicmp(filename, "OS2FILE,", 8)) {
1174            // saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,"RMF = \"%s\"",filename);
1175          }
1176          else {
1177            *filename = 0;
1178            len =
1179              DrgQueryStrName(pdt->hstrRenderToName, CCHMAXPATH, filename);
1180            filename[len] = 0;
1181            if (len && *filename) {
1182              psz = xstrdup(filename, pszSrcFile, __LINE__);
1183              if (psz) {
1184                PostMsg(hwnd, UM_RENDER, MPFROMP(pdt), MPFROMP(psz));
1185                return (MRESULT) TRUE;
1186              }
1187            }
1188            else {
1189              // saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,"No render-to name given.");
1190            }
1191          }
1192        }
1193        pdt->fsReply = DMFL_RENDERRETRY;
1194      }
1195    }
1196    return (MRESULT) FALSE;
1197
1198  case UM_RENDER:
1199    {
1200      PDRAGTRANSFER pdt = (PDRAGTRANSFER) mp1;
1201      USHORT usRes = DMFL_RENDERFAIL;
1202
1203      dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1204      if (dcd && dcd->info && dcd->info->extract && dcd->arcname) {
1205
1206        CHAR *filename = (CHAR *) mp2, *p;
1207        ULONG len;
1208        CHAR membername[CCHMAXPATH], construct[CCHMAXPATH * 2];
1209
1210        *membername = 0;
1211        len = DrgQueryStrName(pdt->pditem->hstrSourceName,
1212                              CCHMAXPATH, membername);
1213        membername[len] = 0;
1214        if (*membername && len && filename) {
1215          unlinkf("%s", filename);
1216          strcpy(construct, filename);
1217          p = strrchr(filename, '\\');
1218          if (!p)
1219            *construct = 0;
1220          else {
1221            if (p == filename || *(p - 1) == ':')
1222              p++;
1223            *p = 0;
1224          }
1225          // saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,"%s %s %s\r[%s]",dcd->info->extract,dcd->arcname,membername,construct);
1226          runemf2(SEPARATE | WINDOWED | WAIT |
1227                    (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED) |
1228                    WAIT,
1229                  dcd->hwndClient, construct, NULL, "%s %s%s%s %s%s%s",
1230                  dcd->info->extract,
1231                  needs_quoting(dcd->arcname) ? "\"" : NullStr,
1232                  dcd->arcname,
1233                  needs_quoting(dcd->arcname) ? "\"" : NullStr,
1234                  needs_quoting(membername) ? "\"" : NullStr,
1235                  membername,
1236                  needs_quoting(membername) ? "\"" : NullStr);
1237          if (*construct && construct[strlen(construct) - 1] != '\\')
1238            strcat(construct, "\\");
1239          strcat(construct, membername);
1240          if (IsFile(construct) != -1) {
1241            rename(construct, filename);
1242            unlinkf("%s", construct);
1243            if (IsFile(filename) != -1)
1244              usRes = DMFL_RENDEROK;
1245          }
1246        }
1247      }
1248      if (mp2)
1249        free((CHAR *) mp2);
1250      PostMsg(pdt->hwndClient, DM_RENDERCOMPLETE, MPFROMP(pdt),
1251              MPFROM2SHORT(usRes, 0));
1252    }
1253    return 0;
1254
1255  case UM_SETUP:
1256    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1257    if (!dcd) {
1258      Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
1259      PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1260    }
1261    else {
1262      /* set unique id */
1263      WinSetWindowUShort(hwnd, QWS_ID, ARCOBJ_FRAME + (ARC_FRAME - dcd->id));
1264      dcd->hwndObject = hwnd;           // pass back hwnd
1265      if (ParentIsDesktop(hwnd, dcd->hwndParent))
1266        DosSleep(250);                  // Avoid race?
1267    }
1268    return 0;
1269
1270  case UM_RESCAN:
1271    /*
1272     * populate container
1273     */
1274    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1275    if (dcd) {
1276      if (mp1)
1277        strcpy(dcd->arcname, (CHAR *) mp1);     // Update name on request
1278      dcd->ullTotalBytes = dcd->totalfiles =
1279        dcd->selectedfiles = dcd->selectedbytes = 0;
1280      WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, "0");
1281      WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, "0 / 0k");
1282      dcd->totalfiles = FillArcCnr(dcd->hwndCnr,
1283                                   dcd->arcname,
1284                                   &dcd->info,
1285                                   &dcd->ullTotalBytes, &dcd->stopflag);
1286      if (!dcd->totalfiles)
1287        PostMsg(dcd->hwndCnr, WM_CLOSE, MPVOID, MPVOID);
1288      else {
1289        dcd->arcfilled = TRUE;
1290        if (!PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID))
1291          WinSendMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1292        PostMsg(dcd->hwndCnr, UM_SETUP2, MPVOID, MPVOID);
1293        WinSendMsg(dcd->hwndCnr,
1294                   CM_INVALIDATERECORD,
1295                   MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
1296      }
1297    }
1298    return 0;
1299
1300  case UM_SELECT:
1301    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1302    if (dcd) {
1303      switch (SHORT1FROMMP(mp1)) {
1304      case IDM_SELECTALL:
1305      case IDM_SELECTALLFILES:
1306        SelectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, TRUE);
1307        break;
1308      case IDM_DESELECTALL:
1309      case IDM_DESELECTALLFILES:
1310        DeselectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, TRUE);
1311        break;
1312      case IDM_DESELECTMASK:
1313      case IDM_SELECTMASK:
1314        {
1315          MASK mask;
1316          PARCITEM pci = (PARCITEM) mp2;
1317
1318          memset(&mask, 0, sizeof(MASK));
1319          mask.fNoAttribs = TRUE;
1320          mask.fNoDirs = TRUE;
1321          strcpy(mask.prompt,
1322                 GetPString((SHORT1FROMMP(mp1) == IDM_SELECTMASK) ?
1323                            IDS_SELECTFILTERTEXT : IDS_DESELECTFILTERTEXT));
1324          if (pci && (INT) pci != -1)
1325            strcpy(mask.szMask, pci->szFileName);
1326          if (WinDlgBox(HWND_DESKTOP, dcd->hwndCnr, PickMaskDlgProc,
1327                        FM3ModHandle, MSK_FRAME, MPFROMP(&mask))) {
1328            if (SHORT1FROMMP(mp1) == IDM_SELECTMASK)
1329              SelectAll(dcd->hwndCnr, TRUE, TRUE, mask.szMask, NULL, FALSE);
1330            else
1331              DeselectAll(dcd->hwndCnr, TRUE, TRUE, mask.szMask, NULL, FALSE);
1332          }
1333        }
1334
1335      case IDM_INVERT:
1336        InvertAll(dcd->hwndCnr);
1337        break;
1338      }
1339    }
1340    return 0;
1341
1342  case UM_ENTER:
1343    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1344    if (dcd) {
1345
1346      CHAR *s = (CHAR *) mp1, *p, *pp, filename[CCHMAXPATH];
1347
1348      if (s) {
1349        if (!dcd->info->extract) {
1350          Runtime_Error(pszSrcFile, __LINE__, "no extract");
1351          free(s);
1352          return 0;
1353        }
1354        runemf2(SEPARATE | WINDOWED |
1355                  (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED) |
1356                  WAIT,
1357                dcd->hwndClient, dcd->workdir, NULL, "%s %s%s%s %s%s%s",
1358                dcd->info->exwdirs ? dcd->info->exwdirs :
1359                                     dcd->info->extract,
1360                needs_quoting(dcd->arcname) ? "\"" : NullStr,
1361                dcd->arcname,
1362                needs_quoting(dcd->arcname) ? "\"" : NullStr,
1363                needs_quoting(s) ? "\"" : NullStr,
1364                s,
1365                needs_quoting(s) ? "\"" : NullStr);
1366
1367        // printf("%s %d runemf2 returned\n", __FILE__, __LINE__); fflush(stdout);      // 10 Mar 07 SHL
1368        if (!dcd->info->exwdirs) {
1369          p = s;
1370          p = strrchr(s, '\\');
1371          pp = strrchr(s, '/');
1372          if (p && pp)
1373            p = max(p, pp);
1374          else if (!p)
1375            p = pp;
1376          if (p)
1377            memmove(s, p + 1, strlen(p + 1));
1378        }
1379        sprintf(filename, "%s\\%s", dcd->workdir, s);
1380        p = filename;
1381        while (*p) {
1382          if (*p == '/')
1383            *p = '\\';
1384          p++;
1385        }
1386        // printf("%s %d UM_ENTER %s %s\n",__FILE__, __LINE__,filename, s); fflush(stdout);     // 10 Mar 07 SHL hang
1387        free(s);
1388        if (IsFile(filename) == 1) {
1389          if (fViewChild && fArcStuffVisible)
1390            DosSleep(100);              // Allow unzip session to finish closing 14 Mar 07 SHL
1391          WinSendMsg(dcd->hwndCnr, UM_ENTER, MPFROMP(filename), MPVOID);
1392        }
1393      }
1394    }
1395    return 0;
1396
1397  case UM_COMMAND:
1398    if (mp1) {
1399      if (PostMsg(hwnd, UM_ACTION, mp1, mp2))
1400        return (MRESULT) TRUE;
1401    }
1402    return 0;
1403
1404  case UM_ACTION:
1405    DosError(FERR_DISABLEHARDERR);
1406    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1407    if (dcd) {
1408
1409      LISTINFO *li = (LISTINFO *) mp1;
1410      register INT x;
1411
1412      if (li && li->list && li->list[0]) {
1413        switch (li->type) {
1414        case IDM_ARCHIVE:
1415        case IDM_ARCHIVEM:
1416          {
1417            DIRCNRDATA ad;
1418            CHAR szBuffer[1025], *p;
1419
1420            if (!li->list[1] && !stricmp(li->list[0], dcd->arcname)) {
1421              Runtime_Error(pszSrcFile, __LINE__, "arc to self");
1422              break;
1423            }
1424            ad = *dcd;
1425            ad.namecanchange = 0;
1426            ad.fmoving = (li->type == IDM_ARCHIVEM);
1427            if (!WinDlgBox(HWND_DESKTOP, dcd->hwndClient, ArchiveDlgProc, FM3ModHandle, ARCH_FRAME, (PVOID) & ad) || !*ad.arcname || !*ad.command)      /* we blew it */
1428              break;
1429            /* build the sucker */
1430            strcpy(szBuffer, ad.command);
1431            strcat(szBuffer, " ");
1432            if (needs_quoting(ad.arcname))
1433              strcat(szBuffer, "\"");
1434            strcat(szBuffer, ad.arcname);
1435            if (needs_quoting(ad.arcname))
1436              strcat(szBuffer, "\"");
1437            p = &szBuffer[strlen(szBuffer)];
1438            if (ad.mask.szMask) {
1439              strcat(szBuffer, " ");
1440              if (needs_quoting(ad.mask.szMask))
1441                strcat(szBuffer, "\"");
1442              strcat(szBuffer, ad.mask.szMask);
1443              if (needs_quoting(ad.mask.szMask))
1444                strcat(szBuffer, "\"");
1445            }
1446            strcat(szBuffer, " ");
1447            x = 0;
1448            while (li->list[x]) {
1449              if (needs_quoting(li->list[x]))
1450                strcat(szBuffer, "\"");
1451              strcat(szBuffer, li->list[x]);
1452              if (!IsFile(li->list[x])) {
1453                if (szBuffer[strlen(szBuffer) - 1] != '\\')
1454                  strcat(szBuffer, "\\");
1455                strcat(szBuffer, "*");
1456              }
1457              if (needs_quoting(li->list[x]))
1458                strcat(szBuffer, "\"");
1459              x++;
1460              if (!li->list[x] || strlen(szBuffer) +
1461                  strlen(li->list[x]) + 5 > 1024) {
1462                runemf2(SEPARATE | WINDOWED |
1463                          (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED) |
1464                          WAIT,
1465                        hwnd, NULL, NULL, "%s", szBuffer);
1466                *p = 0;
1467              }
1468              strcat(szBuffer, " ");
1469            }
1470            PostMsg(dcd->hwndCnr, UM_RESCAN, MPFROMSHORT(1), MPVOID);
1471            Broadcast(WinQueryAnchorBlock(hwnd),
1472                      hwndMain, UM_UPDATERECORD, MPFROMP(ad.arcname), MPVOID);
1473            Broadcast(WinQueryAnchorBlock(hwnd),
1474                      hwndMain,
1475                      UM_UPDATERECORDLIST, MPFROMP(li->list), MPVOID);
1476          }
1477          break;
1478
1479        case IDM_REFRESH:
1480        case IDM_DELETE:
1481          {
1482            CHAR cl[1001], *endofit;
1483            INT z;
1484            CHECKLIST ck;
1485            CHAR prompt[CCHMAXPATH + 257];
1486
1487            if (!dcd->info->delete)
1488              break;
1489            memset(&ck, 0, sizeof(ck));
1490            ck.size = sizeof(ck);
1491            ck.list = li->list;
1492            ck.cmd = li->type;
1493            ck.prompt = prompt;
1494            sprintf(prompt, GetPString(IDS_ARCCNRDELREFTEXT),
1495                    (li->type == IDM_DELETE) ?
1496                    GetPString(IDS_DELETELOWERTEXT) :
1497                    GetPString(IDS_REFRESHLOWERTEXT),
1498                    &"s"[li->list[1] == NULL],
1499                    dcd->arcname,
1500                    (li->type == IDM_DELETE) ?
1501                    GetPString(IDS_DELETELOWERTEXT) :
1502                    GetPString(IDS_REFRESHLOWERTEXT));
1503            if (!WinDlgBox(HWND_DESKTOP, hwnd, CheckListProc,
1504                           FM3ModHandle, CHECK_FRAME, MPFROMP(&ck)))
1505              break;
1506            li->list = ck.list;
1507            if (!li->list || !li->list[0])
1508              break;
1509            if (li->type == IDM_DELETE)
1510              sprintf(cl, "%s %s%s%s", dcd->info->delete,
1511                      (needs_quoting(dcd->arcname)) ? "\"" : NullStr,
1512                      dcd->arcname,
1513                      (needs_quoting(dcd->arcname)) ? "\"" : NullStr);
1514            else
1515              sprintf(cl, "%s %s%s%s", dcd->info->create,
1516                      (needs_quoting(dcd->arcname)) ? "\"" : NullStr,
1517                      dcd->arcname,
1518                      (needs_quoting(dcd->arcname)) ? "\"" : NullStr);
1519            endofit = &cl[strlen(cl)];
1520            z = 0;
1521            do {
1522              for (x = z; li->list[x] &&
1523                   strlen(cl) + strlen(li->list[x]) < 999; x++) {
1524                strcat(cl, " ");
1525                if (needs_quoting(li->list[x]))
1526                  strcat(cl, "\"");
1527                strcat(cl, li->list[x]);
1528                if (needs_quoting(li->list[x]))
1529                  strcat(cl, "\"");
1530              }
1531              z = x;
1532              runemf2(SEPARATE | WINDOWED |
1533                        (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED) |
1534                        WAIT,
1535                      hwnd, NullStr, NULL, "%s", cl);
1536              *endofit = 0;
1537            } while (li->list[x]);
1538            PostMsg(dcd->hwndCnr, UM_RESCAN, MPFROMSHORT(1), MPVOID);
1539            Broadcast(WinQueryAnchorBlock(hwnd),
1540                      hwndMain,
1541                      UM_UPDATERECORD, MPFROMP(dcd->arcname), MPVOID);
1542          }
1543          break;
1544
1545        case IDM_PRINT:
1546        case IDM_VIRUSSCAN:
1547        case IDM_VIEW:
1548        case IDM_MCIPLAY:
1549        case IDM_VIEWARCHIVE:
1550        case IDM_VIEWTEXT:
1551        case IDM_VIEWBINARY:
1552        case IDM_EDIT:
1553        case IDM_EDITTEXT:
1554        case IDM_EDITBINARY:
1555        case IDM_EXEC:
1556        case IDM_EXTRACTWDIRS:
1557        case IDM_EXTRACT:
1558          {
1559            CHAR cl[1001], *endofit, *ptr;
1560            INT z;
1561
1562            if ((li->type == IDM_EXTRACT && !li->info->extract) ||
1563                ((li->type == IDM_VIEW || li->type == IDM_VIEWTEXT ||
1564                  li->type == IDM_VIEWBINARY || li->type == IDM_EDIT ||
1565                  li->type == IDM_VIEWARCHIVE || li->type == IDM_EDITTEXT ||
1566                  li->type == IDM_EDITBINARY || li->type == IDM_MCIPLAY) &&
1567                 (!li->info->extract && !li->info->exwdirs)) ||
1568                (li->type != IDM_EXTRACT && li->type != IDM_EDIT &&
1569                 li->type != IDM_VIEW && li->type != IDM_VIEWTEXT &&
1570                 li->type != IDM_VIEWBINARY &&
1571                 li->type != IDM_VIEWARCHIVE &&
1572                 li->type != IDM_EDITTEXT &&
1573                 li->type != IDM_EDITBINARY &&
1574                 li->type != IDM_MCIPLAY && !li->info->exwdirs)) {
1575              Runtime_Error(pszSrcFile, __LINE__, "no cmd for request");
1576              break;
1577            }
1578            if (li->type == IDM_EXTRACT || li->type == IDM_EXTRACTWDIRS) {
1579
1580              CHAR fullname[CCHMAXPATH * 2];
1581              CHAR **exfiles = NULL;
1582              INT numfiles = 0, numalloc = 0;
1583
1584              for (x = 0; li->list[x]; x++) {
1585                sprintf(fullname, "%s%s%s",
1586                        li->targetpath,
1587                        (li->targetpath[strlen(li->targetpath) - 1] == '\\') ?
1588                        NullStr : "\\", li->list[x]);
1589                if (IsFile(fullname) != -1) {
1590                  AddToList(li->list[x], &exfiles, &numfiles, &numalloc);
1591                  li->list = RemoveFromList(li->list, li->list[x]);
1592                  if (!li->list)
1593                    break;
1594                  x--;
1595                }
1596              }
1597              if (exfiles && numfiles) {
1598
1599                CHECKLIST ckl;
1600                CHAR prompt[(CCHMAXPATH * 2) + 256];
1601
1602                memset(&ckl, 0, sizeof(ckl));
1603                ckl.size = sizeof(ckl);
1604                ckl.list = exfiles;
1605                ckl.prompt = prompt;
1606                ckl.cmd = li->type;
1607                sprintf(prompt,
1608                        GetPString(IDS_REPLACEWARNTEXT),
1609                        &"s"[numfiles == 1],
1610                        li->arcname, &"s"[numfiles != 1], li->targetpath);
1611                if (!WinDlgBox(HWND_DESKTOP, hwnd, CheckListProc,
1612                               FM3ModHandle, CHECK_FRAME, MPFROMP(&ckl))) {
1613                  if (ckl.list)
1614                    FreeList(ckl.list);
1615                  break;
1616                }
1617                else if (ckl.list)
1618                  li->list = CombineLists(li->list, ckl.list);
1619              }
1620            }
1621            if (!li->list || !li->list[0])
1622              break;
1623            sprintf(cl, "%s %s%s%s", (li->type == IDM_EXTRACT ||
1624                                      ((li->type == IDM_VIEW
1625                                        || li->type == IDM_VIEWTEXT
1626                                        || li->type == IDM_VIEWBINARY
1627                                        || li->type == IDM_VIEWARCHIVE
1628                                        || li->type == IDM_PRINT
1629                                        || li->type == IDM_EDIT
1630                                        || li->type == IDM_EDITTEXT
1631                                        || li->type == IDM_EDITBINARY
1632                                        && li->type == IDM_MCIPLAY)
1633                                       && !li->info->exwdirs)) ? li->info->
1634                    extract : li->info->exwdirs,
1635                    needs_quoting(li->arcname) ? "\"" : NullStr,
1636                    li->arcname,
1637                    needs_quoting(li->arcname) ? "\"" : NullStr);
1638            endofit = &cl[strlen(cl)];
1639            z = 0;
1640            do {
1641              for (x = z; li->list[x] &&
1642                   strlen(cl) + strlen(li->list[x]) < 999; x++) {
1643                strcat(cl, " ");
1644                if (needs_quoting(li->list[x]))
1645                  strcat(cl, "\"");
1646                strcat(cl, li->list[x]);
1647                if (needs_quoting(li->list[x]))
1648                  strcat(cl, "\"");
1649                ptr = li->list[x];
1650                while (*ptr) {
1651                  if (*ptr == '/')
1652                    *ptr = '\\';
1653                  ptr++;
1654                }
1655              }
1656              z = x;
1657              runemf2(SEPARATE | WINDOWED |
1658                        (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED) |
1659                        WAIT,
1660                      hwnd, li->targetpath, NULL, "%s", cl);
1661              *endofit = 0;
1662            } while (li->list[x]);
1663            if (li->type == IDM_EXTRACT || li->type == IDM_EXTRACTWDIRS) {
1664              /* update windows */
1665              for (x = 0; li->list[x]; x++) {
1666
1667                CHAR *temp, *p;
1668
1669                temp = li->list[x];
1670                p = temp;
1671                while (*p) {
1672                  if (*p == '/')
1673                    *p = '\\';
1674                  p++;
1675                }
1676                p =
1677                  xmalloc(strlen(temp) + strlen(li->targetpath) + 2,
1678                          pszSrcFile, __LINE__);
1679                if (p) {
1680                  strcpy(p, li->targetpath);
1681                  if (p[strlen(p) - 1] != '\\')
1682                    strcat(p, "\\");
1683                  strcat(p, temp);
1684                  li->list[x] = p;
1685                  free(temp);
1686                }
1687              }
1688              if (fFolderAfterExtract) {
1689
1690                CHAR objectpath[CCHMAXPATH], *p;
1691                APIRET rc;
1692
1693                GetDesktopName(objectpath, sizeof(objectpath));
1694                rc = WinDlgBox(HWND_DESKTOP, dcd->hwndParent, ObjCnrDlgProc,
1695                               FM3ModHandle, OBJCNR_FRAME,
1696                               MPFROMP(objectpath));
1697                if (rc) {
1698                  if (rc > 1)
1699                    strcpy(objectpath, "<WP_DESKTOP>");
1700                  p = NULL;
1701                  if (li->arcname) {
1702                    p = strrchr(li->arcname, '\\');
1703                    if (p)
1704                      p++;
1705                  }
1706                  MakeShadows(dcd->hwndParent, li->list, 2, objectpath, p);
1707                }
1708              }
1709              Broadcast(WinQueryAnchorBlock(hwnd),
1710                        hwndMain,
1711                        UM_UPDATERECORDLIST, MPFROMP(li->list), MPVOID);
1712            }
1713            else if (li->type == IDM_EXEC)
1714              ExecOnList(hwnd,
1715                         li->runfile,
1716                         WINDOWED | SEPARATEKEEP | PROMPT,
1717                         li->targetpath,
1718                         NULL, GetPString(IDS_EXECARCFILETITLETEXT));
1719            else if (li->type == IDM_VIRUSSCAN)
1720              ExecOnList(hwnd, virus, PROMPT | WINDOWED | SEPARATEKEEP,
1721                         li->targetpath, NULL,
1722                         GetPString(IDS_VIRUSSCANARCHIVETITLETEXT));
1723            else if (li->type == IDM_VIEW || li->type == IDM_VIEWTEXT ||
1724                     li->type == IDM_VIEWBINARY || li->type == IDM_EDIT ||
1725                     li->type == IDM_EDITTEXT ||
1726                     li->type == IDM_VIEWARCHIVE ||
1727                     li->type == IDM_EDITBINARY ||
1728                     li->type == IDM_MCIPLAY || li->type == IDM_PRINT) {
1729
1730              CHAR *temp, *p;
1731
1732              for (x = 0; li->list[x]; x++) {
1733                if (!li->info->exwdirs) {
1734                  temp = li->list[x];
1735                  p = strrchr(li->list[x], '\\');
1736                  if (p) {
1737                    p++;
1738                    li->list[x] = xstrdup(p, pszSrcFile, __LINE__);
1739                    if (!li->list[x])
1740                      li->list[x] = temp;
1741                    else {
1742                      free(temp);
1743                    }
1744                  }
1745                }
1746                sprintf(cl, "%s%s%s", li->targetpath,
1747                        (li->targetpath[strlen(li->targetpath) - 1] == '\\') ?
1748                        NullStr : "\\", li->list[x]);
1749                temp = li->list[x];
1750                li->list[x] = xstrdup(cl, pszSrcFile, __LINE__);
1751                if (!li->list[x])
1752                  li->list[x] = temp;
1753                else
1754                  free(temp);
1755              }
1756              if (li->type == IDM_VIEW || li->type == IDM_EDIT) {
1757
1758                BOOL isit = TestBinary(li->list[0]);
1759
1760                if (isit) {
1761                  if (li->type == IDM_VIEW)
1762                    li->type = IDM_VIEWBINARY;
1763                  else
1764                    li->type = IDM_EDITBINARY;
1765                }
1766                else {
1767                  if (li->type == IDM_VIEW)
1768                    li->type = IDM_VIEWTEXT;
1769                  else
1770                    li->type = IDM_EDITTEXT;
1771                }
1772              }
1773              if (li->type == IDM_MCIPLAY) {
1774
1775                FILE *fp;
1776
1777                fp = xfopen("$FM2PLAY.$$$", "w", pszSrcFile, __LINE__);
1778                if (fp) {
1779                  fprintf(fp, "%s", ";AV/2-built FM2Play listfile\n");
1780                  for (x = 0; li->list[x]; x++)
1781                    fprintf(fp, "%s\n", li->list[x]);
1782                  fprintf(fp, ";end\n");
1783                  fclose(fp);
1784                  RunFM2Util("FM2PLAY.EXE", "/@$FM2PLAY.$$$");
1785                }
1786              }
1787              else if (li->type == IDM_PRINT) {
1788                strcpy(li->targetpath, printer);
1789                if (_beginthread(PrintListThread, NULL, 65536, (PVOID) li) !=
1790                    -1) {
1791                  Runtime_Error(pszSrcFile, __LINE__,
1792                                GetPString(IDS_COULDNTSTARTTHREADTEXT));
1793                  li = NULL;
1794                }
1795              }
1796              else if (li->type == IDM_VIEWARCHIVE) {
1797
1798                ARC_TYPE *info;
1799
1800                for (x = 0; li->list[x]; x++) {
1801                  if (IsFile(li->list[x]) == 1) {
1802                    info = NULL;        // Do not hide dups - fixme to know why?
1803                    if (WinDlgBox(HWND_DESKTOP, HWND_DESKTOP,
1804                                  SBoxDlgProc, FM3ModHandle, ASEL_FRAME,
1805                                  (PVOID) & info) && info) {
1806                      StartArcCnr(HWND_DESKTOP,
1807                                  HWND_DESKTOP, li->list[x], 4, info);
1808                    }
1809                  }
1810                }
1811              }
1812              else if ((li->type == IDM_VIEWTEXT && *viewer) ||
1813                       (li->type == IDM_VIEWBINARY && *binview) ||
1814                       (li->type == IDM_EDITTEXT && *editor) ||
1815                       (li->type == IDM_EDITBINARY && *bined)) {
1816                DosSleep(100);
1817                ExecOnList(hwnd, ((li->type == IDM_VIEWTEXT) ? viewer :
1818                                  (li->type == IDM_VIEWBINARY) ? binview :
1819                                  (li->type == IDM_EDITTEXT) ? editor :
1820                                  bined),
1821                           WINDOWED | SEPARATE, li->targetpath, li->list,
1822                           NULL);
1823              }
1824              else {
1825                if (li->hwnd) {
1826
1827                  ULONG viewtype;
1828
1829                  for (x = 0; li->list[x]; x++) {
1830                    if (x == 0) {
1831                      if (li->type == IDM_VIEWBINARY ||
1832                          li->type == IDM_EDITBINARY)
1833                        viewtype = 16;
1834                      else
1835                        viewtype = 8;
1836                    }
1837                    else
1838                      viewtype = 0;
1839                    temp = xstrdup(li->list[x], pszSrcFile, __LINE__);
1840                    if (temp) {
1841                      if (!PostMsg(WinQueryWindow(li->hwnd, QW_PARENT),
1842                                   UM_LOADFILE,
1843                                   MPFROMLONG(4L +
1844                                              (li->type == IDM_VIEWTEXT ||
1845                                               li->type == IDM_VIEWBINARY) +
1846                                              viewtype), MPFROMP(temp)))
1847                        free(temp);
1848                    }
1849                  }
1850                }
1851              }
1852            }
1853          }
1854          break;
1855
1856        case IDM_FIND:
1857          {
1858            INT numfiles = 0, numalloced = 0;
1859            CHAR **list2 = NULL, fullname[CCHMAXPATH * 2], *p;
1860
1861            for (x = 0; li->list[x]; x++) {
1862              p = li->list[x];
1863              while (*p) {
1864                if (*p == '/')
1865                  *p = '\\';
1866                p++;
1867              }
1868              sprintf(fullname, "%s%s%s", dcd->directory,
1869                      (dcd->directory[strlen(dcd->directory) - 1] == '\\') ?
1870                      NullStr : "\\", li->list[x]);
1871              if (IsFile(fullname) != -1)
1872                if (AddToList(fullname, &list2, &numfiles, &numalloced))
1873                  break;
1874              if (strchr(li->list[x], '\\')) {
1875                p = strrchr(li->list[x], '\\');
1876                if (p) {
1877                  p++;
1878                  if (*p) {
1879                    sprintf(fullname, "%s%s%s", dcd->directory,
1880                            (dcd->directory[strlen(dcd->directory) - 1] ==
1881                               '\\') ? NullStr : "\\",
1882                            p);
1883                    if (IsFile(fullname) != -1)
1884                      if (AddToList(fullname, &list2, &numfiles, &numalloced))
1885                        break;
1886                  }
1887                }
1888              }
1889            }
1890            if (!numfiles || !list2)
1891              Runtime_Error(pszSrcFile, __LINE__, "no files or list");
1892            else {
1893              WinSendMsg(dcd->hwndCnr, WM_COMMAND,
1894                         MPFROM2SHORT(IDM_COLLECTOR, 0), MPVOID);
1895              DosSleep(128L);
1896              if (Collector) {
1897                if (!PostMsg(Collector, WM_COMMAND,
1898                             MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(list2)))
1899                  FreeList(list2);
1900              }
1901              else
1902                FreeList(list2);
1903            }
1904          }
1905          break;
1906        }
1907      }
1908      FreeListInfo(li);
1909    }
1910    return 0;
1911
1912  case WM_CLOSE:
1913    WinDestroyWindow(hwnd);
1914    break;
1915
1916  case WM_DESTROY:
1917    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1918    if (dcd) {
1919      if (*dcd->workdir) {
1920        DosSleep(33L);
1921        wipeallf("%s\\*", dcd->workdir);
1922        if (rmdir(dcd->workdir)) {
1923          DosSleep(256L);
1924          wipeallf("%s\\*", dcd->workdir);
1925          rmdir(dcd->workdir);
1926        }
1927      }
1928      FreeList(dcd->lastselection);
1929      WinSendMsg(dcd->hwndCnr, UM_CLOSE, MPVOID, MPVOID);
1930      free(dcd);
1931      WinSetWindowPtr(dcd->hwndCnr, QWL_USER, NULL);
1932    }
1933    if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
1934      WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
1935    break;
1936  }                                     // switch
1937  return WinDefWindowProc(hwnd, msg, mp1, mp2);
1938}
1939
1940static MRESULT EXPENTRY ArcCnrWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
1941                                      MPARAM mp2)
1942{
1943  DIRCNRDATA *dcd = INSTDATA(hwnd);
1944  DIRCNRDATA *dcdsrc;
1945
1946  switch (msg) {
1947  case DM_PRINTOBJECT:
1948  case DM_DISCARDOBJECT:
1949    if (dcd)
1950      return WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
1951    else
1952      return MRFROMLONG(DRR_TARGET);
1953
1954  case WM_CHAR:
1955    shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
1956    if (SHORT1FROMMP(mp1) & KC_KEYUP)
1957      return (MRESULT) TRUE;
1958    if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
1959      switch (SHORT2FROMMP(mp2)) {
1960      case VK_DELETE:
1961        PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DELETE, 0), MPVOID);
1962        break;
1963      }
1964    }
1965    if (shiftstate || fNoSearch)
1966      break;
1967    if (SHORT1FROMMP(mp1) & KC_CHAR) {
1968
1969      ULONG thistime, len;
1970      SEARCHSTRING srch;
1971      PCNRITEM pci;
1972
1973      if (!dcd)
1974        break;
1975      switch (SHORT1FROMMP(mp2)) {
1976      case '\x1b':
1977      case '\r':
1978      case '\n':
1979        dcd->lasttime = 0;
1980        *dcd->szCommonName = 0;
1981        break;
1982      default:
1983        thistime = WinQueryMsgTime(WinQueryAnchorBlock(hwnd));
1984        if (thistime > dcd->lasttime + 1250)
1985          *dcd->szCommonName = 0;
1986        dcd->lasttime = thistime;
1987        if (SHORT1FROMMP(mp2) == ' ' && !*dcd->szCommonName)
1988          break;
1989      KbdRetry:
1990        len = strlen(dcd->szCommonName);
1991        if (len >= CCHMAXPATH - 1) {
1992          *dcd->szCommonName = 0;
1993          len = 0;
1994        }
1995        dcd->szCommonName[len] = toupper(SHORT1FROMMP(mp2));
1996        dcd->szCommonName[len + 1] = 0;
1997        memset(&srch, 0, sizeof(SEARCHSTRING));
1998        srch.cb = (ULONG) sizeof(SEARCHSTRING);
1999        srch.pszSearch = dcd->szCommonName;
2000        srch.fsPrefix = TRUE;
2001        srch.fsCaseSensitive = FALSE;
2002        srch.usView = CV_ICON;
2003        pci = WinSendMsg(hwnd,
2004                         CM_SEARCHSTRING,
2005                         MPFROMP(&srch), MPFROMLONG(CMA_FIRST));
2006        if (pci && (INT) pci != -1) {
2007
2008          USHORT attrib = CRA_CURSORED;
2009
2010          /* make found item current item */
2011          if (!stricmp(pci->pszFileName, dcd->szCommonName))
2012            attrib |= CRA_SELECTED;
2013          WinSendMsg(hwnd,
2014                     CM_SETRECORDEMPHASIS,
2015                     MPFROMP(pci), MPFROM2SHORT(TRUE, attrib));
2016          /* make sure that record shows in viewport */
2017          ShowCnrRecord(hwnd, (PMINIRECORDCORE) pci);
2018          return (MRESULT) TRUE;
2019        }
2020        else {
2021          if (SHORT1FROMMP(mp2) == ' ') {
2022            dcd->szCommonName[len] = 0;
2023            break;
2024          }
2025          *dcd->szCommonName = 0;
2026          dcd->lasttime = 0;
2027          if (len)                      // retry as first letter if no match
2028            goto KbdRetry;
2029        }
2030        break;
2031      }
2032    }
2033    break;
2034
2035  case WM_MOUSEMOVE:
2036  case WM_BUTTON1UP:
2037  case WM_BUTTON2UP:
2038  case WM_BUTTON3UP:
2039  case WM_CHORD:
2040    shiftstate = (SHORT2FROMMP(mp2) & (KC_SHIFT | KC_ALT | KC_CTRL));
2041    break;
2042
2043  case WM_BUTTON1MOTIONEND:
2044    {
2045      CNRINFO cnri;
2046
2047      memset(&cnri, 0, sizeof(CNRINFO));
2048      cnri.cb = sizeof(CNRINFO);
2049      if (WinSendMsg(hwnd,
2050                     CM_QUERYCNRINFO,
2051                     MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)))) {
2052        if (cnri.flWindowAttr & CV_DETAIL)
2053          PrfWriteProfileData(fmprof,
2054                              appname,
2055                              "ArcCnrSplitBar",
2056                              (PVOID) & cnri.xVertSplitbar, sizeof(LONG));
2057      }
2058    }
2059    break;
2060
2061  case WM_PRESPARAMCHANGED:
2062    PresParamChanged(hwnd, "ArcCnr", mp1, mp2);
2063    break;
2064
2065  case UM_UPDATERECORD:
2066  case UM_UPDATERECORDLIST:
2067    if (dcd && !IsArcThere(hwnd, dcd->arcname))
2068      PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2069    return 0;
2070
2071  case WM_SETFOCUS:
2072    /*
2073     * put name of our window (archive name) on status line
2074     */
2075    if (dcd && hwndStatus && mp2)
2076      WinSendMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2077    break;
2078
2079  case UM_SETUP2:
2080    if (dcd && dcd->info) {
2081      if (dcd->info->fdpos == -1 || !dcd->info->datetype)
2082        dcd->sortFlags &= (~SORT_LWDATE);
2083      if (dcd->info->nsizepos == -1)
2084        dcd->sortFlags &= (~SORT_EASIZE);
2085      if (dcd->info->osizepos == -1)
2086        dcd->sortFlags &= (~SORT_SIZE);
2087      AdjustCnrColVis(hwnd,
2088                      GetPString(IDS_OLDSIZECOLTEXT),
2089                      dcd->info->osizepos != -1, FALSE);
2090      AdjustCnrColVis(hwnd,
2091                      GetPString(IDS_NEWSIZECOLTEXT),
2092                      dcd->info->nsizepos != -1, FALSE);
2093      // Display unsullied date/time string if type 0
2094      AdjustCnrColVis(hwnd,
2095                      GetPString(IDS_DATETIMECOLTEXT),
2096                      dcd->info->fdpos != -1 && !dcd->info->datetype, FALSE);
2097      // Display parsed date/time columns if type specified
2098      AdjustCnrColVis(hwnd,
2099                      GetPString(IDS_TIMECOLTEXT),
2100                      dcd->info->fdpos != -1 && dcd->info->datetype, FALSE);
2101      AdjustCnrColVis(hwnd,
2102                      GetPString(IDS_DATECOLTEXT),
2103                      dcd->info->fdpos != -1 && dcd->info->datetype, FALSE);
2104      WinSendMsg(hwnd, CM_INVALIDATEDETAILFIELDINFO, MPVOID, MPVOID);
2105    }
2106    return 0;
2107
2108  case UM_RESCAN:
2109    if (dcd) {
2110      CNRINFO cnri;
2111      CHAR s[CCHMAXPATH * 2], tb[81], tf[81];
2112      PARCITEM pci;
2113
2114      if (mp1) {
2115        PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPVOID);
2116        return 0;
2117      }
2118      memset(&cnri, 0, sizeof(CNRINFO));
2119      cnri.cb = sizeof(CNRINFO);
2120      WinSendMsg(hwnd,
2121                 CM_QUERYCNRINFO,
2122                 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2123      dcd->totalfiles = cnri.cRecords;
2124      commafmt(tf, sizeof(tf), dcd->selectedfiles);
2125      if (dcd->ullTotalBytes)
2126        CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, 'K');
2127      else
2128        *tb = 0;
2129      sprintf(s, "%s%s%s", tf, *tb ? " / " : NullStr, tb);
2130      WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
2131      commafmt(tf, sizeof(tf), dcd->totalfiles);
2132      if (dcd->ullTotalBytes)
2133        CommaFmtULL(tb, sizeof(tb), dcd->ullTotalBytes, 'K');
2134      else
2135        *tb = 0;
2136      sprintf(s, "%s%s%s", tf, *tb ? " / " : NullStr, tb);
2137      WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, s);
2138      if (hwndStatus &&
2139          dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
2140        sprintf(s, " [%s%s%s]%s%s%s  %s",
2141                tf,
2142                *tb ? " / " : NullStr,
2143                tb,
2144                *dcd->mask.szMask ? " (" : NullStr,
2145                *dcd->mask.szMask ? dcd->mask.szMask : NullStr,
2146                *dcd->mask.szMask ? ")" : NullStr, dcd->arcname);
2147        WinSetWindowText(hwndStatus, s);
2148        if (!ParentIsDesktop(hwnd, dcd->hwndParent)) {
2149          pci = WinSendMsg(hwnd,
2150                           CM_QUERYRECORDEMPHASIS,
2151                           MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
2152          if (pci && (INT) pci != -1) {
2153            if (fSplitStatus && hwndStatus2) {
2154              if (dcd->ullTotalBytes)
2155                CommaFmtULL(tb, sizeof(tb), pci->cbFile, ' ');
2156              else
2157                *tb = 0;
2158              sprintf(s, "%s%s%s%s",
2159                      *tb ? " " : NullStr,
2160                      tb, *tb ? "  " : NullStr, pci->szFileName);
2161              WinSetWindowText(hwndStatus2, s);
2162            }
2163            if (fMoreButtons)
2164              WinSetWindowText(hwndName, pci->szFileName);
2165          }
2166          else {
2167            WinSetWindowText(hwndStatus2, NullStr);
2168            WinSetWindowText(hwndName, NullStr);
2169          }
2170          WinSetWindowText(hwndDate, NullStr);
2171          WinSetWindowText(hwndAttr, NullStr);
2172        }
2173      }
2174      if ((dcd->arcfilled && !dcd->totalfiles) ||
2175          !IsArcThere(hwnd, dcd->arcname))
2176        PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2177    }
2178    return 0;
2179
2180  case UM_SETUP:
2181    if (!dcd) {
2182      Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
2183      PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2184      return 0;
2185    }
2186    else {
2187      if (!dcd->hwndObject) {
2188        /*
2189         * first time through -- set things up
2190         */
2191        {
2192          CHAR *p, *pp;
2193          ULONG z, was;
2194          APIRET rc;
2195
2196          rc = DosCreateDir(dcd->workdir, 0);
2197          if (rc) {
2198            if (rc == ERROR_ACCESS_DENIED) {
2199              p = strrchr(dcd->workdir, '.');
2200              if (p) {
2201                p++;
2202                pp = p;
2203                was = strtoul(p, &pp, 16);
2204                for (z = 0; z < 99; z++) {
2205                  was++;
2206                  sprintf(p, "%03x");
2207                  rc = DosCreateDir(dcd->workdir, 0);
2208                  if (!rc || rc != ERROR_ACCESS_DENIED)
2209                    break;
2210                }
2211              }
2212            }
2213            if (rc)
2214              PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2215            return 0;
2216          }
2217        }
2218        RestorePresParams(hwnd, "ArcCnr");
2219        dcd->mask.fNoAttribs = TRUE;
2220        dcd->mask.fNoDirs = TRUE;
2221        *dcd->mask.prompt = 0;
2222        {
2223          PFIELDINFO pfi, pfiLastLeftCol;
2224          ULONG numcols = CON_COLS;
2225          CNRINFO cnri;
2226          ULONG size;
2227
2228          pfi = WinSendMsg(hwnd,
2229                           CM_ALLOCDETAILFIELDINFO,
2230                           MPFROMLONG(numcols), NULL);
2231          if (pfi) {
2232
2233            PFIELDINFO pfiFirst;
2234            FIELDINFOINSERT fii;
2235
2236            pfiFirst = pfi;
2237            pfi->flData = CFA_STRING | CFA_LEFT | CFA_FIREADONLY;
2238            pfi->flTitle = CFA_CENTER;
2239            pfi->pTitleData = GetPString(IDS_FILENAMECOLTEXT);
2240            pfi->offStruct = FIELDOFFSET(ARCITEM, pszFileName);
2241            pfiLastLeftCol = pfi;
2242            pfi = pfi->pNextFieldInfo;
2243            pfi->flData =
2244              CFA_ULONG | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
2245            pfi->flTitle = CFA_CENTER;
2246            pfi->pTitleData = GetPString(IDS_OLDSIZECOLTEXT);
2247            pfi->offStruct = FIELDOFFSET(ARCITEM, cbFile);
2248            pfi = pfi->pNextFieldInfo;
2249            pfi->flData =
2250              CFA_ULONG | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
2251            pfi->flTitle = CFA_CENTER;
2252            pfi->pTitleData = GetPString(IDS_NEWSIZECOLTEXT);
2253            pfi->offStruct = FIELDOFFSET(ARCITEM, cbComp);
2254            pfi = pfi->pNextFieldInfo;
2255            pfi->flData =
2256              CFA_STRING | CFA_CENTER | CFA_SEPARATOR | CFA_FIREADONLY;
2257            pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
2258            pfi->pTitleData = GetPString(IDS_DATETIMECOLTEXT);
2259            pfi->offStruct = FIELDOFFSET(ARCITEM, pszDate);
2260            pfi = pfi->pNextFieldInfo;
2261            pfi->flData = CFA_DATE | CFA_RIGHT | CFA_FIREADONLY;
2262            pfi->flTitle = CFA_CENTER;
2263            pfi->pTitleData = GetPString(IDS_DATECOLTEXT);
2264            pfi->offStruct = FIELDOFFSET(ARCITEM, date);
2265            pfi = pfi->pNextFieldInfo;
2266            pfi->flData = CFA_TIME | CFA_RIGHT | CFA_FIREADONLY;
2267            pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
2268            pfi->pTitleData = GetPString(IDS_TIMECOLTEXT);
2269            pfi->offStruct = FIELDOFFSET(ARCITEM, time);
2270            memset(&fii, 0, sizeof(FIELDINFOINSERT));
2271            fii.cb = sizeof(FIELDINFOINSERT);
2272            fii.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
2273            fii.cFieldInfoInsert = (SHORT) numcols;
2274            fii.fInvalidateFieldInfo = TRUE;
2275            WinSendMsg(hwnd,
2276                       CM_INSERTDETAILFIELDINFO,
2277                       MPFROMP(pfiFirst), MPFROMP(&fii));
2278            PostMsg(hwnd, UM_SETUP2, MPVOID, MPVOID);
2279
2280            memset(&cnri, 0, sizeof(cnri));
2281            cnri.cb = sizeof(CNRINFO);
2282            cnri.pFieldInfoLast = pfiLastLeftCol;
2283            cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET + 32;
2284
2285            size = sizeof(LONG);
2286            PrfQueryProfileData(fmprof, appname, "ArcCnrSplitBar",
2287                                &cnri.xVertSplitbar, &size);
2288            if (cnri.xVertSplitbar <= 0)
2289              cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET + 32;
2290
2291            cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT | CV_NAME));
2292            cnri.flWindowAttr |= (CV_DETAIL | CA_DETAILSVIEWTITLES | CV_FLOW);
2293            cnri.flWindowAttr &= (~(CA_ORDEREDTARGETEMPH |
2294                                    CA_MIXEDTARGETEMPH));
2295            cnri.pSortRecord = (PVOID) ArcSort;
2296            WinSendMsg(hwnd,
2297                       CM_SETCNRINFO,
2298                       MPFROMP(&cnri),
2299                       MPFROMLONG(CMA_PFIELDINFOLAST |
2300                                  CMA_XVERTSPLITBAR |
2301                                  CMA_PSORTRECORD | CMA_FLWINDOWATTR));
2302          }
2303        }
2304        WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
2305        if (_beginthread(MakeObjWin, NULL, 245760, (PVOID) dcd) == -1) {
2306          Runtime_Error(pszSrcFile, __LINE__,
2307                        GetPString(IDS_COULDNTSTARTTHREADTEXT));
2308          PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2309          return 0;
2310        }
2311        else
2312          DosSleep(1L);
2313        SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2314                                  DIR_FILTER), &dcd->mask, TRUE);
2315        SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2316                                DIR_SORT), dcd->sortFlags, TRUE);
2317        DefArcSortFlags = dcd->sortFlags;       // Remember for new windows
2318      }
2319    }
2320    return 0;
2321
2322  case UM_SETDIR:
2323    if (dcd) {
2324
2325      CHAR s[CCHMAXPATH], *p;
2326      ULONG ret = 0;
2327
2328      WinQueryDlgItemText(dcd->hwndClient, ARC_EXTRACTDIR, CCHMAXPATH, s);
2329      bstrip(s);
2330      MakeFullName(s);
2331      if (*s) {
2332        while ((p = strchr(s, '/')) != NULL)
2333          *p = '\\';
2334        while (strlen(s) > 3 && s[strlen(s) - 1] == '\\')
2335          s[strlen(s) - 1] = 0;
2336        if (stricmp(s, dcd->directory)) {
2337          if (IsFullName(s)) {
2338            if (driveflags[toupper(*s) - 'A'] &
2339                (DRIVE_NOTWRITEABLE | DRIVE_IGNORE | DRIVE_INVALID)) {
2340              Runtime_Error(pszSrcFile, __LINE__, "drive %s bad", s);
2341              WinSetDlgItemText(dcd->hwndClient,
2342                                ARC_EXTRACTDIR, dcd->directory);
2343              return 0;
2344            }
2345          }
2346          if (!SetDir(dcd->hwndParent, hwnd, s, 0)) {
2347            if (stricmp(dcd->directory, s)) {
2348              DosEnterCritSec();
2349              strcpy(lastextractpath, s);
2350              DosExitCritSec();
2351            }
2352            strcpy(dcd->directory, s);
2353            if ((!isalpha(*s) || s[1] != ':') && *s != '.')
2354              saymsg(MB_ENTER | MB_ICONASTERISK,
2355                     hwnd,
2356                     GetPString(IDS_WARNINGTEXT),
2357                     GetPString(IDS_SPECIFYDRIVETEXT));
2358          }
2359          else
2360            ret = 1;
2361        }
2362      }
2363      WinSetDlgItemText(dcd->hwndClient, ARC_EXTRACTDIR, dcd->directory);
2364      return (MRESULT) ret;
2365    }
2366    return 0;
2367
2368  case UM_ENTER:
2369    if (WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID))
2370      return 0;
2371    SetShiftState();
2372    if (dcd && (CHAR *) mp1) {
2373
2374      SWP swp;
2375      CHAR *filename = mp1;
2376
2377      if (IsFile(filename) != 1)
2378        return 0;
2379      WinQueryWindowPos(dcd->hwndFrame, &swp);
2380      DefaultViewKeys(hwnd, dcd->hwndFrame, dcd->hwndParent, &swp, filename);
2381      if (fUnHilite)
2382        UnHilite(hwnd, FALSE, &dcd->lastselection, 0);
2383    }
2384    return 0;
2385
2386  case WM_MENUEND:
2387    if (dcd) {
2388
2389      HWND hwndMenu = (HWND) mp2;
2390
2391      if (hwndMenu == ArcCnrMenu || hwndMenu == ArcMenu) {
2392        MarkAll(hwnd, TRUE, FALSE, TRUE);
2393        if (dcd->cnremphasized) {
2394          WinSendMsg(hwnd,
2395                     CM_SETRECORDEMPHASIS,
2396                     MPVOID, MPFROM2SHORT(FALSE, CRA_SOURCE));
2397          dcd->cnremphasized = FALSE;
2398        }
2399      }
2400    }
2401    break;
2402
2403  case MM_PORTHOLEINIT:
2404    if (dcd) {
2405      switch (SHORT1FROMMP(mp1)) {
2406      case 0:
2407      case 1:
2408        {
2409          ULONG wmsg;
2410
2411          wmsg = SHORT1FROMMP(mp1) == 0 ? UM_FILESMENU : UM_VIEWSMENU;
2412          PortholeInit((HWND) WinSendMsg(dcd->hwndClient,
2413                                         wmsg, MPVOID, MPVOID), mp1, mp2);
2414        }
2415        break;
2416      }
2417    }
2418    break;
2419
2420  case UM_INITMENU:
2421  case WM_INITMENU:
2422    if (dcd) {
2423      switch (SHORT1FROMMP(mp1)) {
2424      case IDM_FILESMENU:
2425        if (dcd->info) {
2426          WinEnableMenuItem((HWND) mp2,
2427                            IDM_DELETE, dcd->info->delete != NULL);
2428          WinEnableMenuItem((HWND) mp2, IDM_TEST, dcd->info->test != NULL);
2429          WinEnableMenuItem((HWND) mp2,
2430                            IDM_EXTRACT, dcd->info->extract != NULL);
2431          WinEnableMenuItem((HWND) mp2,
2432                            IDM_EXTRACTWDIRS, dcd->info->exwdirs != NULL);
2433          WinEnableMenuItem((HWND) mp2,
2434                            IDM_ARCEXTRACTWDIRS, dcd->info->exwdirs != NULL);
2435          WinEnableMenuItem((HWND) mp2,
2436                            IDM_ARCEXTRACTWDIRSEXIT,
2437                            dcd->info->exwdirs != NULL);
2438        }
2439        break;
2440
2441      case IDM_VIEWSMENU:
2442        WinCheckMenuItem((HWND) mp2,
2443                         IDM_MINIICONS, (dcd->flWindowAttr & CV_MINI) != 0);
2444        WinEnableMenuItem((HWND) mp2,
2445                          IDM_RESELECT, (dcd->lastselection != NULL));
2446        break;
2447
2448      case IDM_COMMANDSMENU:
2449        SetupCommandMenu((HWND) mp2, hwnd);
2450        break;
2451
2452      case IDM_SORTSUBMENU:
2453        SetSortChecks((HWND) mp2, dcd->sortFlags);
2454        break;
2455
2456      case IDM_WINDOWSMENU:
2457        /*
2458         * add switchlist entries to end of pulldown menu
2459         */
2460        SetupWinList((HWND)mp2,
2461                     hwndMain ? hwndMain : (HWND)0, dcd->hwndFrame);
2462        break;
2463      }
2464      dcd->hwndLastMenu = (HWND) mp2;
2465    }
2466    if (msg == WM_INITMENU)
2467      break;
2468    return 0;
2469
2470  case UM_LOADFILE:
2471    if (dcd && mp2) {
2472
2473      HWND ret;
2474
2475      ret = StartMLEEditor(dcd->hwndParent,
2476                           (INT) mp1, (CHAR *) mp2, dcd->hwndFrame);
2477      free((CHAR *) mp2);
2478      return MRFROMLONG(ret);
2479    }
2480    return 0;
2481
2482  case UM_COMMAND:
2483    if (mp1) {
2484      if (dcd) {
2485        if (!PostMsg(dcd->hwndObject, UM_COMMAND, mp1, mp2)) {
2486          Runtime_Error(pszSrcFile, __LINE__, "post");
2487          FreeListInfo((LISTINFO *) mp1);
2488        }
2489        else
2490          return (MRESULT) TRUE;
2491      }
2492      else
2493        FreeListInfo((LISTINFO *) mp1);
2494    }
2495    return 0;
2496
2497  case UM_OPENWINDOWFORME:
2498    if (dcd) {
2499      if (mp1 && !IsFile((CHAR *) mp1)) {
2500        OpenDirCnr((HWND) 0, hwndMain, dcd->hwndFrame, FALSE, (char *)mp1);
2501      }
2502      else if (mp1 && IsFile(mp1) == 1) {
2503        StartArcCnr(HWND_DESKTOP,
2504                    dcd->hwndFrame, (CHAR *) mp1, 4, (ARC_TYPE *) mp2);
2505      }
2506    }
2507    return 0;
2508
2509  case WM_COMMAND:
2510    DosError(FERR_DISABLEHARDERR);
2511    if (dcd) {
2512      if (SwitchCommand(dcd->hwndLastMenu, SHORT1FROMMP(mp1)))
2513        return 0;
2514      if (WinSendMsg(hwnd, UM_SETDIR, MPVOID, MPVOID))
2515        return 0;
2516      if (!IsArcThere(hwnd, dcd->arcname)) {
2517        PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2518        return 0;
2519      }
2520      switch (SHORT1FROMMP(mp1)) {
2521      case IDM_TREEVIEW:
2522
2523        break;
2524
2525      case IDM_CONTEXTMENU:
2526        {
2527          PCNRITEM pci;
2528
2529          pci = (PCNRITEM) CurrentRecord(hwnd);
2530          PostMsg(hwnd,
2531                  WM_CONTROL,
2532                  MPFROM2SHORT(ARC_CNR, CN_CONTEXTMENU), MPFROMP(pci));
2533        }
2534        break;
2535
2536      case IDM_NEXTWINDOW:
2537      case IDM_PREVWINDOW:
2538        {
2539          HWND hwndActive;
2540
2541          hwndActive = WinQueryFocus(HWND_DESKTOP);
2542          WinSetFocus(HWND_DESKTOP,
2543                      hwndActive == hwnd ?
2544                        WinWindowFromID(dcd->hwndClient, ARC_EXTRACTDIR) :
2545                        hwnd);
2546        }
2547        break;
2548
2549      case IDM_FOLDERAFTEREXTRACT:
2550        fFolderAfterExtract = fFolderAfterExtract ? FALSE : TRUE;
2551        PrfWriteProfileData(fmprof, appname, "FolderAfterExtract",
2552                            &fFolderAfterExtract, sizeof(BOOL));
2553        break;
2554
2555      case IDM_SHOWSELECT:
2556        QuickPopup(hwnd, dcd, CheckMenu(&ArcCnrMenu, ARCCNR_POPUP),
2557                   IDM_SELECTSUBMENU);
2558        break;
2559
2560      case IDM_SHOWSORT:
2561        QuickPopup(hwnd, dcd, CheckMenu(&ArcCnrMenu, ARCCNR_POPUP),
2562                   IDM_SORTSUBMENU);
2563        break;
2564
2565      case IDM_NOTEBOOK:
2566        if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndParent))
2567          PostMsg(dcd->hwndParent, msg, mp1, mp2);
2568        else
2569          WinDlgBox(HWND_DESKTOP,
2570                    hwnd,
2571                    CfgDlgProc, FM3ModHandle, CFG_FRAME, (PVOID) "Archive");
2572        break;
2573
2574      case IDM_RESCAN:
2575        dcd->ullTotalBytes = dcd->totalfiles =
2576          dcd->selectedfiles = dcd->selectedbytes = 0;
2577        WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, "0");
2578        WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, "0 / 0k");
2579        dcd->totalfiles = FillArcCnr(dcd->hwndCnr,
2580                                     dcd->arcname,
2581                                     &dcd->info,
2582                                     &dcd->ullTotalBytes, &dcd->stopflag);
2583        PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
2584        PostMsg(dcd->hwndCnr, UM_SETUP2, MPVOID, MPVOID);
2585        WinSendMsg(dcd->hwndCnr,
2586                   CM_INVALIDATERECORD,
2587                   MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
2588        break;
2589
2590      case IDM_RESELECT:
2591        SelectList(hwnd, TRUE, FALSE, FALSE, NULL, NULL, dcd->lastselection);
2592        break;
2593
2594      case IDM_HELP:
2595        if (hwndHelp)
2596          WinSendMsg(hwndHelp,
2597                     HM_DISPLAY_HELP,
2598                     MPFROM2SHORT(HELP_ARCLIST, 0),
2599                     MPFROMSHORT(HM_RESOURCEID));
2600        break;
2601
2602      case IDM_WINDOWDLG:
2603        if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndFrame))
2604          PostMsg(dcd->hwndParent,
2605                  UM_COMMAND, MPFROM2SHORT(IDM_WINDOWDLG, 0), MPVOID);
2606        break;
2607
2608      case IDM_SELECTALL:
2609      case IDM_SELECTALLFILES:
2610      case IDM_DESELECTALL:
2611      case IDM_DESELECTALLFILES:
2612      case IDM_SELECTMASK:
2613      case IDM_DESELECTMASK:
2614      case IDM_INVERT:
2615        {
2616          PARCITEM pci;
2617
2618          pci = (PARCITEM) WinSendMsg(hwnd,
2619                                      CM_QUERYRECORDEMPHASIS,
2620                                      MPFROMLONG(CMA_FIRST),
2621                                      MPFROMSHORT(CRA_CURSORED));
2622          if ((INT) pci == -1)
2623            pci = NULL;
2624          if (SHORT1FROMMP(mp1) == IDM_HIDEALL) {
2625            if (pci) {
2626              if (!(pci->rc.flRecordAttr & CRA_SELECTED))
2627                pci->rc.flRecordAttr |= CRA_FILTERED;
2628              WinSendMsg(hwnd,
2629                         CM_INVALIDATERECORD,
2630                         MPFROMP(&pci),
2631                         MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
2632              break;
2633            }
2634          }
2635          PostMsg(dcd->hwndObject, UM_SELECT, mp1, MPFROMP(pci));
2636        }
2637        break;
2638
2639      case IDM_SORTSMARTNAME:
2640      case IDM_SORTNAME:
2641      case IDM_SORTFILENAME:
2642      case IDM_SORTSIZE:
2643      case IDM_SORTEASIZE:
2644      case IDM_SORTFIRST:
2645      case IDM_SORTLAST:
2646      case IDM_SORTLWDATE:
2647        dcd->sortFlags &= SORT_REVERSE;
2648        /* intentional fallthru */
2649      case IDM_SORTREVERSE:
2650        switch (SHORT1FROMMP(mp1)) {
2651        case IDM_SORTSMARTNAME:
2652        case IDM_SORTFILENAME:
2653          dcd->sortFlags |= SORT_FILENAME;
2654          break;
2655        case IDM_SORTSIZE:
2656          dcd->sortFlags |= SORT_SIZE;
2657          break;
2658        case IDM_SORTEASIZE:
2659          dcd->sortFlags |= SORT_EASIZE;
2660          break;
2661        case IDM_SORTFIRST:
2662          dcd->sortFlags |= SORT_FIRSTEXTENSION;
2663          break;
2664        case IDM_SORTLAST:
2665          dcd->sortFlags |= SORT_LASTEXTENSION;
2666          break;
2667        case IDM_SORTLWDATE:
2668          dcd->sortFlags |= SORT_LWDATE;
2669          break;
2670        case IDM_SORTREVERSE:
2671          if (dcd->sortFlags & SORT_REVERSE)
2672            dcd->sortFlags &= (~SORT_REVERSE);
2673          else
2674            dcd->sortFlags |= SORT_REVERSE;
2675          break;
2676        }
2677        WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
2678        SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2679                                DIR_SORT), dcd->sortFlags, TRUE);
2680        DefArcSortFlags = dcd->sortFlags;       // Remember for new windows
2681        break;
2682
2683      case IDM_COLLECTOR:
2684        if (!Collector) {
2685          HWND hwndC;
2686          SWP swp;
2687
2688          if (ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
2689              (!fExternalCollector && !strcmp(realappname, FM3Str)))
2690            GetNextWindowPos(dcd->hwndParent, &swp, NULL, NULL);
2691          hwndC = StartCollector(fExternalCollector ||
2692                                   strcmp(realappname, FM3Str) ?
2693                                     HWND_DESKTOP : dcd->hwndParent, 4);
2694          if (hwndC) {
2695            if (!ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
2696                (!fExternalCollector && !strcmp(realappname, FM3Str)))
2697              WinSetWindowPos(hwndC,
2698                              HWND_TOP,
2699                              swp.x,
2700                              swp.y,
2701                              swp.cx,
2702                              swp.cy,
2703                              SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
2704            else if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2705                     fAutoTile && !strcmp(realappname, FM3Str)) {
2706              TileChildren(dcd->hwndParent, TRUE);
2707            }
2708            WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
2709            DosSleep(128L);
2710          }
2711        }
2712        else
2713          StartCollector(dcd->hwndParent, 4);
2714        break;
2715
2716      case IDM_ARCEXTRACTEXIT:
2717      case IDM_ARCEXTRACT:
2718        if (dcd->info->extract)
2719          runemf2(SEPARATE | WINDOWED |
2720                    (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
2721                  hwnd, dcd->directory, NULL, "%s %s%s%s",
2722                  dcd->info->extract,
2723                  needs_quoting(dcd->arcname) ? "\"" : NullStr,
2724                  dcd->arcname,
2725                  needs_quoting(dcd->arcname) ? "\"" : NullStr);
2726        if (SHORT1FROMMP(mp1) == IDM_ARCEXTRACTEXIT)
2727          PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2728        break;
2729
2730      case IDM_ARCEXTRACTWDIRSEXIT:
2731      case IDM_ARCEXTRACTWDIRS:
2732        if (dcd->info->exwdirs)
2733          runemf2(SEPARATE | WINDOWED |
2734                    (fArcStuffVisible ? 0 : BACKGROUND | MINIMIZED),
2735                  hwnd, dcd->directory, NULL, "%s %s%s%s",
2736                  dcd->info->exwdirs,
2737                  needs_quoting(dcd->arcname) ? "\"" : NullStr,
2738                  dcd->arcname,
2739                  needs_quoting(dcd->arcname) ? "\"" : NullStr);
2740        if (SHORT1FROMMP(mp1) == IDM_ARCEXTRACTWDIRSEXIT)
2741          PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
2742        break;
2743
2744      case IDM_RESORT:
2745        WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(ArcSort), MPFROMP(dcd));
2746        break;
2747
2748      case IDM_FILTER:
2749        {
2750          BOOL empty = FALSE;
2751          PARCITEM pci;
2752
2753          if (!*dcd->mask.szMask) {
2754            empty = TRUE;
2755            pci = (PARCITEM) CurrentRecord(hwnd);
2756            if (pci && strchr(pci->szFileName, '.'))
2757              strcpy(dcd->mask.szMask, pci->szFileName);
2758          }
2759
2760          if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
2761                        FM3ModHandle, MSK_FRAME, MPFROMP(&dcd->mask))) {
2762            WinSendMsg(hwnd, CM_FILTER, MPFROMP(ArcFilter), MPFROMP(dcd));
2763            PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2764          }
2765          else if (empty)
2766            *dcd->mask.szMask = 0;
2767          SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2768                                    DIR_FILTER), &dcd->mask, TRUE);
2769        }
2770        break;
2771
2772      case IDM_SWITCH:
2773        if (mp2) {
2774          if (stricmp(dcd->directory, (CHAR *) mp2)) {
2775            DosEnterCritSec();
2776            strcpy(lastextractpath, (CHAR *) mp2);
2777            MakeValidDir(lastextractpath);
2778            DosExitCritSec();
2779          }
2780          strcpy(dcd->directory, (CHAR *) mp2);
2781          MakeValidDir(dcd->directory);
2782          WinSetWindowText(dcd->hwndExtract, dcd->directory);
2783        }
2784        break;
2785
2786      case IDM_WALKDIR:
2787        {
2788          CHAR newdir[CCHMAXPATH];
2789
2790          strcpy(newdir, dcd->directory);
2791          if (!WinDlgBox(HWND_DESKTOP, dcd->hwndParent, WalkExtractDlgProc,
2792                         FM3ModHandle, WALK_FRAME,
2793                         MPFROMP(newdir)) || !*newdir)
2794            break;
2795          if (stricmp(newdir, dcd->directory)) {
2796            strcpy(dcd->directory, newdir);
2797            if (stricmp(lastextractpath, newdir))
2798              strcpy(lastextractpath, newdir);
2799            WinSetWindowText(dcd->hwndExtract, dcd->directory);
2800          }
2801        }
2802        break;
2803
2804      case IDM_TEST:
2805        if (dcd->info->test)
2806          runemf2(SEPARATEKEEP | WINDOWED | MAXIMIZED,
2807                  hwnd, NULL, NULL, "%s %s%s%s", dcd->info->test,
2808                  needs_quoting(dcd->arcname) ? "\"" : NullStr,
2809                  dcd->arcname,
2810                  needs_quoting(dcd->arcname) ? "\"" : NullStr);
2811        break;
2812
2813      case IDM_REFRESH:
2814      case IDM_DELETE:
2815      case IDM_PRINT:
2816      case IDM_VIEW:
2817      case IDM_VIEWTEXT:
2818      case IDM_VIEWBINARY:
2819      case IDM_VIEWARCHIVE:
2820      case IDM_EDIT:
2821      case IDM_EDITTEXT:
2822      case IDM_EDITBINARY:
2823      case IDM_EXTRACT:
2824      case IDM_EXTRACTWDIRS:
2825      case IDM_FIND:
2826      case IDM_EXEC:
2827      case IDM_VIRUSSCAN:
2828        {
2829          LISTINFO *li;
2830
2831          li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
2832          if (li) {
2833            li->type = SHORT1FROMMP(mp1);
2834            li->hwnd = hwnd;
2835            li->list = BuildArcList(hwnd);
2836            if (li->type == IDM_REFRESH) {
2837
2838              CHAR s[CCHMAXPATH], *p;
2839              INT x, y;
2840
2841              for (x = 0; li->list && li->list[x]; x++) {
2842                sprintf(s, "%s%s%s", dcd->workdir,
2843                        (dcd->workdir[strlen(dcd->workdir) - 1] == '\\') ?
2844                        NullStr : "\\", li->list[x]);
2845                if (IsFile(s) != 1) {
2846                  free(li->list[x]);
2847                  li->list[x] = NULL;
2848                  for (y = x; li->list[y]; y++)
2849                    li->list[y] = li->list[y + 1];
2850                  li->list =
2851                    xrealloc(li->list, y * sizeof(CHAR *), pszSrcFile,
2852                             __LINE__);
2853                  x--;
2854                }
2855                else {
2856                  p = xstrdup(s, pszSrcFile, __LINE__);
2857                  if (p) {
2858                    free(li->list[x]);
2859                    li->list[x] = p;
2860                  }
2861                }
2862              }                         // for
2863            }
2864            strcpy(li->arcname, dcd->arcname);
2865            li->info = dcd->info;
2866            {
2867              PARCITEM pai;
2868
2869              if (SHORT1FROMMP(mp1) != IDM_EXEC)
2870                pai = (PARCITEM) CurrentRecord(hwnd);
2871              else
2872                pai = (PARCITEM) WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
2873                                            MPFROMLONG(CMA_FIRST),
2874                                            MPFROMSHORT(CRA_CURSORED));
2875              if (pai && (INT) pai != -1)
2876                strcpy(li->runfile, pai->szFileName);
2877              else
2878                strcpy(li->runfile, li->list[0]);
2879            }
2880            switch (SHORT1FROMMP(mp1)) {
2881            case IDM_VIEW:
2882            case IDM_VIEWTEXT:
2883            case IDM_VIEWBINARY:
2884            case IDM_VIEWARCHIVE:
2885            case IDM_EDIT:
2886            case IDM_EDITTEXT:
2887            case IDM_EDITBINARY:
2888            case IDM_EXEC:
2889            case IDM_PRINT:
2890            case IDM_VIRUSSCAN:
2891              strcpy(li->targetpath, dcd->workdir);
2892              break;
2893            default:
2894              strcpy(li->targetpath, dcd->directory);
2895              break;
2896            }
2897            if (li->list) {
2898              if (!PostMsg(dcd->hwndObject, UM_ACTION, MPFROMP(li), MPVOID)) {
2899                Runtime_Error(pszSrcFile, __LINE__, "post");
2900                FreeListInfo(li);
2901              }
2902              else if (fUnHilite && SHORT1FROMMP(mp1) != IDM_EDIT)
2903                UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
2904            }
2905            else
2906              free(li);
2907          }
2908        }
2909        break;
2910      }
2911    }
2912    return 0;
2913
2914  case WM_CONTROL:
2915    DosError(FERR_DISABLEHARDERR);
2916    if (dcd) {
2917      switch (SHORT2FROMMP(mp1)) {
2918      case CN_BEGINEDIT:
2919        PostMsg(hwnd, CM_CLOSEEDIT, MPVOID, MPVOID);
2920        break;
2921
2922      case CN_ENDEDIT:
2923        if (!((PCNREDITDATA) mp2)->pRecord) {
2924
2925          PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
2926          USHORT cmd = 0;
2927
2928          if (!pfi || pfi->offStruct == FIELDOFFSET(ARCITEM, pszFileName))
2929            cmd = IDM_SORTSMARTNAME;
2930          else if (pfi->offStruct == FIELDOFFSET(ARCITEM, cbFile))
2931            cmd = IDM_SORTSIZE;
2932          else if (pfi->offStruct == FIELDOFFSET(ARCITEM, cbComp))
2933            cmd = IDM_SORTEASIZE;
2934          else if (pfi->offStruct == FIELDOFFSET(ARCITEM, date))
2935            cmd = IDM_SORTLWDATE;
2936          else if (pfi->offStruct == FIELDOFFSET(ARCITEM, time))
2937            cmd = IDM_SORTLWDATE;
2938          if (cmd)
2939            PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
2940        }
2941        break;
2942
2943      case CN_DROPHELP:
2944        saymsg(MB_ENTER, hwnd,
2945               GetPString(IDS_DROPHELPHDRTEXT),
2946               GetPString(IDS_ARCCNRDROPHELPTEXT), dcd->arcname);
2947        return 0;
2948
2949      case CN_DRAGLEAVE:
2950        if (mp2) {
2951
2952          PDRAGINFO pDInfo;
2953
2954          pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2955          DrgAccessDraginfo(pDInfo);    /* Access DRAGINFO */
2956          DrgFreeDraginfo(pDInfo);      /* Free DRAGINFO */
2957        }
2958        return 0;
2959
2960      case CN_DRAGAFTER:
2961      case CN_DRAGOVER:
2962        if (mp2) {
2963
2964          PDRAGITEM pDItem;     /* Pointer to DRAGITEM */
2965          PDRAGINFO pDInfo;     /* Pointer to DRAGINFO */
2966          PARCITEM pci;
2967
2968          pci = (PARCITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2969          if (SHORT1FROMMP(mp1) == CN_DRAGAFTER)
2970            pci = NULL;
2971          pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2972          DrgAccessDraginfo(pDInfo);    /* Access DRAGINFO */
2973          if (*dcd->arcname) {
2974            if ((driveflags[toupper(*dcd->arcname) - 'A'] &
2975                 DRIVE_NOTWRITEABLE) || !dcd->info || !dcd->info->create) {
2976              DrgFreeDraginfo(pDInfo);
2977              return MRFROM2SHORT(DOR_NEVERDROP, 0);
2978            }
2979          }
2980          if (pci) {
2981            DrgFreeDraginfo(pDInfo);
2982            return MRFROM2SHORT(DOR_NODROP, 0);
2983          }
2984          pDItem = DrgQueryDragitemPtr(pDInfo,  /* Access DRAGITEM */
2985                                       0);      /* Index to DRAGITEM */
2986          if (DrgVerifyRMF(pDItem,      /* Check valid rendering */
2987                           DRM_OS2FILE, /* mechanisms and data */
2988                           NULL) && !(pDItem->fsControl & DC_PREPARE)) {
2989            DrgFreeDraginfo(pDInfo);    /* Free DRAGINFO         */
2990            return MRFROM2SHORT(DOR_DROP,       /* Return okay to drop */
2991                                fCopyDefault ? DO_COPY : DO_MOVE);
2992          }
2993          DrgFreeDraginfo(pDInfo);      /* Free DRAGINFO */
2994        }
2995        return (MRFROM2SHORT(DOR_NEVERDROP, 0));        /* Drop not valid */
2996
2997      case CN_INITDRAG:
2998        if (mp2) {
2999
3000          BOOL wasemphasized = FALSE;
3001          PCNRDRAGINIT pcd = (PCNRDRAGINIT) mp2;
3002          PARCITEM pci;
3003
3004          if (pcd) {
3005            pci = (PARCITEM) pcd->pRecord;
3006            if (pci) {
3007              if (pci->rc.flRecordAttr & CRA_SELECTED)
3008                wasemphasized = TRUE;
3009              if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3010                  fSplitStatus && hwndStatus2)
3011                WinSetWindowText(hwndStatus2, GetPString(IDS_DRAGARCMEMTEXT));
3012              if (DoFileDrag(hwnd,
3013                             dcd->hwndObject,
3014                             mp2, dcd->arcname, NULL, TRUE)) {
3015                if ((fUnHilite && wasemphasized) || dcd->ulItemsToUnHilite)
3016                  UnHilite(hwnd, TRUE, &dcd->lastselection, dcd->ulItemsToUnHilite);
3017              }
3018              if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3019                  fSplitStatus && hwndStatus2) {
3020                PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3021              }
3022            }
3023            else {
3024              if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3025                  fSplitStatus && hwndStatus2)
3026                WinSetWindowText(hwndStatus2,
3027                                 GetPString(IDS_DRAGARCFILETEXT));
3028              DragOne(hwnd, dcd->hwndObject, dcd->arcname, FALSE);
3029              if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
3030                  fSplitStatus && hwndStatus2)
3031                PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3032            }
3033          }
3034        }
3035        return 0;
3036
3037      case CN_DROP:
3038        if (mp2) {
3039
3040          LISTINFO *li;
3041
3042          DosBeep(500, 100);            // fixme to know why beep?
3043          li = DoFileDrop(hwnd, dcd->arcname, FALSE, mp1, mp2);
3044          DosBeep(50, 100);             // fixme to know why beep?
3045          dcdsrc = INSTDATA(((PCNRDRAGINFO)mp2)->pDragInfo->hwndSource);
3046          if (dcdsrc->ulItemsToUnHilite) {
3047            saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
3048                   hwnd,
3049                   GetPString(IDS_ERRORTEXT),
3050                   GetPString(IDS_EXCEEDPMDRGLMT));
3051          }
3052          if (li) {
3053            li->type = li->type == DO_MOVE ? IDM_ARCHIVEM : IDM_ARCHIVE;
3054            strcpy(li->targetpath, dcd->arcname);
3055            if (!li->list ||
3056                !li->list[0] ||
3057                !PostMsg(dcd->hwndObject, UM_ACTION, MPFROMP(li), MPVOID))
3058              FreeListInfo(li);
3059          }
3060        }
3061        return 0;
3062
3063      case CN_CONTEXTMENU:
3064        {
3065          PARCITEM pci = (PARCITEM) mp2;
3066
3067          if (pci) {
3068            WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPFROMP(pci),
3069                       MPFROM2SHORT(TRUE, CRA_CURSORED));
3070            MarkAll(hwnd, FALSE, FALSE, TRUE);
3071            dcd->hwndLastMenu = CheckMenu(&ArcMenu, ARC_POPUP);
3072          }
3073          else {
3074            dcd->hwndLastMenu = CheckMenu(&ArcCnrMenu, ARCCNR_POPUP);
3075            if (dcd->hwndLastMenu && !dcd->cnremphasized) {
3076              WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
3077                         MPFROM2SHORT(TRUE, CRA_SOURCE));
3078              dcd->cnremphasized = TRUE;
3079            }
3080          }
3081          if (dcd->hwndLastMenu) {
3082            if (dcd->hwndLastMenu == ArcCnrMenu) {
3083              if (dcd->flWindowAttr & CV_MINI)
3084                WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
3085            }
3086            WinCheckMenuItem(dcd->hwndLastMenu, IDM_FOLDERAFTEREXTRACT,
3087                             fFolderAfterExtract);
3088            if (!PopupMenu(hwnd, hwnd, dcd->hwndLastMenu)) {
3089              if (dcd->cnremphasized) {
3090                WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
3091                           MPFROM2SHORT(FALSE, CRA_SOURCE));
3092                dcd->cnremphasized = TRUE;
3093              }
3094              MarkAll(hwnd, TRUE, FALSE, TRUE);
3095            }
3096          }
3097        }
3098        break;
3099
3100      case CN_EMPHASIS:
3101        if (mp2) {
3102
3103          PNOTIFYRECORDEMPHASIS pre = mp2;
3104          PARCITEM pci;
3105          CHAR s[CCHMAXPATHCOMP + 91], tf[81], tb[81];
3106
3107          pci = (PARCITEM)(pre ? pre->pRecord : NULL);
3108          if (!pci) {
3109            if (!ParentIsDesktop(hwnd, dcd->hwndParent)) {
3110              if (hwndStatus2)
3111                WinSetWindowText(hwndStatus2, NullStr);
3112              if (fMoreButtons)
3113                WinSetWindowText(hwndName, NullStr);
3114            }
3115            break;
3116          }
3117          if (pre->fEmphasisMask & CRA_SELECTED) {
3118            if (pci->rc.flRecordAttr & CRA_SELECTED) {
3119              dcd->selectedbytes += pci->cbFile;
3120              dcd->selectedfiles++;
3121            }
3122            else if (dcd->selectedfiles) {
3123              dcd->selectedbytes -= pci->cbFile;
3124              dcd->selectedfiles--;
3125            }
3126            commafmt(tf, sizeof(tf), dcd->selectedfiles);
3127            if (dcd->ullTotalBytes)
3128              CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, ' ');
3129            else
3130              *tb = 0;
3131            sprintf(s, "%s%s%s", tf, *tb ? " / " : NullStr, tb);
3132            WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
3133          }
3134          else if (WinQueryActiveWindow(dcd->hwndParent) ==
3135                   dcd->hwndFrame &&
3136                   !ParentIsDesktop(hwnd, dcd->hwndParent)) {
3137            if (pre->fEmphasisMask & CRA_CURSORED) {
3138              if (pci->rc.flRecordAttr & CRA_CURSORED) {
3139                if (fSplitStatus && hwndStatus2) {
3140                  if (dcd->ullTotalBytes)
3141                    CommaFmtULL(tb, sizeof(tb), pci->cbFile, ' ');
3142                  else
3143                    *tb = 0;
3144                  sprintf(s, "%s%s%s%s",
3145                          *tb ? " " : NullStr,
3146                          tb, *tb ? "  " : NullStr, pci->szFileName);
3147                  WinSetWindowText(hwndStatus2, s);
3148                }
3149                if (fMoreButtons)
3150                  WinSetWindowText(hwndName, pci->szFileName);
3151              }
3152            }
3153          }
3154        }
3155        break;
3156
3157      case CN_ENTER:
3158        if (mp2) {
3159
3160          PARCITEM pci = (PARCITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
3161
3162          if (pci) {
3163
3164            CHAR *s;
3165
3166            if ((pci->rc.flRecordAttr & CRA_INUSE) ||
3167                (pci->flags & (ARCFLAGS_REALDIR | ARCFLAGS_PSEUDODIR)))
3168              break;
3169            s = xstrdup(pci->szFileName, pszSrcFile, __LINE__);
3170            if (s) {
3171              if (!PostMsg(dcd->hwndObject, UM_ENTER, MPFROMP(s), MPVOID)) {
3172                Runtime_Error(pszSrcFile, __LINE__, "post");
3173                free(s);
3174              }
3175            }
3176          }
3177        }
3178        break;
3179      }
3180    }
3181    return 0;
3182
3183  case UM_FOLDUP:
3184    if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
3185      DosExit(EXIT_PROCESS, 1);
3186    return 0;
3187
3188  case UM_CLOSE:
3189    WinDestroyWindow(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
3190                                    QW_PARENT));
3191    return 0;
3192
3193  case WM_SAVEAPPLICATION:
3194    if (dcd && ParentIsDesktop(hwnd, dcd->hwndParent)) {
3195      SWP swp;
3196
3197      WinQueryWindowPos(dcd->hwndFrame, &swp);
3198      if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE | SWP_MAXIMIZE)))
3199        PrfWriteProfileData(fmprof, appname, "AV2SizePos", &swp, sizeof(swp));
3200    }
3201    break;
3202
3203  case WM_CLOSE:
3204    WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
3205    if (dcd)
3206      dcd->stopflag++;
3207    if (dcd && dcd->hwndObject) {
3208      if (!PostMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID))
3209        WinSendMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID);
3210    }
3211    // In case object window frees dcd
3212    dcd = WinQueryWindowPtr(hwnd, QWL_USER);
3213    if (!dcd ||
3214        (!dcd->dontclose &&
3215         !dcd->amextracted && ParentIsDesktop(hwnd, dcd->hwndParent))) {
3216      if (!PostMsg(hwnd, UM_FOLDUP, MPVOID, MPVOID))
3217        WinSendMsg(hwnd, UM_FOLDUP, MPVOID, MPVOID);
3218    }
3219    return 0;
3220
3221  case WM_DESTROY:
3222    if (ArcMenu)
3223      WinDestroyWindow(ArcMenu);
3224    if (ArcCnrMenu)
3225      WinDestroyWindow(ArcCnrMenu);
3226    ArcMenu = ArcCnrMenu = (HWND) 0;
3227    EmptyCnr(hwnd);
3228    break;
3229  }
3230  return dcd && dcd->oldproc ? dcd->oldproc(hwnd, msg, mp1, mp2) :
3231                               PFNWPCnr(hwnd, msg, mp1, mp2);
3232}
3233
3234HWND StartArcCnr(HWND hwndParent, HWND hwndCaller, CHAR * arcname, INT flags,
3235                 ARC_TYPE * sinfo)
3236{
3237  /*
3238   * bitmapped flags:
3239   *  1 = am extracted from another archive
3240   *  4 = don't kill proc on close
3241   */
3242
3243  HWND hwndFrame = (HWND) 0, hwndClient;
3244  ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
3245    FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE;
3246  USHORT id;
3247  DIRCNRDATA *dcd;
3248  ARC_TYPE *info = sinfo;
3249  CHAR title[MAXNAMEL + 1] = "AV/2 - ";
3250  CHAR fullname[CCHMAXPATH + 8], *p, temp;
3251  static USHORT idinc = 0;
3252
3253  if (!idinc)
3254    idinc = (rand() % 256);
3255  if (ParentIsDesktop(hwndParent, hwndParent))
3256    FrameFlags |= (FCF_TASKLIST | FCF_MENU);
3257  if (arcname) {
3258    DosError(FERR_DISABLEHARDERR);
3259    if (DosQueryPathInfo(arcname,
3260                         FIL_QUERYFULLNAME, fullname, sizeof(fullname)))
3261      strcpy(fullname, arcname);
3262    p = fullname;
3263    while (*p) {
3264      if (*p == '/')
3265        *p = '\\';
3266      p++;
3267    }
3268    if (!info)
3269      info = find_type(fullname, arcsighead);
3270    if (!info)
3271      return hwndFrame;
3272    if (strlen(title) + strlen(fullname) > MAXNAMEL) {
3273      p = title + strlen(title);
3274      strncpy(p, fullname, MAXNAMEL / 2 - 5);
3275      strcpy(p + MAXNAMEL / 2 - 5, "...");
3276      strcat(title, fullname + strlen(fullname) - (MAXNAMEL / 2 - 5));
3277    }
3278    else {
3279      strcat(title, fullname);
3280    }
3281    hwndFrame = WinCreateStdWindow(hwndParent,
3282                                   WS_VISIBLE,
3283                                   &FrameFlags,
3284                                   WC_ARCCONTAINER,
3285                                   title,
3286                                   WS_VISIBLE | fwsAnimate,
3287                                   FM3ModHandle, ARC_FRAME, &hwndClient);
3288    if (hwndFrame && hwndClient) {
3289      id = ARC_FRAME + idinc++;
3290      if (idinc > 512)
3291        idinc = 0;
3292      WinSetWindowUShort(hwndFrame, QWS_ID, id);
3293      dcd = xmallocz(sizeof(DIRCNRDATA), pszSrcFile, __LINE__);
3294      if (!dcd) {
3295        PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3296        hwndFrame = (HWND) 0;
3297      }
3298      else {
3299        dcd->size = sizeof(DIRCNRDATA);
3300        dcd->id = id;
3301        dcd->type = ARC_FRAME;
3302        save_dir2(dcd->workdir);
3303        if (dcd->workdir[strlen(dcd->workdir) - 1] != '\\')
3304          strcat(dcd->workdir, "\\");
3305        sprintf(dcd->workdir + strlen(dcd->workdir), "%s.%03x",
3306                ArcTempRoot, (clock() & 4095));
3307        strcpy(dcd->arcname, fullname);
3308        if (*extractpath) {
3309          if (!strcmp(extractpath, "*")) {
3310            p = strrchr(fullname, '\\');
3311            if (p) {
3312              if (p < fullname + 3)
3313                p++;
3314              temp = *p;
3315              *p = 0;
3316              strcpy(dcd->directory, fullname);
3317              *p = temp;
3318            }
3319          }
3320          else
3321            strcpy(dcd->directory, extractpath);
3322        }
3323        if (!*dcd->directory && *lastextractpath) {
3324          DosEnterCritSec();
3325          strcpy(dcd->directory, lastextractpath);
3326          DosExitCritSec();
3327        }
3328        if (!*dcd->directory) {
3329          if (!ParentIsDesktop(hwndParent, hwndParent))
3330            TopWindowName(hwndParent, hwndCaller, dcd->directory);
3331          if (!*dcd->directory) {
3332            p = strrchr(fullname, '\\');
3333            if (p) {
3334              if (p < fullname + 3)
3335                p++;
3336              *p = 0;
3337              strcpy(dcd->directory, fullname);
3338            }
3339          }
3340        }
3341        if (!*dcd->directory ||
3342            IsFile(dcd->directory) ||
3343            (isalpha(*dcd->directory) &&
3344             (driveflags[toupper(*dcd->directory) - 'A'] &
3345              DRIVE_NOTWRITEABLE)))
3346          save_dir2(dcd->directory);
3347        dcd->hwndParent = hwndParent ? hwndParent : HWND_DESKTOP;
3348        dcd->hwndFrame = hwndFrame;
3349        dcd->hwndClient = hwndClient;
3350        dcd->amextracted = (flags & 1) != 0;
3351        dcd->dontclose = (flags & 4) != 0;
3352        dcd->info = info;
3353        dcd->sortFlags = DefArcSortFlags;
3354        {
3355          PFNWP oldproc;
3356
3357          oldproc = WinSubclassWindow(hwndFrame, (PFNWP) ArcFrameWndProc);
3358          WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
3359        }
3360        dcd->hwndCnr = WinCreateWindow(hwndClient,
3361                                       WC_CONTAINER,
3362                                       NULL,
3363                                       CCS_AUTOPOSITION | CCS_MINIICONS |
3364                                       CCS_MINIRECORDCORE | ulCnrType |
3365                                       WS_VISIBLE,
3366                                       0,
3367                                       0,
3368                                       0,
3369                                       0,
3370                                       hwndClient,
3371                                       HWND_TOP, (ULONG) ARC_CNR, NULL, NULL);
3372        if (!dcd->hwndCnr) {
3373          Win_Error2(hwndClient, hwndClient, pszSrcFile, __LINE__,
3374                     IDS_WINCREATEWINDOW);
3375          PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3376          free(dcd);
3377          hwndFrame = (HWND) 0;
3378        }
3379        else {
3380          WinSetWindowPtr(dcd->hwndCnr, QWL_USER, (PVOID) dcd);
3381          dcd->oldproc = WinSubclassWindow(dcd->hwndCnr,
3382                                           (PFNWP) ArcCnrWndProc);
3383          {
3384            USHORT ids[] = { DIR_TOTALS, DIR_SELECTED, DIR_VIEW, DIR_SORT,
3385              DIR_FILTER, DIR_FOLDERICON, 0
3386            };
3387
3388            CommonCreateTextChildren(dcd->hwndClient,
3389                                     WC_ARCSTATUS, ids);
3390          }
3391          WinEnableWindow(WinWindowFromID(dcd->hwndClient, DIR_VIEW), FALSE);
3392          dcd->hwndExtract = WinCreateWindow(dcd->hwndClient,
3393                                             WC_ENTRYFIELD,
3394                                             NULL,
3395                                             ES_AUTOSCROLL,
3396                                             0,
3397                                             0,
3398                                             0,
3399                                             0,
3400                                             dcd->hwndClient,
3401                                             HWND_TOP,
3402                                             ARC_EXTRACTDIR, NULL, NULL);
3403          WinSendMsg(dcd->hwndExtract,
3404                     EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
3405          WinSetWindowText(dcd->hwndExtract, dcd->directory);
3406          if (!PostMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID))
3407            WinSendMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID);
3408          if (FrameFlags & FCF_MENU) {
3409            if (!fToolbar) {
3410              HWND hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
3411
3412              if (hwndMenu) {
3413                WinSendMsg(hwndMenu, MM_DELETEITEM,
3414                           MPFROM2SHORT(IDM_VIEW, FALSE), MPVOID);
3415                WinSendMsg(hwndMenu, MM_DELETEITEM,
3416                           MPFROM2SHORT(IDM_EXEC, FALSE), MPVOID);
3417                WinSendMsg(hwndMenu, MM_DELETEITEM,
3418                           MPFROM2SHORT(IDM_RESCAN, FALSE), MPVOID);
3419                WinSendMsg(hwndMenu, MM_DELETEITEM,
3420                           MPFROM2SHORT(IDM_DELETE, FALSE), MPVOID);
3421                WinSendMsg(hwndMenu, MM_DELETEITEM,
3422                           MPFROM2SHORT(IDM_EXTRACT, FALSE), MPVOID);
3423                WinSendMsg(hwndMenu, MM_DELETEITEM,
3424                           MPFROM2SHORT(IDM_TEST, FALSE), MPVOID);
3425                WinSendMsg(hwndMenu, MM_DELETEITEM,
3426                           MPFROM2SHORT(IDM_VIRUSSCAN, FALSE), MPVOID);
3427                WinSendMsg(hwndMenu, MM_DELETEITEM,
3428                           MPFROM2SHORT(IDM_WALKDIR, FALSE), MPVOID);
3429                WinSendMsg(hwndMenu, MM_DELETEITEM,
3430                           MPFROM2SHORT(IDM_FILTER, FALSE), MPVOID);
3431              }
3432            }
3433          }
3434          if (FrameFlags & FCF_TASKLIST) {
3435
3436            SWP swp, swpD;
3437            ULONG size = sizeof(swp);
3438            LONG cxScreen, cyScreen;
3439
3440            WinQueryTaskSizePos(WinQueryAnchorBlock(hwndFrame), 0, &swp);
3441            if (PrfQueryProfileData(fmprof,
3442                                    appname, "AV2SizePos", &swpD, &size)) {
3443              cxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
3444              cyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
3445              if (swp.x + swpD.cx > cxScreen)
3446                swp.x = cxScreen - swpD.cx;
3447              if (swp.y + swpD.cy > cyScreen)
3448                swp.y = cyScreen - swpD.cy;
3449              swp.cx = swpD.cx;
3450              swp.cy = swpD.cy;
3451            }
3452            WinSetWindowPos(hwndFrame,
3453                            HWND_TOP,
3454                            swp.x,
3455                            swp.y,
3456                            swp.cx,
3457                            swp.cy,
3458                            SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER |
3459                            SWP_ACTIVATE);
3460          }
3461        }
3462      }
3463    }
3464  }
3465  return hwndFrame;
3466}
Note: See TracBrowser for help on using the repository browser.