source: trunk/dll/arccnrs.c @ 751

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

Sync rest of code with CNRITEM mods
Sync code with ARCITEM mods
Get compare dialog working
Still some issues with status display
Still some issues with directory sizes tree display
Heap check diagnostic code mostly enabled

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