source: trunk/dll/dircnrs.c @ 730

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

Preliminary work on variable sized container buffers. Removes szFileName etc. Builds fine but traps.

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