source: trunk/dll/arccnrs.c @ 740

Last change on this file since 740 was 740, checked in by Gregg Young, 13 years ago

Fixed file name display

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