source: trunk/dll/dircnrs.c @ 618

Last change on this file since 618 was 618, checked in by Steven Levine, 14 years ago

Add more drag/drop error checking
Use FreeDragInfoData?
Sync with NumItemsToUnhilite? AcceptOneDrop? GetOneDrop? mods

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