source: trunk/dll/arccnrs.c @ 630

Last change on this file since 630 was 630, checked in by Gregg Young, 14 years ago

Improved fix of utility app path problem

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