source: trunk/dll/arccnrs.c @ 762

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

Use two pass logic to free CNRITEMs and ARCITEMs
Rename pszLongname to pszLongName
More compare directories rework
Make directory sizes item draw placement deterministic - how did it ever work?

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