source: trunk/dll/mainwnd.c @ 672

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

Use dcd->ulItemsToUnHilite
Sync UnHilite? calls with arg mods

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 154.8 KB
Line 
1
2/***********************************************************************
3
4  $Id: mainwnd.c 672 2007-05-13 05:57:48Z stevenhl $
5
6  fm/2 main window
7
8  Copyright (c) 1993-98 M. Kimes
9  Copyright (c) 2001, 2007 Steven H. Levine
10
11  11 Jun 02 SHL Drop obsolete xor code
12  16 Oct 02 SHL Handle large partitions
13  01 Aug 04 SHL Rework lstrip/rstrip usage
14  23 May 05 SHL Use QWL_USER
15  23 May 05 SHL Use datamin.h
16  25 May 05 SHL Use ULONGLONG and CommaFmtULL
17  26 May 05 SHL Comments and localize code
18  05 Jun 05 SHL Use QWL_USER
19  06 Jun 05 SHL Rework MainWMCommand for VAC3.65 compat
20  13 Aug 05 SHL Renames and comments
21  08 Dec 05 SHL DriveProc: disable menu items if drive not ready
22  17 Dec 05 SHL DriveProc: correct my stupid
23  29 May 06 SHL IDM_EDITANYARCHIVER: sanitize code
24  17 Jul 06 SHL Use Runtime_Error
25  17 Aug 06 SHL Complain nicer if state name does not exist
26  18 Feb 07 GKY More drive type and icon support
27  08 Mar 07 SHL SaveDirCnrState: do not save state of NOPRESCAN volumes
28  09 Mar 07 SHL RestoreDirCnrState/SaveDirCnrState: optimize and avoid overflows
29  30 Mar 07 GKY Remove GetPString for window class names
30  06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
31  06 Apr 07 GKY Add some error checking in drag/drop
32  15 Apr 07 SHL mainwnd MAIN_SETUPLIST restore state not found reporting
33  19 Apr 07 SHL Sync with AcceptOneDrop GetOneDrop mods
34  20 Apr 07 SHL Avoid spurious add_udir error reports
35  12 May 07 SHL Use dcd->ulItemsToUnHilite
36
37***********************************************************************/
38
39#define INCL_DOS
40#define INCL_WIN
41// #define INCL_WINERRORS
42#define INCL_SHLERRORS
43#define INCL_WINHELP
44#define INCL_GPI
45#define INCL_LONGLONG
46#include <os2.h>
47
48#include <stdarg.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <ctype.h>
53#include <share.h>
54
55#include "fm3dll.h"
56#include "fm3dlg.h"
57#include "fm3str.h"
58#include "tools.h"
59#include "datamin.h"
60
61#pragma data_seg(DATA1)
62
63static PSZ pszSrcFile = __FILE__;
64
65#pragma alloc_text(MISC8,SetToggleChecks,FindDirCnrByName,TopWindow)
66#pragma alloc_text(MISC8,TopWindowName,CountDirCnrs)
67#pragma alloc_text(MAINWND,AdjustSizeOfClient,FillClient,ChildButtonProc)
68#pragma alloc_text(MAINWND,ToolBackProc,StatusProc)
69#pragma alloc_text(MAINWND,MoveChildrenAwayFromTree,ArrangeIcons,NextChild)
70#pragma alloc_text(MAINWND,ChildFrameButtonProc)
71#pragma alloc_text(MAINWND2,CloseChildren,CountChildren,GetNextWindowPos)
72#pragma alloc_text(MAINWND2,CascadeChildren,TileChildren,ResizeChildren)
73#pragma alloc_text(MAINWND2,MinResChildren,MainFrameWndProc,MainWndProc)
74#pragma alloc_text(MAINWND2,DropDownListProc)
75#pragma alloc_text(MAINWND3,RestoreDirCnrState,SaveDirCnrState)
76#pragma alloc_text(MAINWND3,CloseDirCnrChildren,TransformSwp)
77#pragma alloc_text(MAINWND3,ResizeTools,BuildTools,CommandLineProc)
78#pragma alloc_text(MAINWND4,DriveProc,DriveBackProc,BuildDriveBarButtons,ResizeDrives)
79#pragma alloc_text(MAINWND4,LEDProc,IdealButtonProc)
80#pragma alloc_text(MAINWND5,MainWMOnce)
81#pragma alloc_text(MAINWND6,MainWMCommand)
82#pragma alloc_text(BUBBLE,MakeBubble,BubbleProc,BubbleHelp)
83#pragma alloc_text(MAINOBJ,MainObjectWndProc,MakeMainObjWin)
84
85static USHORT firsttool = 0;
86
87static BOOL CloseDirCnrChildren(HWND hwndClient);
88static BOOL RestoreDirCnrState(HWND hwndClient, PSZ pszStateName, BOOL noview);
89
90static MRESULT EXPENTRY MainObjectWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
91                                          MPARAM mp2)
92{
93  switch (msg) {
94  case UM_SETUP:
95  case UM_SETUP2:
96  case UM_SETUP3:
97  case UM_SETUP4:
98  case UM_SETUP5:
99    /*
100     * feed setup messages to main window
101     */
102    PostMsg(hwndMain, msg, mp1, mp2);
103    return 0;
104
105  case UM_SETUP6:
106    /*
107     * handle bubble help requests from drive bar buttons
108     */
109    {
110      char dv[3], d;
111      HWND hwndB = (HWND) mp1;
112      USHORT id;
113
114      id = WinQueryWindowUShort(hwndB, QWS_ID);
115      *dv = 0;
116      WinQueryWindowText(WinWindowFromID(WinQueryWindow(hwndB, QW_PARENT),
117                                         id + 50), sizeof(dv), dv);
118      d = toupper(*dv);
119      if (isalpha(d) && d > 'B' &&
120          !(driveflags[d - 'A'] & (DRIVE_CDROM | DRIVE_INVALID |
121                                   DRIVE_SLOW)) &&
122          (!hwndBubble ||
123           WinQueryWindowULong(hwndBubble, QWL_USER) != hwndB) &&
124          !WinQueryCapture(HWND_DESKTOP)) {
125
126        FSALLOCATE fsa;
127        CHAR s[90], szQty[38];
128        ULONG ulPctFree;
129        ULONGLONG ullFreeQty;
130
131        if (!DosQueryFSInfo((d - 'A') + 1,
132                            FSIL_ALLOC, &fsa, sizeof(FSALLOCATE))) {
133          ullFreeQty = (ULONGLONG) fsa.cUnitAvail *
134            (fsa.cSectorUnit * fsa.cbSector);
135          ulPctFree = (fsa.cUnit && fsa.cUnitAvail) ?
136            (fsa.cUnitAvail * 100) / fsa.cUnit : 0;
137          CommaFmtULL(szQty, sizeof(szQty), ullFreeQty, ' ');
138          sprintf(s, "%s (%lu%%) free", szQty, ulPctFree);
139        }
140        if ((!hwndBubble ||
141             WinQueryWindowULong(hwndBubble, QWL_USER) != hwndB) &&
142            !WinQueryCapture(HWND_DESKTOP))
143          WinSendMsg(hwndB, UM_SETUP6, MPFROMP(s), MPVOID);
144      }
145    }
146    return 0;
147
148  case UM_SETDIR:
149    {
150      CHAR s[8] = " :\\OS2";
151      ULONG bd;
152
153      if (DosQuerySysInfo(QSV_BOOT_DRIVE,
154                          QSV_BOOT_DRIVE,
155                          (PVOID) & bd, (ULONG) sizeof(ULONG)))
156        bd = 3L;
157      *s = (CHAR) bd + '@';
158      WinSendMsg(hwndMain, UM_SETDIR, MPFROMP(s), MPFROMLONG(1L));
159      if (!mp1) {
160        s[3] = 0;
161        WinSendMsg(hwndMain, UM_SETDIR, MPFROMP(s), MPVOID);
162      }
163      PostMsg(MainObjectHwnd, UM_RESTORE, MPFROMLONG(1L), MPFROMLONG(1L));
164    }
165    return 0;
166
167  case UM_RESTORE:
168    if (mp2) {
169      switch ((ULONG) mp2) {
170      case 1:
171        TileChildren(hwndMain, TRUE);
172        break;
173      case 2:
174        CloseDirCnrChildren(hwndMain);
175        break;
176      }
177    }
178    else {
179      fNoTileUpdate = TRUE;
180      WinEnableWindow(WinQueryWindow(hwndMain, QW_PARENT), FALSE);
181      RestoreDirCnrState(hwndMain, (char *)mp1, FALSE);
182      WinEnableWindow(WinQueryWindow(hwndMain, QW_PARENT), TRUE);
183      fNoTileUpdate = FALSE;
184      if (mp1)
185        free((char *)mp1);
186      if (fAutoTile)
187        TileChildren(hwndMain, TRUE);
188    }
189    return 0;
190
191  case UM_NOTIFY:
192    /*
193     * bring up notify messages for various windows
194     */
195    if (mp1)
196      return MRFROMLONG(DoNotify((char *)mp1));
197    return 0;
198
199  case WM_DESTROY:
200    if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
201      WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
202    break;
203  }
204  return WinDefWindowProc(hwnd, msg, mp1, mp2);
205}
206
207VOID MakeMainObjWin(VOID * args)
208{
209  HAB hab2;
210  HMQ hmq2;
211  QMSG qmsg2;
212
213  priority_bumped();
214  hab2 = WinInitialize(0);
215  if (hab2) {
216    hmq2 = WinCreateMsgQueue(hab2, 128);
217    if (hmq2) {
218      DosError(FERR_DISABLEHARDERR);
219      WinRegisterClass(hab2,
220                       (PSZ) WC_OBJECTWINDOW,
221                       MainObjectWndProc, 0, sizeof(PVOID));
222      MainObjectHwnd = WinCreateWindow(HWND_OBJECT,
223                                       WC_OBJECTWINDOW,
224                                       (PSZ) NULL,
225                                       0,
226                                       0L,
227                                       0L,
228                                       0L,
229                                       0L,
230                                       0L, HWND_TOP, OBJ_FRAME, NULL, NULL);
231      if (!MainObjectHwnd)
232        Win_Error2(HWND_OBJECT, HWND_DESKTOP, pszSrcFile, __LINE__,
233                   IDS_WINCREATEWINDOW);
234      else {
235        WinSetWindowPtr(MainObjectHwnd, QWL_USER, args);
236        while (WinGetMsg(hab2, &qmsg2, (HWND) 0, 0, 0))
237          WinDispatchMsg(hab2, &qmsg2);
238        WinDestroyWindow(MainObjectHwnd);
239      }
240      WinDestroyMsgQueue(hmq2);
241    }
242    WinTerminate(hab2);
243  }
244}
245
246static MRESULT EXPENTRY IdealButtonProc(HWND hwnd, ULONG msg, MPARAM mp1,
247                                        MPARAM mp2)
248{
249  switch (msg) {
250  case WM_MOUSEMOVE:
251    BubbleHelp(hwnd, TRUE, FALSE, FALSE, GetPString(IDS_IDEALBUTTONHELP));
252    break;
253  }
254  return PFNWPButton(hwnd, msg, mp1, mp2);
255}
256
257HWND TopWindow(HWND hwndParent, HWND exclude)
258{
259  HENUM henum;
260  HWND hwndC = (HWND) 0;
261  USHORT id;
262
263  if (hwndParent) {
264    henum = WinBeginEnumWindows(hwndMain);
265    while ((hwndC = WinGetNextWindow(henum)) != NULLHANDLE) {
266      if (hwndC != exclude) {
267        id = WinQueryWindowUShort(hwndC, QWS_ID);
268        if (id)
269          break;
270      }
271    }
272    WinEndEnumWindows(henum);
273  }
274  return hwndC;
275}
276
277HWND TopWindowName(HWND hwndParent, HWND exclude, CHAR * ret)
278{
279  HENUM henum;
280  HWND hwndC = (HWND) 0, hwndDir, hwndClient;
281  USHORT id;
282  PCNRITEM pci = NULL;
283
284  if (ret) {
285    *ret = 0;
286    if (hwndParent) {
287      henum = WinBeginEnumWindows(hwndMain);
288      while ((hwndC = WinGetNextWindow(henum)) != NULLHANDLE) {
289        // saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,"Tree = %lu\rExclude = %lu\rFound = %lu",hwndTree,exclude,hwndC);
290        if (hwndC != exclude && hwndC != hwndTree) {
291          id = WinQueryWindowUShort(hwndC, QWS_ID);
292          if (id) {
293            hwndClient = WinWindowFromID(hwndC, FID_CLIENT);
294            if (hwndClient) {
295              hwndDir = WinWindowFromID(hwndClient, DIR_CNR);
296              if (hwndDir) {
297                if (fLookInDir) {
298                  pci = (PCNRITEM) WinSendMsg(hwndDir,
299                                              CM_QUERYRECORDEMPHASIS,
300                                              MPFROMLONG(CMA_FIRST),
301                                              MPFROMSHORT(CRA_CURSORED));
302                  if (pci && (INT) pci != -1)
303                    break;
304                }
305                if (WinSendMsg(hwndClient,
306                               UM_CONTAINERDIR, MPFROMP(ret), MPVOID)) {
307                  MakeValidDir(ret);
308                  // saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,"Tree = %lu\rExclude = %lu\rFound = %lu\r\"%s\"",hwndTree,exclude,hwndC,ret);
309                  WinEndEnumWindows(henum);
310                  return hwndC;
311                }
312              }
313            }
314          }
315        }
316      }
317      WinEndEnumWindows(henum);
318      if (!pci || (INT) pci == -1) {
319        hwndC = hwndTree;
320        pci = (PCNRITEM) WinSendMsg(WinWindowFromID(WinWindowFromID(hwndTree,
321                                                                    FID_CLIENT),
322                                                    TREE_CNR),
323                                    CM_QUERYRECORDEMPHASIS,
324                                    MPFROMLONG(CMA_FIRST),
325                                    MPFROMSHORT(CRA_CURSORED));
326      }
327      if (pci && (INT) pci != -1) {
328        strcpy(ret, pci->szFileName);
329        MakeValidDir(ret);
330      }
331      else
332        save_dir2(ret);
333    }
334  }
335  return hwndC;
336}
337
338ULONG CountDirCnrs(HWND hwndParent)
339{
340  HENUM henum;
341  HWND hwndF = (HWND) 0, hwndC, hwndDir;
342  ULONG ret = 0;
343
344  henum = WinBeginEnumWindows(hwndParent);
345  while ((hwndF = WinGetNextWindow(henum)) != NULLHANDLE) {
346    hwndC = WinWindowFromID(hwndF, FID_CLIENT);
347    if (hwndC) {
348      hwndDir = WinWindowFromID(hwndC, DIR_CNR);
349      if (hwndDir)
350        ret++;
351    }
352  }
353  WinEndEnumWindows(henum);
354  return ret;
355}
356
357HWND FindDirCnrByName(CHAR * directory, BOOL restore)
358{
359  HENUM henum;
360  HWND hwndF = (HWND) 0, hwndC, hwndDir;
361  CHAR retstr[CCHMAXPATH];
362
363  if (hwndMain) {
364    henum = WinBeginEnumWindows(hwndMain);
365    while ((hwndF = WinGetNextWindow(henum)) != NULLHANDLE) {
366      hwndC = WinWindowFromID(hwndF, FID_CLIENT);
367      if (hwndC) {
368        hwndDir = WinWindowFromID(hwndC, DIR_CNR);
369        if (hwndDir) {
370          *retstr = 0;
371          WinSendMsg(hwndC, UM_CONTAINERDIR, MPFROMP(retstr), MPVOID);
372          if (*retstr && !stricmp(retstr, directory)) {
373            if (restore)
374              WinSetWindowPos(hwndF,
375                              HWND_TOP,
376                              0,
377                              0,
378                              0,
379                              0,
380                              SWP_RESTORE | SWP_SHOW |
381                              SWP_ACTIVATE | SWP_ZORDER);
382            break;
383          }
384        }
385      }
386    }
387    WinEndEnumWindows(henum);
388  }
389  return hwndF;
390}
391
392static VOID SetToggleChecks(HWND hwndMenu)
393{
394  WinCheckMenuItem(hwndMenu, IDM_TEXTTOOLS, fTextTools);
395  WinCheckMenuItem(hwndMenu, IDM_TOOLTITLES, fToolTitles);
396  WinCheckMenuItem(hwndMenu, IDM_USERLIST, fUserComboBox);
397  WinCheckMenuItem(hwndMenu, IDM_TOOLSUBMENU, fToolbar);
398  WinCheckMenuItem(hwndMenu, IDM_AUTOVIEWSUBMENU, fAutoView);
399  WinCheckMenuItem(hwndMenu, IDM_AUTOVIEWFILE, !fComments);
400  WinCheckMenuItem(hwndMenu, IDM_AUTOVIEWCOMMENTS, fComments);
401  WinCheckMenuItem(hwndMenu, IDM_MOREBUTTONS, fMoreButtons);
402  WinCheckMenuItem(hwndMenu, IDM_DRIVEBAR, fDrivebar);
403  WinCheckMenuItem(hwndMenu, IDM_AUTOTILE, fAutoTile);
404  WinCheckMenuItem(hwndMenu, IDM_TILEBACKWARDS, fTileBackwards);
405}
406
407static VOID ResizeTools(HWND hwnd)
408{
409  register ULONG butx = 18L;
410  INT attrib = SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER | SWP_NOREDRAW,
411    noattrib;
412  register TOOL *tool, *starttool;
413  SWP *swp;
414  register ULONG numtools, x;
415
416  if (!fToolbar)
417    return;
418  noattrib = attrib;
419  noattrib &= (~(SWP_SHOW | SWP_ZORDER));
420  noattrib |= SWP_HIDE;
421  /* count tools */
422  tool = toolhead;
423  for (numtools = 0L; tool; numtools++)
424    tool = tool->next;
425  /* allocate swp array for WinSetMultWindowPos */
426  swp = xmallocz(sizeof(SWP) * (numtools + 2), pszSrcFile, __LINE__);
427  if (swp) {
428    for (x = 0; x < numtools + 2L; x++) {
429      swp[x].hwndInsertBehind = HWND_TOP;
430      swp[x].fl = attrib;
431      swp[x].y = (fToolTitles) ? 14L : 3L;
432      swp[x].cx = 32L;
433      swp[x].cy = 32L;
434    }
435    swp[0].x = swp[1].x = 2L;
436    swp[0].y = (fTextTools) ? 14L : 18L;
437    swp[1].y = (fTextTools) ? 1L : 2L;
438    swp[0].cx = swp[1].cx = 14L;
439    swp[0].cy = swp[1].cy = 14L;
440    swp[0].hwnd = WinWindowFromID(hwnd, IDM_TOOLLEFT);
441    swp[1].hwnd = WinWindowFromID(hwnd, IDM_TOOLRIGHT);
442    x = 2L;
443    tool = find_tool(firsttool);
444    if (!tool)
445      tool = toolhead;
446    starttool = tool;
447    while (tool) {
448      if (!(tool->flags & T_INVISIBLE)) {
449        swp[x].x = butx;
450        if (fTextTools || (tool->flags & T_TEXT)) {
451          butx += 55L;
452          swp[x].cx = 54L;
453          swp[x].cy = 24L;
454          swp[x].y = 3L;
455        }
456        else
457          butx += 33L;
458        if (tool->flags & T_SEPARATOR)
459          butx += 12;
460      }
461      else
462        swp[x].fl = noattrib;
463      swp[x].hwnd = WinWindowFromID(hwnd, tool->id);
464      x++;
465      tool = tool->next;
466    }
467    tool = toolhead;
468    while (tool && tool != starttool) {
469      swp[x].x = butx;
470      if (!(tool->flags & T_INVISIBLE)) {
471        if (fTextTools || (tool->flags & T_TEXT)) {
472          butx += 55L;
473          swp[x].cx = 54L;
474          swp[x].cy = 24L;
475          swp[x].y = 3L;
476        }
477        else
478          butx += 33L;
479        if (tool->flags & T_SEPARATOR)
480          butx += 12;
481      }
482      else
483        swp[x].fl = noattrib;
484      swp[x].hwnd = WinWindowFromID(hwnd, tool->id);
485      x++;
486      tool = tool->next;
487    }
488    WinSetMultWindowPos(WinQueryAnchorBlock(hwnd), swp, numtools + 2L);
489    if (!fTextTools && fToolTitles) {
490      for (x = 2L; x < numtools + 2L; x++) {
491        if (fTextTools || !fToolTitles)
492          swp[x].fl = noattrib;
493        else {
494          tool = find_tool(WinQueryWindowUShort(swp[x].hwnd, QWS_ID));
495          if (tool && (tool->flags & T_TEXT))
496            swp[x].fl = noattrib;
497          else {
498            swp[x].hwndInsertBehind = HWND_TOP;
499            swp[x].y = 1L;
500            swp[x].cy = 10L;
501          }
502        }
503        swp[x].hwnd = WinWindowFromID(hwnd,
504                                      WinQueryWindowUShort(swp[x].hwnd,
505                                                           QWS_ID) + 25000);
506      }
507      WinSetMultWindowPos(WinQueryAnchorBlock(hwnd), &swp[2], numtools);
508    }
509    free(swp);
510  }
511  WinInvalidateRect(hwnd, NULL, TRUE);
512}
513
514static MRESULT EXPENTRY DropDownListProc(HWND hwnd, ULONG msg, MPARAM mp1,
515                                         MPARAM mp2)
516{
517  PFNWP oldproc = (PFNWP) INSTDATA(hwnd);
518  static HWND hwndMenu = (HWND) 0;
519  USHORT id;
520  static BOOL emphasized = FALSE;
521
522  switch (msg) {
523  case WM_MOUSEMOVE:
524    shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
525    break;
526
527  case WM_CHAR:
528    shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
529    break;
530
531  case WM_MENUEND:
532    if (hwndMenu == (HWND) mp2) {
533      WinDestroyWindow(hwndMenu);
534      hwndMenu = (HWND) 0;
535    }
536    break;
537
538  case WM_CONTEXTMENU:
539    {
540      MRESULT ret = MRFROMSHORT(TRUE);
541
542      if (hwndMenu)
543        WinDestroyWindow(hwndMenu);
544      hwndMenu = (HWND) 0;
545      id = WinQueryWindowUShort(WinQueryWindow(hwnd, QW_PARENT), QWS_ID);
546      switch (id) {
547      case MAIN_CMDLIST:
548        WinPostMsg(WinWindowFromID(WinQueryWindow(WinQueryWindow(hwnd,
549                                                                 QW_PARENT),
550                                                  QW_PARENT),
551                                   FID_CLIENT),
552                   WM_COMMAND, MPFROM2SHORT(IDM_EDITCOMMANDS, 0), MPVOID);
553        break;
554      case MAIN_USERLIST:
555      case MAIN_SETUPLIST:
556        hwndMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
557        if (hwndMenu)
558          PopupMenu(hwnd,
559                    WinWindowFromID(WinQueryWindow(WinQueryWindow(hwnd,
560                                                                  QW_PARENT),
561                                                   QW_PARENT),
562                                    FID_CLIENT), hwndMenu);
563        break;
564      default:
565        ret = FALSE;
566        break;
567      }
568      return ret;
569    }
570
571  case WM_CONTROL:
572    if (hwndStatus2) {
573      switch (SHORT1FROMMP(mp1)) {
574      case CBID_EDIT:
575        id = WinQueryWindowUShort(hwnd, QWS_ID);
576        switch (SHORT2FROMMP(mp1)) {
577        case EN_SETFOCUS:
578          switch (id) {
579          case MAIN_CMDLIST:
580            WinSetWindowText(hwndStatus2, GetPString(IDS_CMDLISTHELP));
581            break;
582          case MAIN_SETUPLIST:
583            WinSetWindowText(hwndStatus2, GetPString(IDS_SETUPLISTHELP));
584            break;
585          case MAIN_USERLIST:
586            WinSetWindowText(hwndStatus2, GetPString(IDS_USERLISTHELP));
587            break;
588          case MAIN_DRIVELIST:
589            WinSetWindowText(hwndStatus2, GetPString(IDS_DRIVELISTHELP));
590            break;
591          case MAIN_BUTTONLIST:
592            WinSetWindowText(hwndStatus2, GetPString(IDS_BUTTONLISTHELP));
593            break;
594          default:
595            break;
596          }
597          break;
598
599        default:
600          break;
601        }
602      }
603      break;
604
605  default:
606      break;
607    }
608    break;
609
610  case WM_BEGINDRAG:
611    id = WinQueryWindowUShort(hwnd, QWS_ID);
612    // saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,"%u %s %u",id,(id == CBID_EDIT) ? "TRUE" : "FALSE",WinQueryWindowUShort(WinQueryWindow(hwnd,QW_PARENT),QWS_ID) == MAIN_USERLIST);
613    if (id == CBID_EDIT &&
614        WinQueryWindowUShort(WinQueryWindow(hwnd, QW_PARENT), QWS_ID) ==
615        MAIN_USERLIST) {
616
617      CHAR path[CCHMAXPATH];
618
619      *path = 0;
620      WinQueryWindowText(hwnd, CCHMAXPATH, path);
621      bstrip(path);
622      // saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,"Dragging: %s",path);
623      if (*path && !IsRoot(path))
624        DragOne(hwnd, (HWND) 0, path, FALSE);
625      return 0;
626    }
627    break;
628
629  case DM_DRAGOVER:
630    id = WinQueryWindowUShort(WinQueryWindow(hwnd, QW_PARENT), QWS_ID);
631    if (id == MAIN_USERLIST) {
632      if (!emphasized) {
633        emphasized = TRUE;
634        DrawTargetEmphasis(hwnd, emphasized);
635      }
636      if (AcceptOneDrop(hwnd, mp1, mp2))
637        return MRFROM2SHORT(DOR_DROP, DO_MOVE);
638      return MRFROM2SHORT(DOR_NEVERDROP, 0);
639    }
640    break;
641
642  case DM_DRAGLEAVE:
643    id = WinQueryWindowUShort(WinQueryWindow(hwnd, QW_PARENT), QWS_ID);
644    if (id == MAIN_USERLIST) {
645      if (emphasized) {
646        emphasized = FALSE;
647        DrawTargetEmphasis(hwnd, emphasized);
648      }
649    }
650    break;
651
652  case DM_DROPHELP:
653    id = WinQueryWindowUShort(WinQueryWindow(hwnd, QW_PARENT), QWS_ID);
654    if (id == MAIN_USERLIST) {
655      DropHelp(mp1, mp2, hwnd, GetPString(IDS_USERLISTDROPHELP));
656      return 0;
657    }
658    break;
659
660  case DM_DROP:
661    id = WinQueryWindowUShort(WinQueryWindow(hwnd, QW_PARENT), QWS_ID);
662    if (id == MAIN_USERLIST) {
663
664      char szFrom[CCHMAXPATH + 2];
665
666      if (emphasized) {
667        emphasized = FALSE;
668        DrawTargetEmphasis(hwnd, emphasized);
669      }
670      if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom))) {
671        MakeValidDir(szFrom);
672        WinSetWindowText(hwnd, szFrom);
673        PostMsg(WinWindowFromID(WinQueryWindow(WinQueryWindow(hwnd,
674                                                              QW_PARENT),
675                                               QW_PARENT),
676                                FID_CLIENT),
677                UM_COMMAND, MPFROM2SHORT(IDM_ADDTOUSERLIST, 0), MPVOID);
678        return 0;
679      }
680    }
681    break;
682
683  case WM_DESTROY:
684    if (hwndMenu)
685      WinDestroyWindow(hwndMenu);
686    hwndMenu = (HWND) 0;
687    break;
688  }
689
690  return oldproc(hwnd, msg, mp1, mp2);
691}
692
693void BubbleHelp(HWND hwnd, BOOL other, BOOL drive, BOOL above, char *help)
694{
695  if (help && *help &&
696      ((drive && fDrivebarHelp) ||
697       (other && fOtherHelp) || (!other && !drive && fToolbarHelp))) {
698    if ((!hwndBubble ||
699         WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
700        !WinQueryCapture(HWND_DESKTOP))
701      MakeBubble(hwnd, above, help);
702  }
703}
704
705VOID MakeBubble(HWND hwnd, BOOL above, CHAR * help)
706{
707  if (!hwnd || !help || !*help)
708    return;
709
710  if (hwndBubble)
711    WinDestroyWindow(hwndBubble);
712
713  {
714    HWND hwndActive;
715    char ucClassname[8];
716
717    hwndActive = WinQueryActiveWindow(HWND_DESKTOP);
718    if (hwndActive) {
719      /* don't bring up help if window isn't active */
720      if (!WinIsChild(hwnd, hwndActive))
721        return;
722    }
723    hwndActive = WinQueryFocus(HWND_DESKTOP);
724    if (WinQueryClassName(hwndActive, sizeof(ucClassname), ucClassname)) {
725      /* don't bring up help if a menu is active */
726      if (!strcmp(ucClassname, "#4"))
727        return;
728    }
729  }
730
731  hwndBubble = WinCreateWindow(HWND_DESKTOP,
732                               WC_BUBBLE,
733                               help,
734                               WS_CLIPSIBLINGS | SS_TEXT |
735                               DT_CENTER | DT_VCENTER,
736                               0,
737                               0,
738                               0,
739                               0,
740                               HWND_DESKTOP, HWND_TOP, MAIN_HELP, NULL, NULL);
741  if (!hwndBubble)
742    Win_Error2(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
743               IDS_WINCREATEWINDOW);
744  else {
745    HPS hps;
746    POINTL aptl[TXTBOX_COUNT], ptl, tptl;
747    LONG lxScreen, sx, sy, extra = 0, lyScreen;
748    char *p, *pp, *wp;
749    SWP swp;
750
751    WinQueryWindowPos(hwnd, &swp);
752    lyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
753    lxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
754    WinSetWindowULong(hwndBubble, QWL_USER, hwnd);
755    SetPresParams(hwndBubble, NULL, NULL, NULL, GetPString(IDS_8HELVTEXT));
756    hps = WinGetPS(hwndBubble);
757    p = help;
758    tptl.x = tptl.y = 0;
759    while (p && *p) {
760      wp = NULL;
761      pp = strchr(p, '\r');
762      if (pp) {
763        wp = pp;
764        *pp = 0;
765        pp++;
766      }
767      GpiQueryTextBox(hps, strlen(p), p, TXTBOX_COUNT, aptl);
768      tptl.x = max(aptl[TXTBOX_TOPRIGHT].x, tptl.x);
769      if (tptl.y)
770        tptl.y += extra;
771      else
772        extra = aptl[TXTBOX_TOPLEFT].y / 4;
773      tptl.y += aptl[TXTBOX_TOPLEFT].y;
774      if (wp)
775        *wp = '\r';
776      p = pp;
777    }
778    WinSetWindowULong(hwndBubble, QWL_USER + 4, extra);
779    WinReleasePS(hps);
780    ptl.x = ptl.y = 0;
781    WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptl, 1);
782    if (above) {
783      sy = ptl.y + swp.cy + 4;
784      if (sy + tptl.y + 12 > lyScreen) {
785        above = FALSE;
786        sy = ptl.y - (tptl.y + 14);
787      }
788    }
789    else
790      sy = ptl.y - (tptl.y + 14);
791    if (ptl.x > (lxScreen / 2))
792      sx = (ptl.x - tptl.x) - 16;
793    else
794      sx = ptl.x + (54 * (above == FALSE)) + 2;
795    if (sx < 0)
796      sx = 0;
797    if (sx + tptl.x + 14 > lxScreen)
798      sx = lxScreen - (tptl.x + 14);
799    if (sy < 0) {
800      sy = ptl.y + swp.cy + 4;
801      if (sy + tptl.y + 12 > lyScreen)
802        sy = 0;
803    }
804    WinSetWindowPos(hwndBubble, HWND_TOP, sx, sy,
805                    tptl.x + 14,
806                    tptl.y + 12,
807                    SWP_DEACTIVATE | SWP_SHOW | SWP_ZORDER |
808                    SWP_MOVE | SWP_SIZE);
809  }
810}
811
812MRESULT EXPENTRY BubbleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
813{
814  switch (msg) {
815  case WM_SETFOCUS:
816    if (mp2)
817      PostMsg(hwnd, UM_FOCUSME, mp1, MPVOID);
818    break;
819
820  case UM_FOCUSME:
821    WinSetFocus(HWND_DESKTOP, (HWND) mp1);
822    return 0;
823
824  case WM_MOUSEMOVE:
825    WinShowWindow(hwnd, FALSE);
826    break;
827
828  case UM_TIMER:
829    {
830      POINTL ptl;
831
832      WinQueryPointerPos(HWND_DESKTOP, &ptl);
833      if (WinWindowFromPoint(HWND_DESKTOP, &ptl, TRUE) !=
834          WinQueryWindowULong(hwnd, QWL_USER) || !WinIsWindowVisible(hwnd))
835        WinDestroyWindow(hwnd);
836    }
837    return 0;
838
839  case WM_PAINT:
840    {
841      HPS hps;
842      SWP swp;
843      POINTL ptl, aptl[TXTBOX_COUNT];
844      CHAR *s, *p, *pp, *wp;
845      ULONG extra, tlen, y;
846
847      hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
848      if (hps) {
849        WinQueryWindowPos(hwnd, &swp);
850        GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, 0);
851        GpiSetColor(hps, ((255 << 16) | (255 << 8) | 198));
852        GpiSetBackMix(hps, BM_LEAVEALONE);
853        GpiSetMix(hps, FM_OVERPAINT);
854        ptl.x = ptl.y = 0;
855        GpiMove(hps, &ptl);
856        ptl.x = swp.cx - 1;
857        ptl.y = swp.cy - 1;
858        GpiBox(hps, DRO_OUTLINEFILL, &ptl, 0, 0);
859        tlen = WinQueryWindowTextLength(hwnd);
860        if (tlen) {
861          s = xmalloc(tlen + 2, pszSrcFile, __LINE__);
862          if (s) {
863            WinQueryWindowText(hwnd, tlen + 1, s);
864            if (*s) {
865              p = s;
866              y = swp.cy - 3;
867              extra = WinQueryWindowULong(hwnd, QWL_USER + 4);
868              GpiSetColor(hps, 0);
869              GpiSetMix(hps, FM_OVERPAINT);
870              while (p && *p) {
871                wp = NULL;
872                pp = strchr(p, '\r');
873                if (pp) {
874                  wp = pp;
875                  *pp = 0;
876                  pp++;
877                }
878                GpiQueryTextBox(hps, strlen(p), p, TXTBOX_COUNT, aptl);
879                ptl.x = 7;
880                y -= aptl[TXTBOX_TOPLEFT].y;
881                if (p != s)
882                  y -= extra;
883                ptl.y = y;
884                GpiCharStringAt(hps, &ptl, strlen(p), p);
885                if (wp)
886                  *wp = '\r';
887                p = pp;
888              }
889            }
890            free(s);
891          }
892        }
893        if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE)) && swp.cx > 6 && swp.cy > 6) {
894          GpiSetColor(hps, CLR_WHITE);
895          ptl.x = 1;
896          ptl.y = 1;
897          GpiMove(hps, &ptl);
898          ptl.y = swp.cy - 2;
899          GpiLine(hps, &ptl);
900          ptl.x = swp.cx - 2;
901          GpiLine(hps, &ptl);
902          ptl.x = 2;
903          ptl.y = 2;
904          GpiMove(hps, &ptl);
905          ptl.y = swp.cy - 3;
906          GpiLine(hps, &ptl);
907          ptl.x = swp.cx - 3;
908          GpiLine(hps, &ptl);
909          GpiSetColor(hps, CLR_BROWN);
910          ptl.x = 1;
911          ptl.y = 1;
912          GpiMove(hps, &ptl);
913          ptl.x = swp.cx - 2;
914          GpiLine(hps, &ptl);
915          ptl.y = swp.cy - 2;
916          GpiLine(hps, &ptl);
917          ptl.x = 2;
918          ptl.y = 2;
919          GpiMove(hps, &ptl);
920          ptl.x = swp.cx - 3;
921          GpiLine(hps, &ptl);
922          ptl.y = swp.cy - 3;
923          GpiLine(hps, &ptl);
924        }
925        WinEndPaint(hps);
926      }
927    }
928    return 0;
929
930  case WM_CLOSE:
931    WinDestroyWindow(hwnd);
932    return 0;
933
934  case WM_DESTROY:
935    hwndBubble = (HWND) 0;
936    break;
937  }
938  return PFNWPStatic(hwnd, msg, mp1, mp2);
939}
940
941MRESULT EXPENTRY LEDProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
942{
943  switch (msg) {
944  case WM_CREATE:
945    {
946      MRESULT mr = PFNWPStatic(hwnd, msg, mp1, mp2);
947      HBITMAP hbmold = (HBITMAP) 0;
948      HPS hps = (HPS) 0;
949
950      switch (WinQueryWindowUShort(hwnd, QWS_ID)) {
951      case MAIN_LED:
952        hps = WinGetPS(hwnd);
953        hbmold = (HBITMAP) WinSendMsg(hwnd, SM_QUERYHANDLE, MPVOID, MPVOID);
954        if (!fBlueLED) {
955          hbmLEDon = GpiLoadBitmap(hps, 0, LEDON_BMP, 12, 12);
956          hbmLEDoff = GpiLoadBitmap(hps, 0, LEDOFF_BMP, 12, 12);
957        }
958        else {
959          hbmLEDon = GpiLoadBitmap(hps, 0, LEDON2_BMP, 12, 12);
960          hbmLEDoff = GpiLoadBitmap(hps, 0, LEDOFF2_BMP, 12, 12);
961        }
962        if (hbmLEDoff && hbmLEDon)
963          WinSendMsg(hwnd, SM_SETHANDLE, MPFROMLONG(hbmLEDoff), MPVOID);
964        else {
965          if (hbmLEDoff)
966            GpiDeleteBitmap(hbmLEDoff);
967          if (hbmLEDon)
968            GpiDeleteBitmap(hbmLEDon);
969        }
970        if (hbmold &&
971            hbmLEDon &&
972            hbmLEDoff && hbmold != hbmLEDon && hbmold != hbmLEDoff)
973          GpiDeleteBitmap(hbmold);
974        if (hps)
975          WinReleasePS(hps);
976        break;
977      default:
978        SetPresParams(hwnd,
979                      &RGBGREY,
980                      &RGBBLACK, &RGBGREY, GetPString(IDS_6HELVTEXT));
981        break;
982      }
983      return mr;
984    }
985
986  case WM_SETFOCUS:
987    if (mp2)
988      PostMsg(hwnd, UM_FOCUSME, mp1, MPVOID);
989    break;
990
991  case UM_FOCUSME:
992    WinSetFocus(HWND_DESKTOP, (HWND) mp1);
993    return 0;
994
995  case WM_MOUSEMOVE:
996    BubbleHelp(hwnd, TRUE, FALSE, FALSE, GetPString(IDS_LEDHELP));
997    if (!fNoFinger) {
998      WinSetPointer(HWND_DESKTOP, hptrFinger);
999      return MRFROMLONG(TRUE);
1000    }
1001    break;
1002
1003  case WM_BUTTON1CLICK:
1004    PostMsg(WinQueryWindow(hwnd, QW_PARENT),
1005            WM_COMMAND, MPFROM2SHORT(IDM_SHOWNOTEWND, 0), MPVOID);
1006    break;
1007
1008  case WM_BUTTON2CLICK:
1009    PostMsg(WinQueryWindow(hwnd, QW_PARENT),
1010            WM_COMMAND, MPFROM2SHORT(IDM_HIDENOTEWND, 0), MPVOID);
1011    break;
1012
1013  case WM_CHORD:
1014  case WM_BUTTON3CLICK:
1015    PostMsg(WinQueryWindow(hwnd, QW_PARENT),
1016            WM_COMMAND, MPFROM2SHORT(IDM_WINDOWDLG, 0), MPVOID);
1017    break;
1018  }
1019  return PFNWPStatic(hwnd, msg, mp1, mp2);
1020}
1021
1022MRESULT EXPENTRY ChildButtonProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1023{
1024  USHORT id;
1025  TOOL *tool;
1026  DIRCNRDATA *dcd;
1027
1028  static HWND hwndMenu = (HWND) 0;
1029
1030  switch (msg) {
1031  case WM_BUTTON1DOWN:
1032  case WM_BUTTON2DOWN:
1033  case WM_BUTTON3DOWN:
1034    shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
1035    break;
1036
1037  case WM_MOUSEMOVE:
1038    if (fToolbarHelp) {
1039      if ((!hwndBubble || WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd)
1040          && !WinQueryCapture(HWND_DESKTOP)) {
1041        id = WinQueryWindowUShort(hwnd, QWS_ID);
1042        tool = find_tool(id);
1043        if (tool && tool->help && *tool->help) {
1044
1045          char s[128];
1046
1047          strcpy(s, tool->help);
1048          if (tool->flags & T_DROPABLE)
1049            strcat(s, GetPString(IDS_DROPONMETEXT));
1050          MakeBubble(hwnd, FALSE, s);
1051        }
1052      }
1053    }
1054    break;
1055
1056  case WM_COMMAND:
1057    switch (SHORT1FROMMP(mp1)) {
1058    case IDM_HELP:
1059      if (hwndHelp)
1060        WinSendMsg(hwndHelp,
1061                   HM_DISPLAY_HELP,
1062                   MPFROM2SHORT(HELP_TOOLBAR, 0), MPFROMSHORT(HM_RESOURCEID));
1063      break;
1064
1065    case IDM_HIDEANYTOOL:               /* hide any tool */
1066    case IDM_HIDETOOL:                  /* hide tool */
1067      if (SHORT1FROMMP(mp1) == IDM_HIDETOOL)
1068        id = WinQueryWindowUShort(hwnd, QWS_ID);
1069      else
1070        id = (USHORT) WinDlgBox(HWND_DESKTOP, hwnd,
1071                                PickToolProc, FM3ModHandle,
1072                                PICKBTN_FRAME, GetPString(IDS_HIDETEXT));
1073      if (id) {
1074        tool = find_tool(id);
1075        if (tool) {
1076          tool->flags |= T_INVISIBLE;
1077          fToolsChanged = TRUE;
1078        }
1079      }
1080      break;
1081
1082    case IDM_SHOWTOOLS:                 /* show all tools */
1083      tool = toolhead;
1084      while (tool) {
1085        tool->flags &= (~T_INVISIBLE);
1086        tool = tool->next;
1087        fToolsChanged = TRUE;
1088      }
1089      break;
1090
1091    case IDM_DELETEANYTOOL:             /* delete any button */
1092    case IDM_DELETETOOL:                /* delete button */
1093      if (SHORT1FROMMP(mp1) == IDM_DELETETOOL)
1094        id = WinQueryWindowUShort(hwnd, QWS_ID);
1095      else
1096        id =
1097          (USHORT) WinDlgBox(HWND_DESKTOP, hwnd, PickToolProc, FM3ModHandle,
1098                             PICKBTN_FRAME, GetPString(IDS_DELETETEXT));
1099      if (id)
1100        PostMsg(WinQueryWindow(hwnd, QW_PARENT), UM_SETUP,
1101                MPFROM2SHORT(id, 0), MPVOID);
1102      return 0;
1103
1104    case IDM_EDITANYTOOL:               /* edit any button */
1105    case IDM_EDITTOOL:                  /* edit button */
1106      if (SHORT1FROMMP(mp1) == IDM_EDITTOOL)
1107        id = WinQueryWindowUShort(hwnd, QWS_ID);
1108      else
1109        id =
1110          (USHORT) WinDlgBox(HWND_DESKTOP, hwnd, PickToolProc, FM3ModHandle,
1111                             PICKBTN_FRAME, GetPString(IDS_EDITTEXT));
1112      if (id) {
1113        tool = find_tool(id);
1114        if (tool) {
1115          if (WinDlgBox(HWND_DESKTOP, hwnd, AddToolProc, FM3ModHandle,
1116                        ADDBTN_FRAME, (PVOID) tool))
1117            WinSendMsg(WinWindowFromID(WinQueryWindow(WinQueryWindow(hwnd,
1118                                                                     QW_PARENT),
1119                                                      QW_PARENT), FID_CLIENT),
1120                       WM_COMMAND, MPFROM2SHORT(IDM_CREATETOOL, 0),
1121                       MPFROM2SHORT(id, 0));
1122        }
1123      }
1124      break;
1125
1126    case IDM_ADDTOOL:                   /* add tool */
1127      id = (USHORT) WinDlgBox(HWND_DESKTOP, hwnd, AddToolProc, FM3ModHandle,
1128                              ADDBTN_FRAME, MPVOID);
1129      if (id && id != (USHORT) - 1)
1130        WinSendMsg(WinWindowFromID(WinQueryWindow(WinQueryWindow(hwnd,
1131                                                                 QW_PARENT),
1132                                                  QW_PARENT), FID_CLIENT),
1133                   WM_COMMAND, MPFROM2SHORT(IDM_CREATETOOL, 0),
1134                   MPFROM2SHORT(id, 0));
1135      break;
1136
1137    case IDM_REORDERTOOLS:              /* reorder tools */
1138      WinDlgBox(HWND_DESKTOP,
1139                hwnd, ReOrderToolsProc, FM3ModHandle, RE_FRAME, MPVOID);
1140      break;
1141
1142    case IDM_SAVETOOLS:
1143    case IDM_LOADTOOLS:
1144      if (WinDlgBox(HWND_DESKTOP,
1145                    hwnd,
1146                    ToolIODlgProc,
1147                    FM3ModHandle,
1148                    SVBTN_FRAME,
1149                    (PVOID) (SHORT1FROMMP(mp1) == IDM_SAVETOOLS) ?
1150                    "TRUE" : NULL))
1151        BuildTools(hwndToolback, TRUE);
1152      break;
1153    }
1154    ResizeTools(WinQueryWindow(hwnd, QW_PARENT));
1155    return 0;
1156
1157  case WM_MENUEND:
1158    if (hwndMenu == (HWND) mp2) {
1159      WinDestroyWindow(hwndMenu);
1160      hwndMenu = (HWND) 0;
1161    }
1162    break;
1163
1164  case WM_CONTEXTMENU:
1165    DosEnterCritSec();
1166    if (!hwndMenu)
1167      hwndMenu = WinLoadMenu(hwnd, FM3ModHandle, ID_BUTTONMENU);
1168    DosExitCritSec();
1169    SetPresParams(hwndMenu, NULL, NULL, NULL, GetPString(IDS_10SYSPROTEXT));
1170    if (PopupMenu(hwnd, hwnd, hwndMenu))
1171      WinShowWindow(hwndMenu, TRUE);
1172    return MRFROMSHORT(TRUE);
1173
1174  case DM_DRAGOVER:
1175    {
1176      PDRAGINFO pDInfo;                 /* Pointer to DRAGINFO */
1177
1178      pDInfo = (PDRAGINFO) mp1;         /* Get DRAGINFO pointer */
1179      DrgAccessDraginfo(pDInfo);        /* Access DRAGINFO */
1180      id = WinQueryWindowUShort(hwnd, QWS_ID);
1181      tool = find_tool(id);
1182      if (!tool) {
1183        DrgFreeDraginfo(pDInfo);
1184        return (MRFROM2SHORT(DOR_NEVERDROP, 0));        /* Drop not valid */
1185      }
1186      if (!(tool->flags & T_DROPABLE)) {
1187        DrgFreeDraginfo(pDInfo);
1188        return (MRFROM2SHORT(DOR_NEVERDROP, 0));        /* Drop not valid */
1189      }
1190      {
1191        PDRAGITEM pDItem;               /* Pointer to DRAGITEM */
1192
1193        pDItem = DrgQueryDragitemPtr(pDInfo,    /* Access DRAGITEM */
1194                                     0);        /* Index to DRAGITEM */
1195        if (DrgVerifyRMF(pDItem,        /* Check valid rendering */
1196                         DRM_OS2FILE,   /* mechanisms and data */
1197                         NULL)) {       /* formats */
1198          if (!(tool->flags & T_EMPHASIZED)) {
1199            tool->flags |= T_EMPHASIZED;
1200            DrawTargetEmphasis(hwnd, ((tool->flags & T_EMPHASIZED) != 0));
1201            DrgFreeDraginfo(pDInfo);
1202          }
1203          return (MRFROM2SHORT(DOR_DROP,        /* Return okay to drop */
1204                               DO_MOVE));       /* Move operation valid */
1205        }
1206        DrgFreeDraginfo(pDInfo);
1207      }
1208    }
1209    return (MRFROM2SHORT(DOR_NEVERDROP, 0));    /* Drop not valid */
1210
1211  case DM_DROPHELP:
1212    id = WinQueryWindowUShort(hwnd, QWS_ID);
1213    tool = find_tool(id);
1214    PFNWPButton(hwnd, msg, mp1, mp2);
1215    DropHelp(mp1, mp2, hwnd, GetPString(IDS_TOOLDROPHELP));
1216    return 0;
1217
1218  case DM_DRAGLEAVE:
1219    id = WinQueryWindowUShort(hwnd, QWS_ID);
1220    tool = find_tool(id);
1221    if (tool && (tool->flags & T_DROPABLE)) {
1222      if (tool->flags & T_EMPHASIZED) {
1223        tool->flags &= (~T_EMPHASIZED);
1224        DrawTargetEmphasis(hwnd, ((tool->flags & T_EMPHASIZED) != 0));
1225      }
1226    }
1227    break;
1228
1229  case DM_DROP:
1230    id = WinQueryWindowUShort(hwnd, QWS_ID);
1231    tool = find_tool(id);
1232    if (tool && (tool->flags & T_DROPABLE) != 0) {
1233      LISTINFO *li;
1234      CNRDRAGINFO cdi;
1235
1236      if (tool->flags & T_EMPHASIZED) {
1237        DrawTargetEmphasis(hwnd, ((tool->flags & T_EMPHASIZED) != 0));
1238        tool->flags &= (~T_EMPHASIZED);
1239      }
1240      memset(&cdi, 0, sizeof(cdi));
1241      cdi.pDragInfo = mp1;
1242      li = DoFileDrop(hwnd, NULL, FALSE, mp1, MPFROMP(&cdi));
1243      dcd = INSTDATA(cdi.pDragInfo->hwndSource);
1244      if (dcd->ulItemsToUnHilite) {
1245        saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
1246               hwnd,
1247               GetPString(IDS_ERRORTEXT),
1248               GetPString(IDS_EXCEEDPMDRGLMT));
1249      }
1250      if (li) {
1251        li->type = id;
1252        if (!li->list || !li->list[0])
1253          FreeListInfo(li);
1254        else {
1255          HWND hwndActive;
1256
1257          hwndActive = TopWindow(hwndMain, (HWND) 0);
1258          if (hwndActive) {
1259            if (!WinSendMsg(hwndActive, UM_COMMAND, MPFROMP(li), MPVOID))
1260              FreeListInfo(li);
1261          }
1262          else
1263            FreeListInfo(li);
1264        }
1265      }
1266    }
1267    return 0;
1268
1269  case WM_CLOSE:
1270    WinDestroyWindow(hwnd);
1271    return 0;
1272  }
1273  return PFNWPButton(hwnd, msg, mp1, mp2);
1274}
1275
1276VOID BuildTools(HWND hwndT, BOOL resize)
1277{
1278  TOOL *tool;
1279  ULONG ctrlxpos = 18L;
1280  CHAR s[33];
1281  HENUM henum;
1282  HWND hwndTool;
1283
1284  henum = WinBeginEnumWindows(hwndT);
1285  while ((hwndTool = WinGetNextWindow(henum)) != NULLHANDLE)
1286    WinDestroyWindow(hwndTool);
1287  WinEndEnumWindows(henum);
1288  if (!fToolbar) {
1289    load_quicktools();
1290    load_tools(NULL);
1291    return;
1292  }
1293  if (!toolhead)
1294    load_tools(NULL);
1295  tool = toolhead;
1296  while (tool) {
1297    sprintf(s, "#%u", tool->id);
1298    hwndTool = (HWND) 0;
1299    if (!fTextTools) {
1300      if (!(tool->flags & T_MYICON)) {
1301        hwndTool = WinCreateWindow(hwndT,
1302                                   WC_TOOLBUTTONS,
1303                                   s,
1304                                   BS_NOPOINTERFOCUS |
1305                                   BS_BITMAP | BS_PUSHBUTTON,
1306                                   ctrlxpos,
1307                                   14,
1308                                   32,
1309                                   32, hwndT, HWND_TOP, tool->id, NULL, NULL);
1310      }
1311      if (!hwndTool) {
1312        HBITMAP hbm = LoadBitmapFromFileNum(tool->id);
1313
1314        if (hbm) {
1315          BTNCDATA btc;
1316
1317          memset(&btc, 0, sizeof(btc));
1318          btc.cb = sizeof(btc);
1319          btc.hImage = hbm;
1320          hwndTool = WinCreateWindow(hwndT,
1321                                     WC_TOOLBUTTONS,
1322                                     NullStr,
1323                                     BS_NOPOINTERFOCUS |
1324                                     BS_BITMAP | BS_PUSHBUTTON,
1325                                     ctrlxpos,
1326                                     14,
1327                                     32,
1328                                     32,
1329                                     hwndT, HWND_TOP, tool->id, &btc, NULL);
1330          if (!hwndTool)
1331            GpiDeleteBitmap(hbm);
1332        }
1333      }
1334      if (hwndTool)
1335        tool->flags &= (~T_TEXT);
1336    }
1337    if (!hwndTool) {
1338      hwndTool = WinCreateWindow(hwndT,
1339                                 WC_TOOLBUTTONS,
1340                                 (!tool->text && tool->id >= IDM_COMMANDSTART
1341                                  && tool->id <
1342                                  IDM_QUICKTOOLSTART) ? command_title(tool->
1343                                                                      id -
1344                                                                      IDM_COMMANDSTART)
1345                                 : tool->text,
1346                                 BS_NOPOINTERFOCUS | BS_PUSHBUTTON, ctrlxpos,
1347                                 2, 54, 24, hwndT, HWND_TOP, tool->id, NULL,
1348                                 NULL);
1349      if (!hwndTool)
1350        Win_Error2(hwndT, HWND_DESKTOP, pszSrcFile, __LINE__,
1351                   IDS_WINCREATEWINDOW);
1352      tool->flags |= T_TEXT;
1353    }
1354    if (fToolTitles && !fTextTools) {
1355      hwndTool = WinCreateWindow(hwndT,
1356                                 WC_STATIC,
1357                                 tool->text,
1358                                 SS_TEXT | DT_LEFT | DT_VCENTER,
1359                                 ctrlxpos,
1360                                 1,
1361                                 32,
1362                                 10,
1363                                 hwndT,
1364                                 HWND_TOP, tool->id + 25000, NULL, NULL);
1365      if (!hwndTool)
1366        Win_Error2(hwndT, HWND_DESKTOP, pszSrcFile, __LINE__,
1367                   IDS_WINCREATEWINDOW);
1368      else {
1369        SetPresParams(hwndTool,
1370                      &RGBGREY,
1371                      &RGBBLACK, &RGBGREY, GetPString(IDS_2SYSTEMVIOTEXT));
1372      }
1373    }
1374    ctrlxpos += ((tool->flags & T_TEXT) ? 55L : 33L);
1375    SetPresParams(WinWindowFromID(hwndT, tool->id),
1376                  NULL, NULL, NULL, GetPString(IDS_8HELVTEXT));
1377    tool = tool->next;
1378  }                                     // while tool
1379
1380  hwndTool = WinCreateWindow(hwndT,
1381                             WC_BUTTON,
1382                             "#6010",
1383                             BS_NOPOINTERFOCUS |
1384                             BS_BITMAP | BS_PUSHBUTTON,
1385                             1,
1386                             19,
1387                             14,
1388                             13, hwndT, HWND_TOP, IDM_TOOLLEFT, NULL, NULL);
1389  if (!hwndTool)
1390    Win_Error2(hwndT, HWND_DESKTOP, pszSrcFile, __LINE__,
1391               IDS_WINCREATEWINDOW);
1392  hwndTool =
1393    WinCreateWindow(hwndT, WC_BUTTON, "#6011",
1394                    BS_NOPOINTERFOCUS | BS_BITMAP | BS_PUSHBUTTON, 1, 4, 14,
1395                    13, hwndT, HWND_TOP, IDM_TOOLRIGHT, NULL, NULL);
1396  if (!hwndTool)
1397    Win_Error2(hwndT, HWND_DESKTOP, pszSrcFile, __LINE__,
1398               IDS_WINCREATEWINDOW);
1399  if (resize)
1400    ResizeTools(hwndT);
1401}
1402
1403static MRESULT EXPENTRY CommandLineProc(HWND hwnd, ULONG msg, MPARAM mp1,
1404                                        MPARAM mp2)
1405{
1406  PFNWP oldproc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
1407  static BOOL lbup = FALSE;
1408
1409  switch (msg) {
1410  case UM_FOCUSME:
1411    WinSetFocus(HWND_DESKTOP, hwnd);
1412    return 0;
1413
1414  case WM_SETFOCUS:
1415    if (!mp2 && !lbup) {
1416
1417      PID pid;
1418      TID tid;
1419
1420      if (WinQueryWindowUShort((HWND) mp1, QWS_ID) == COMMAND_BUTTON)
1421        break;
1422      if (!WinQueryWindowProcess((HWND) mp1, &pid, &tid) || pid == mypid)
1423        WinDestroyWindow(hwnd);
1424    }
1425    break;
1426
1427  case UM_RESCAN:
1428    {
1429      CHAR cl[1024];
1430
1431      *cl = 0;
1432      lbup = TRUE;
1433      if (WinDlgBox(HWND_DESKTOP,
1434                    hwnd,
1435                    CmdLine2DlgProc,
1436                    FM3ModHandle, EXEC2_FRAME, MPFROMP(cl))) {
1437        lstrip(cl);
1438        WinSetWindowText(hwnd, cl);
1439      }
1440      PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
1441      PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
1442    }
1443    return 0;
1444
1445  case UM_SETUP:
1446    lbup = FALSE;
1447    return 0;
1448
1449  case WM_BUTTON1DBLCLK:
1450    PostMsg(hwnd, UM_OPENWINDOWFORME, MPVOID, MPVOID);
1451    return 0;
1452
1453  case WM_COMMAND:
1454    switch (SHORT1FROMMP(mp1)) {
1455    case COMMAND_BUTTON:
1456      if (!lbup)
1457        PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1458      break;
1459    }
1460    return 0;
1461
1462  case UM_OPENWINDOWFORME:
1463    {
1464      static char directory[CCHMAXPATH], cl[1000];
1465      char **list = NULL;
1466      ULONG len;
1467      HWND hwndCnr;
1468
1469      *directory = *cl = 0;
1470      strcpy(cl, GetCmdSpec(FALSE));
1471      strcat(cl, " /C ");
1472      len = strlen(cl);
1473      WinQueryWindowText(hwnd, 1000 - len, cl + len);
1474      bstrip(cl + len);
1475      if (strlen(cl) > len) {
1476        WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
1477                   UM_SETUP, MPFROMP(cl + len), MPVOID);
1478        WinQueryWindowText(hwndStatus, CCHMAXPATH, directory);
1479        bstrip(directory);
1480        if (*directory && (IsRoot(directory) || !IsFile(directory))) {
1481          if (!FM2Command(directory, cl + len)) {
1482            hwndCnr = TopWindow(hwndMain, (HWND) 0);
1483            if (hwndCnr) {
1484              hwndCnr = WinWindowFromID(hwndCnr, FID_CLIENT);
1485              if (hwndCnr) {
1486                hwndCnr = WinWindowFromID(hwndCnr, DIR_CNR);
1487                if (hwndCnr)
1488                  list = BuildList(hwndCnr);
1489              }
1490            }
1491            WinSetActiveWindow(HWND_DESKTOP, hwndCnr);
1492            if (add_cmdline(cl + len, FALSE) && fSaveMiniCmds)
1493              save_cmdlines(FALSE);
1494            ExecOnList(hwndCnr,
1495                       cl,
1496                       WINDOWED | ((fKeepCmdLine) ?
1497                                   SEPARATEKEEP : SEPARATE),
1498                       directory, list, NULL);
1499            if (list)
1500              free(list);
1501            WinDestroyWindow(hwnd);
1502            break;
1503          }
1504        }
1505      }
1506      WinSendMsg(hwnd, EM_SETSEL, MPFROM2SHORT(0, 1024), MPVOID);
1507    }
1508    return 0;
1509
1510  case WM_CHAR:
1511    if (!lbup && !(SHORT1FROMMP(mp1) & KC_KEYUP)) {
1512      if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
1513        if ((SHORT1FROMMP(mp2) & 255) == '\r')
1514          PostMsg(hwnd, UM_OPENWINDOWFORME, MPVOID, MPVOID);
1515        else if ((SHORT1FROMMP(mp2) & 0xff) == 0x1b)
1516          WinDestroyWindow(hwnd);
1517        else if (SHORT2FROMMP(mp2) == VK_UP || SHORT2FROMMP(mp2) == VK_DOWN)
1518          PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1519      }
1520    }
1521    else if ((SHORT1FROMMP(mp1) & KC_VIRTUALKEY) &&
1522             ((SHORT2FROMMP(mp2) == VK_UP ||
1523               SHORT2FROMMP(mp2) == VK_DOWN) ||
1524              (SHORT1FROMMP(mp2) == '\x1b') || (SHORT1FROMMP(mp2) == '\r')))
1525      return 0;
1526    break;
1527
1528  case WM_DESTROY:
1529    PostMsg(WinQueryWindow(hwnd, QW_PARENT), UM_RESCAN, MPVOID, MPVOID);
1530    lbup = FALSE;
1531    break;
1532  }
1533  return oldproc(hwnd, msg, mp1, mp2);
1534}
1535
1536MRESULT EXPENTRY DriveBackProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1537{
1538  switch (msg) {
1539  case WM_CREATE:
1540    PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
1541    break;
1542
1543  case UM_SETUP:
1544    {
1545      RGB2 rgb;
1546
1547      memset(&rgb, 0, sizeof(rgb));
1548      rgb.bRed = 128;
1549      SetPresParams(hwnd,
1550                    &RGBGREY, &rgb, &RGBGREY, GetPString(IDS_8HELVTEXT));
1551      SetTargetDir(hwnd, TRUE);
1552    }
1553    return 0;
1554
1555  case WM_SETFOCUS:
1556  case UM_FOCUSME:
1557  case WM_BUTTON1DOWN:
1558  case WM_BUTTON1UP:
1559  case WM_BUTTON2DOWN:
1560  case WM_BUTTON2UP:
1561  case WM_BUTTON3DOWN:
1562  case WM_BUTTON3UP:
1563    return CommonTextButton(hwnd, msg, mp1, mp2);
1564
1565  case WM_MOUSEMOVE:
1566    shiftstate = (SHORT2FROMMP(mp2) & (KC_SHIFT | KC_ALT | KC_CTRL));
1567    break;
1568
1569  case UM_CLICKED:
1570  case UM_CLICKED3:
1571    PostMsg(hwndMain, WM_COMMAND, MPFROM2SHORT(IDM_SETTARGET, 0), MPVOID);
1572    return 0;
1573
1574  case WM_CHAR:
1575    shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
1576    break;
1577
1578  case WM_CONTROLPOINTER:
1579    if (!fNoFinger &&
1580        (SHORT1FROMMP(mp1) >= IDM_DRIVEA &&
1581         SHORT1FROMMP(mp1) < IDM_DRIVEA + 26))
1582      return MRFROMLONG(hptrFinger);
1583    break;
1584
1585  case WM_COMMAND:
1586    {
1587      CHAR dv[4];
1588
1589      *dv = 0;
1590      WinQueryWindowText(WinWindowFromID(hwnd, SHORT1FROMMP(mp1) + 50),
1591                         2, dv);
1592      if (isalpha(*dv)) {
1593
1594        HWND hwndActive;
1595
1596        dv[1] = ':';
1597        dv[2] = '\\';
1598        dv[3] = 0;
1599        hwndActive = TopWindow(hwnd, (HWND) 0);
1600        if (hwndActive)
1601          WinSendMsg(WinWindowFromID(hwndActive, FID_CLIENT),
1602                     UM_DRIVECMD, MPFROMP(dv), MPVOID);
1603      }
1604    }
1605    return 0;
1606
1607  case WM_PAINT:
1608    PaintRecessedWindow(hwnd, (HPS) 0, TRUE, FALSE);
1609    break;
1610
1611  case WM_CLOSE:
1612    WinDestroyWindow(hwnd);
1613    return 0;
1614  }
1615  return PFNWPStatic(hwnd, msg, mp1, mp2);
1616}
1617
1618MRESULT EXPENTRY DriveProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1619{
1620  USHORT id;
1621  CHAR szDrv[CCHMAXPATH];
1622  DIRCNRDATA *dcd;
1623
1624  static BOOL emphasized = FALSE;
1625  static HWND hwndMenu = NULLHANDLE;
1626  static USHORT helpid = 0;
1627
1628  switch (msg) {
1629  case WM_MOUSEMOVE:
1630    if (fDrivebarHelp &&
1631        (!hwndBubble ||
1632         WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
1633        !WinQueryCapture(HWND_DESKTOP)) {
1634      id = WinQueryWindowUShort(hwnd, QWS_ID);
1635      if (helpid != id) {
1636        helpid = id;
1637        PostMsg(MainObjectHwnd, UM_SETUP6, MPFROMLONG((ULONG) hwnd), MPVOID);
1638      }
1639      else
1640        helpid = 0;
1641    }
1642    break;
1643
1644  case UM_SETUP6:
1645    if (helpid == WinQueryWindowUShort(hwnd, QWS_ID)) {
1646      if ((char *)mp1 &&
1647          (!hwndBubble ||
1648           WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
1649          !WinQueryCapture(HWND_DESKTOP)) {
1650
1651        RECTL rcl;
1652        POINTL ptl;
1653
1654        WinQueryPointerPos(HWND_DESKTOP, &ptl);
1655        WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
1656        WinQueryWindowRect(hwnd, &rcl);
1657        if (WinPtInRect(WinQueryAnchorBlock(hwnd), &rcl, &ptl))
1658          BubbleHelp(hwnd, FALSE, TRUE, FALSE, (char *)mp1);
1659      }
1660    }
1661    return 0;
1662
1663  case WM_MENUEND:
1664    if (hwndMenu == (HWND) mp2) {
1665      WinDestroyWindow(hwndMenu);
1666      hwndMenu = (HWND) 0;
1667    }
1668    break;
1669
1670  case WM_CONTEXTMENU:
1671    if (hwndMenu)
1672      WinDestroyWindow(hwndMenu);
1673    hwndMenu = (HWND) 0;
1674    id = WinQueryWindowUShort(hwnd, QWS_ID);
1675    *szDrv = 0;
1676    WinQueryWindowText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1677                                       id + 50), sizeof(szDrv), szDrv);
1678    if (isalpha(*szDrv)) {
1679      hwndMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, MAIN_DRIVES);
1680      if (hwndMenu) {
1681        BOOL rdy;
1682        CHAR chDrv = *szDrv;
1683        UINT iDrv;
1684
1685        strcpy(szDrv + 2, "\\");
1686        MakeValidDir(szDrv);
1687        // Disable menus if MakeValidDir changes drive letter fixme this section doesn't do anything see treecnt.c
1688        rdy = toupper(*szDrv) == toupper(chDrv);
1689        iDrv = toupper(*szDrv) - 'A';
1690        if (!rdy || ~driveflags[iDrv] & DRIVE_REMOTE)
1691          WinEnableMenuItem(hwndMenu, IDM_DETACH, FALSE);
1692
1693        if (!rdy || driveflags[iDrv] & DRIVE_NOTWRITEABLE) {
1694          WinEnableMenuItem(hwndMenu, IDM_MKDIR, FALSE);
1695          WinEnableMenuItem(hwndMenu, IDM_FORMAT, FALSE);
1696          WinEnableMenuItem(hwndMenu, IDM_OPTIMIZE, FALSE);
1697          WinEnableMenuItem(hwndMenu, IDM_UNDELETE, FALSE);
1698        }
1699        if (!rdy || ~driveflags[iDrv] & DRIVE_REMOVABLE) {
1700          WinEnableMenuItem(hwndMenu, IDM_EJECT, FALSE);
1701          WinEnableMenuItem(hwndMenu, IDM_LOCK, FALSE);
1702          WinEnableMenuItem(hwndMenu, IDM_UNLOCK, FALSE);
1703        }
1704        if (!rdy) {
1705          WinEnableMenuItem(hwndMenu, IDM_INFO, FALSE);
1706          WinEnableMenuItem(hwndMenu, IDM_ARCHIVE, FALSE);
1707          WinEnableMenuItem(hwndMenu, IDM_SIZES, FALSE);
1708          WinEnableMenuItem(hwndMenu, IDM_SHOWALLFILES, FALSE);
1709          WinEnableMenuItem(hwndMenu, IDM_CHKDSK, FALSE);
1710        }
1711        /* fixme to be gone?
1712           if (!rdy || ~driveflags[iDrv] & DRIVE_CDROM) {
1713           WinEnableMenuItem(hwndMenu, IDM_CLOSETRAY, FALSE);
1714           }
1715         */
1716        PopupMenu(hwnd, hwnd, hwndMenu);
1717      }
1718    }
1719    return MRFROMSHORT(TRUE);
1720
1721  case WM_BUTTON2CLICK:
1722    shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
1723    if (!(shiftstate & KC_CTRL))
1724      break;
1725
1726  case WM_CHORD:
1727  case WM_BUTTON3CLICK:
1728    id = WinQueryWindowUShort(hwnd, QWS_ID);
1729    *szDrv = 0;
1730    WinQueryWindowText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1731                                       id + 50), sizeof(szDrv), szDrv);
1732    if (isalpha(*szDrv)) {
1733      strcat(szDrv, "\\");
1734      if (!FindDirCnrByName(szDrv, TRUE))
1735        OpenDirCnr((HWND) 0, hwndMain, hwndTree, FALSE, szDrv);
1736    }
1737    break;
1738
1739  case WM_COMMAND:
1740    PostMsg(hwnd, UM_COMMAND, mp1, mp2);
1741    return 0;
1742
1743  case UM_COMMAND:
1744    id = WinQueryWindowUShort(hwnd, QWS_ID);
1745    *szDrv = 0;
1746    WinQueryWindowText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1747                                       id + 50), sizeof(szDrv), szDrv);
1748    if (isalpha(*szDrv)) {
1749      strcat(szDrv, "\\");
1750      CommonDriveCmd(hwnd, szDrv, SHORT1FROMMP(mp1));
1751    }
1752    return 0;
1753
1754  case DM_DRAGOVER:
1755    id = WinQueryWindowUShort(hwnd, QWS_ID);
1756    *szDrv = 0;
1757    WinQueryWindowText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1758                                       id + 50), sizeof(szDrv), szDrv);
1759    if (isalpha(*szDrv) &&
1760        !(driveflags[toupper(*szDrv) - 'A'] & DRIVE_NOTWRITEABLE)) {
1761      if (!emphasized) {
1762        emphasized = TRUE;
1763        DrawTargetEmphasis(hwnd, emphasized);
1764      }
1765      if (AcceptOneDrop(hwnd, mp1, mp2))
1766        return MRFROM2SHORT(DOR_DROP, DO_MOVE);
1767      return MRFROM2SHORT(DOR_NEVERDROP, 0);
1768    }
1769    break;
1770
1771  case DM_DRAGLEAVE:
1772    id = WinQueryWindowUShort(hwnd, QWS_ID);
1773    *szDrv = 0;
1774    WinQueryWindowText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1775                                       id + 50), sizeof(szDrv), szDrv);
1776    if (isalpha(*szDrv) &&
1777        !(driveflags[toupper(*szDrv) - 'A'] & DRIVE_NOTWRITEABLE)) {
1778      if (emphasized) {
1779        emphasized = FALSE;
1780        DrawTargetEmphasis(hwnd, emphasized);
1781      }
1782    }
1783    break;
1784
1785  case DM_DROPHELP:
1786    id = WinQueryWindowUShort(hwnd, QWS_ID);
1787    *szDrv = 0;
1788    WinQueryWindowText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1789                                       id + 50), sizeof(szDrv), szDrv);
1790    if (isalpha(*szDrv) &&
1791        !(driveflags[toupper(*szDrv) - 'A'] & DRIVE_NOTWRITEABLE)) {
1792      DropHelp(mp1, mp2, hwnd, GetPString(IDS_DRIVEDROPHELP));
1793      return 0;
1794    }
1795    break;
1796
1797  case DM_DROP:
1798    id = WinQueryWindowUShort(hwnd, QWS_ID);
1799    *szDrv = 0;
1800    WinQueryWindowText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1801                                       id + 50), sizeof(szDrv), szDrv);
1802    if (isalpha(*szDrv) &&
1803        !(driveflags[toupper(*szDrv) - 'A'] & DRIVE_NOTWRITEABLE)) {
1804
1805      CNRDRAGINFO cnd;
1806      LISTINFO *li;
1807      ULONG action = UM_ACTION;
1808
1809      if (emphasized) {
1810        emphasized = FALSE;
1811        DrawTargetEmphasis(hwnd, emphasized);
1812      }
1813      memset(&cnd, 0, sizeof(cnd));
1814      cnd.pDragInfo = (PDRAGINFO) mp1;
1815      cnd.pRecord = NULL;
1816      li = DoFileDrop(hwnd,
1817                      NULL,
1818                      TRUE, MPFROM2SHORT(TREE_CNR, CN_DROP), MPFROMP(&cnd));
1819      dcd = INSTDATA(cnd.pDragInfo->hwndSource);
1820      if (dcd && dcd->ulItemsToUnHilite) {
1821        saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
1822               hwnd,
1823               GetPString(IDS_ERRORTEXT),
1824               GetPString(IDS_EXCEEDPMDRGLMT));
1825      }
1826      if (li) {
1827        strcpy(li->targetpath, szDrv);
1828        strcat(li->targetpath, "\\");
1829        if (li->list && li->list[0] && IsRoot(li->list[0]))
1830          li->type = DO_LINK;
1831        else if (fDragndropDlg && (!*li->arcname || !li->info)) {
1832
1833          CHECKLIST cl;
1834
1835          memset(&cl, 0, sizeof(cl));
1836          cl.size = sizeof(cl);
1837          cl.flags = li->type;
1838          cl.list = li->list;
1839          cl.cmd = li->type;
1840          cl.prompt = li->targetpath;
1841          li->type = WinDlgBox(HWND_DESKTOP,
1842                               hwndMain,
1843                               DropListProc,
1844                               FM3ModHandle, DND_FRAME, MPFROMP(&cl));
1845          if (li->type == DID_ERROR)
1846                  Win_Error(DND_FRAME, HWND_DESKTOP, pszSrcFile, __LINE__,
1847                            "Drag & Drop Dialog");
1848          if (!li->type) {
1849            FreeListInfo(li);
1850            return 0;
1851          }
1852          li->list = cl.list;
1853          if (!li->list || !li->list[0]) {
1854            FreeListInfo(li);
1855            return 0;
1856          }
1857        }
1858        else {
1859          if (!WinDlgBox(HWND_DESKTOP,
1860                         hwndMain,
1861                         WalkDlgProc,
1862                         FM3ModHandle,
1863                         WALK_FRAME,
1864                         MPFROMP(li->targetpath)) || !*li->targetpath) {
1865            FreeListInfo(li);
1866            return 0;
1867          }
1868        }
1869        switch (li->type) {
1870        case DND_LAUNCH:
1871          strcat(li->targetpath, " %a");
1872          ExecOnList(hwndMain,
1873                     li->targetpath, PROMPT | WINDOWED, NULL, li->list, NULL);
1874          FreeList(li->list);
1875          li->list = NULL;
1876          break;
1877        case DO_LINK:
1878          if (fLinkSetsIcon) {
1879            li->type = IDM_SETICON;
1880            action = UM_MASSACTION;
1881          }
1882          else
1883            li->type = IDM_COMPARE;
1884          break;
1885        case DND_EXTRACT:
1886          if (*li->targetpath && !IsFile(li->targetpath))
1887            li->type = IDM_EXTRACT;
1888          break;
1889        case DND_MOVE:
1890          li->type = IDM_MOVE;
1891          if (*li->targetpath && IsFile(li->targetpath) == 1) {
1892            action = UM_MASSACTION;
1893            li->type = IDM_ARCHIVEM;
1894          }
1895          break;
1896        case DND_WILDMOVE:
1897          li->type = IDM_WILDMOVE;
1898          if (*li->targetpath && IsFile(li->targetpath) == 1) {
1899            action = UM_MASSACTION;
1900            li->type = IDM_ARCHIVEM;
1901          }
1902          break;
1903        case DND_OBJECT:
1904          li->type = IDM_OBJECT;
1905          action = UM_MASSACTION;
1906          break;
1907        case DND_SHADOW:
1908          li->type = IDM_SHADOW;
1909          action = UM_MASSACTION;
1910          break;
1911        case DND_COMPARE:
1912          li->type = IDM_COMPARE;
1913          break;
1914        case DND_SETICON:
1915          action = UM_MASSACTION;
1916          li->type = IDM_SETICON;
1917          break;
1918        case DND_COPY:
1919          li->type = IDM_COPY;
1920          if (*li->targetpath && IsFile(li->targetpath) == 1) {
1921            action = UM_MASSACTION;
1922            li->type = IDM_ARCHIVE;
1923          }
1924          break;
1925        case DND_WILDCOPY:
1926          li->type = IDM_WILDCOPY;
1927          if (*li->targetpath && IsFile(li->targetpath) == 1) {
1928            action = UM_MASSACTION;
1929            li->type = IDM_ARCHIVE;
1930          }
1931          break;
1932        default:
1933          if (*li->arcname && li->info) {
1934            action = UM_MASSACTION;
1935            li->type = (li->type == DO_MOVE) ? IDM_FAKEEXTRACTM :
1936              IDM_FAKEEXTRACT;
1937          }
1938          else if (*li->targetpath && IsFile(li->targetpath) == 1) {
1939            action = UM_MASSACTION;
1940            li->type = (li->type == DO_MOVE) ? IDM_ARCHIVEM : IDM_ARCHIVE;
1941          }
1942          else
1943            li->type = (li->type == DO_MOVE) ? IDM_MOVE : IDM_COPY;
1944          break;
1945        }
1946        if (!li->list || !li->list[0])
1947          FreeListInfo(li);
1948        else
1949          WinSendMsg(hwndTree, UM_ACTION, MPFROMP(li), MPFROMLONG(action));
1950      }
1951      return 0;
1952    }
1953    break;
1954
1955  case WM_DESTROY:
1956    if (hwndMenu)
1957      WinDestroyWindow(hwndMenu);
1958    hwndMenu = (HWND) 0;
1959    break;
1960  }
1961  return PFNWPButton(hwnd, msg, mp1, mp2);
1962}
1963
1964VOID BuildDriveBarButtons(HWND hwndT)
1965{
1966  register ULONG x, y = 0;
1967  ULONG ulDriveNum, ulDriveMap, iconid;
1968  CHAR s[8];
1969  HENUM henum;
1970  HWND hwndB;
1971
1972  henum = WinBeginEnumWindows(hwndT);
1973
1974  while ((hwndB = WinGetNextWindow(henum)) != NULLHANDLE)
1975    WinDestroyWindow(hwndB);
1976
1977  WinEndEnumWindows(henum);
1978  if (fDrivebar) {
1979    DosError(FERR_DISABLEHARDERR);
1980    DosQCurDisk(&ulDriveNum, &ulDriveMap);
1981    for (x = 0; x < 26; x++) {
1982      if ((ulDriveMap & (1L << x)) && !(driveflags[x] & DRIVE_IGNORE)) {
1983        if (x > 1) {
1984          if (driveflags[x] & DRIVE_CDROM)
1985            iconid = CDROM_ICON;
1986          else
1987            iconid = (driveflags[x] & DRIVE_REMOVABLE) ?
1988              REMOVABLE_ICON :
1989                     (driveflags[x] & DRIVE_VIRTUAL) ?
1990                      VIRTUAL_ICON :
1991              (driveflags[x] & DRIVE_REMOTE) ?
1992              REMOTE_ICON :
1993                     (driveflags[x] & DRIVE_RAMDISK) ?
1994                      RAMDISK_ICON :
1995                     (driveflags[x] & DRIVE_ZIPSTREAM) ?
1996                      ZIPSTREAM_ICON :DRIVE_ICON;
1997        }
1998        else
1999          iconid = FLOPPY_ICON;
2000        sprintf(s, "#%lu", iconid);
2001        hwndB = WinCreateWindow(hwndT,
2002                                WC_DRIVEBUTTONS,
2003                                s,
2004                                BS_NOPOINTERFOCUS | BS_BITMAP | BS_PUSHBUTTON,
2005                                0,
2006                                0,
2007                                28,
2008                                18,
2009                                hwndT, HWND_TOP, y + IDM_DRIVEA, NULL, NULL);
2010        if (!hwndB)
2011          Win_Error2(hwndT, HWND_DESKTOP, pszSrcFile, __LINE__,
2012                     IDS_WINCREATEWINDOW);
2013        else {
2014          WinSetWindowPos(hwndB, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER);
2015          sprintf(s, "%c:", (CHAR) x + 'A');
2016          hwndB = WinCreateWindow(hwndT,
2017                                  WC_STATIC,
2018                                  s,
2019                                  SS_TEXT | DT_LEFT | DT_VCENTER,
2020                                  0,
2021                                  0,
2022                                  10,
2023                                  18,
2024                                  hwndT,
2025                                  HWND_TOP, y + IDM_DRIVEATEXT, NULL, NULL);
2026          if (!hwndB)
2027            Win_Error2(hwndT, HWND_DESKTOP, pszSrcFile, __LINE__,
2028                       IDS_WINCREATEWINDOW);
2029          else {
2030            SetPresParams(hwndB,
2031                          &RGBGREY,
2032                          &RGBBLACK, &RGBGREY, GetPString(IDS_6HELVTEXT));
2033            WinSetWindowPos(hwndB, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER);
2034          }
2035          y++;
2036        }
2037      }
2038    }                                   // for
2039  }                                     // if drivebar
2040  PostMsg(WinQueryWindow(hwndT, QW_PARENT),
2041          WM_UPDATEFRAME, MPFROMLONG(FCF_SIZEBORDER), MPVOID);
2042}
2043
2044VOID ResizeDrives(HWND hwndT, long xwidth)
2045{
2046  register ULONG ctrlxpos = 2, ctrlypos = 0, ctrlxsize;
2047  HENUM henum;
2048  HWND hwndB;
2049  RECTL rcl;
2050
2051  DriveLines = 0;
2052  if (!fDrivebar)
2053    return;
2054  if (!xwidth) {
2055    WinQueryWindowRect(hwndT, &rcl);
2056    xwidth = rcl.xRight - ((WinQuerySysValue(HWND_DESKTOP,
2057                                             SV_CYSIZEBORDER) * 2) + 2);
2058  }
2059  henum = WinBeginEnumWindows(hwndT);
2060  while ((hwndB = WinGetNextWindow(henum)) != NULLHANDLE) {
2061    if (WinQueryWindowUShort(hwndB, QWS_ID) > IDM_DRIVEA + 27)
2062      ctrlxsize = 10;
2063    else
2064      ctrlxsize = 28;
2065    WinSetWindowPos(hwndB,
2066                    HWND_TOP,
2067                    ctrlxpos, ctrlypos, ctrlxsize, 18, SWP_MOVE | SWP_SHOW);
2068    ctrlxpos += (ctrlxsize + 2);
2069    if (ctrlxsize == 10) {
2070      if (ctrlxpos + (42 + ((fShowTarget && DriveLines == 0) ?
2071                            256 : 0)) > xwidth) {
2072        ctrlxpos = 2;
2073        ctrlypos += 18;
2074        DriveLines++;
2075      }
2076    }
2077  }
2078  if (ctrlxpos == 2 && DriveLines)
2079    DriveLines--;
2080}
2081
2082MRESULT EXPENTRY StatusProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
2083{
2084  static HWND hwndE = (HWND) 0, hwndB = (HWND) 0;
2085  static CHAR lastcmd[1024] = "";
2086
2087  switch (msg) {
2088  case WM_CREATE:
2089    {
2090      MRESULT mr = PFNWPStatic(hwnd, msg, mp1, mp2);
2091
2092      SetPresParams(hwnd,
2093                    &RGBGREY,
2094                    &RGBBLACK, &RGBGREY, GetPString(IDS_8HELVBOLDTEXT));
2095      return mr;
2096    }
2097
2098  case WM_PRESPARAMCHANGED:
2099    if (fRunning) {
2100
2101      ULONG AttrFound, AttrValue[64], cbRetLen;
2102
2103      cbRetLen = WinQueryPresParam(hwnd,
2104                                   (ULONG) mp1,
2105                                   0,
2106                                   &AttrFound,
2107                                   (ULONG) sizeof(AttrValue), &AttrValue, 0);
2108      if (cbRetLen) {
2109        switch (AttrFound) {
2110        case PP_FONTNAMESIZE:
2111          PostMsg(WinQueryWindow(hwnd, QW_PARENT),
2112                  WM_UPDATEFRAME, MPFROMLONG(FCF_SIZEBORDER), MPVOID);
2113          break;
2114        }
2115      }
2116    }
2117    break;
2118
2119  case WM_CONTEXTMENU:
2120    PostMsg(hwndMain, UM_CONTEXTMENU, MPVOID, MPVOID);
2121    return MRFROMSHORT(TRUE);
2122
2123  case WM_BEGINDRAG:
2124    if (hwndTree) {
2125
2126      SWP swp;
2127      ULONG fl = SWP_ACTIVATE | SWP_SHOW | SWP_ZORDER;
2128
2129      WinQueryWindowPos(hwndTree, &swp);
2130      if (!(swp.fl & SWP_MAXIMIZE))
2131        fl |= SWP_RESTORE;
2132      WinSetWindowPos(hwndTree, HWND_TOP, 0, 0, 0, 0, fl);
2133    }
2134    break;
2135
2136  case UM_SETUP:
2137    if (mp1)
2138      strcpy(lastcmd, (CHAR *) mp1);
2139    return 0;
2140
2141  case UM_RESCAN:
2142    if (hwndE && WinIsWindow(WinQueryAnchorBlock(hwnd), hwndE))
2143      WinDestroyWindow(hwndE);
2144    if (hwndB && WinIsWindow(WinQueryAnchorBlock(hwnd), hwndB))
2145      WinDestroyWindow(hwndB);
2146    hwndE = hwndB = (HWND) 0;
2147    return 0;
2148
2149  case WM_COMMAND:
2150    switch (SHORT1FROMMP(mp1)) {
2151    case COMMAND_BUTTON:
2152      PostMsg(hwndE, msg, mp1, mp2);
2153      break;
2154    }
2155    return 0;
2156
2157  case WM_MOUSEMOVE:
2158    shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
2159    {
2160      USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
2161      char *s = NULL;
2162
2163      if (fOtherHelp) {
2164        if ((!hwndBubble || WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd)
2165            && !WinQueryCapture(HWND_DESKTOP)) {
2166          switch (id) {
2167          case IDM_ATTRS:
2168            if (WinQueryWindowTextLength(hwnd))
2169              s = GetPString(IDS_ATTRSBUTTONHELP);
2170            break;
2171          case IDM_INFO:
2172            if (WinQueryWindowTextLength(hwnd))
2173              s = GetPString(IDS_INFOBUTTONHELP);
2174            break;
2175          case IDM_RENAME:
2176            if (WinQueryWindowTextLength(hwnd))
2177              s = GetPString(IDS_NAMEBUTTONHELP);
2178            break;
2179          case MAIN_STATUS2:
2180            if (!hwndE)
2181              s = GetPString(IDS_STATUS2HELP);
2182            break;
2183          default:
2184            break;
2185          }
2186          if (s)
2187            MakeBubble(hwnd, FALSE, s);
2188          else if (hwndBubble)
2189            WinDestroyWindow(hwndBubble);
2190        }
2191      }
2192      switch (id) {
2193      case IDM_ATTRS:
2194      case IDM_INFO:
2195      case IDM_RENAME:
2196      case MAIN_STATUS2:
2197        return CommonTextProc(hwnd, msg, mp1, mp2);
2198      default:
2199        break;
2200      }
2201    }
2202    break;
2203
2204  case WM_BUTTON2DOWN:
2205  case WM_BUTTON2UP:
2206  case UM_FOCUSME:
2207    return CommonTextButton(hwnd, msg, mp1, mp2);
2208
2209  case WM_BUTTON1DOWN:
2210  case WM_BUTTON1UP:
2211  case WM_BUTTON3DOWN:
2212  case WM_BUTTON3UP:
2213    {
2214      USHORT id;
2215
2216      id = WinQueryWindowUShort(hwnd, QWS_ID);
2217      switch (id) {
2218      case IDM_ATTRS:
2219      case IDM_INFO:
2220      case IDM_RENAME:
2221      case MAIN_STATUS2:
2222        return CommonTextButton(hwnd, msg, mp1, mp2);
2223      default:
2224        PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
2225        break;
2226      }
2227    }
2228    break;
2229
2230  case WM_SETFOCUS:
2231    if (mp2) {
2232
2233      USHORT id;
2234
2235      id = WinQueryWindowUShort(hwnd, QWS_ID);
2236      if (id == MAIN_STATUS2 && hwndE)
2237        WinSendMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2238      else
2239        return CommonTextButton(hwnd, msg, mp1, mp2);
2240    }
2241    break;
2242
2243  case WM_BUTTON1CLICK:
2244    {
2245      USHORT id;
2246
2247      id = WinQueryWindowUShort(hwnd, QWS_ID);
2248      if (id == MAIN_STATUS) {
2249        if (SHORT2FROMMP(mp2) & KC_CTRL)
2250          PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2251                                  FID_CLIENT),
2252                  WM_COMMAND, MPFROM2SHORT(IDM_WINDOWDLG, 0), MPVOID);
2253        else if (hwndTree)
2254          PostMsg(hwndTree, UM_TIMER, MPVOID, MPVOID);
2255      }
2256    }
2257    break;
2258
2259  case UM_CLICKED:
2260  case UM_CLICKED3:
2261    {
2262      USHORT id;
2263
2264      id = WinQueryWindowUShort(hwnd, QWS_ID);
2265      if (id == MAIN_STATUS2 && !hwndE) {
2266
2267        SWP swp;
2268        CHAR directory[CCHMAXPATH];
2269        PFNWP oldproce;
2270
2271        *directory = 0;
2272        TopWindowName(hwndMain, (HWND) 0, directory);
2273        WinQueryWindowPos(hwnd, &swp);
2274        hwndB = WinCreateWindow(hwnd,
2275                                WC_BUTTON,
2276                                "+",
2277                                WS_VISIBLE | BS_PUSHBUTTON |
2278                                BS_NOPOINTERFOCUS,
2279                                swp.cx - swp.cy,
2280                                0,
2281                                swp.cy,
2282                                swp.cy,
2283                                hwnd, HWND_TOP, COMMAND_BUTTON, NULL, NULL);
2284        if (!hwndB)
2285          Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
2286        hwndE = WinCreateWindow(hwnd,
2287                                WC_ENTRYFIELD,
2288                                NULL,
2289                                WS_VISIBLE | ES_AUTOSCROLL,
2290                                0,
2291                                0,
2292                                swp.cx - swp.cy,
2293                                swp.cy,
2294                                hwnd, HWND_TOP, COMMAND_LINE, NULL, NULL);
2295        if (!hwndE)
2296          Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
2297        if (!hwndE || !hwndB) {
2298          PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2299          return 0;
2300        }
2301        WinSendMsg(hwndE, EM_SETTEXTLIMIT, MPFROM2SHORT(1024, 0), MPVOID);
2302        WinSetWindowText(hwndStatus, directory);
2303        if (*lastcmd)
2304          WinSetWindowText(hwndE, lastcmd);
2305        else
2306          WinSetWindowText(hwndE, GetPString(IDS_HELPCMDTEXT));
2307        oldproce = WinSubclassWindow(hwndE, (PFNWP) CommandLineProc);
2308        if (oldproce)
2309          WinSetWindowPtr(hwndE, QWL_USER, (PVOID) oldproce);
2310        PostMsg(hwndE, UM_FOCUSME, MPVOID, MPVOID);
2311        PostMsg(hwndE, EM_SETSEL, MPFROM2SHORT(0, 1024), MPVOID);
2312        return 0;
2313      }
2314      if (msg == UM_CLICKED3 || (SHORT2FROMMP(mp2) & KC_CTRL)) {
2315        switch (id) {
2316        case IDM_ATTRS:
2317          id = IDM_SORTSIZE;
2318          break;
2319        case IDM_INFO:
2320          id = IDM_SORTLWDATE;
2321          break;
2322        case IDM_RENAME:
2323          id = IDM_SORTFILENAME;
2324          break;
2325        }
2326      }
2327      PostMsg(WinQueryWindow(hwnd, QW_PARENT),
2328              WM_COMMAND, MPFROM2SHORT(id, 0), MPVOID);
2329    }
2330    return 0;
2331
2332  case WM_PAINT:
2333    {
2334      USHORT id;
2335
2336      id = WinQueryWindowUShort(hwnd, QWS_ID);
2337      switch (id) {
2338      case IDM_ATTRS:
2339      case IDM_INFO:
2340      case IDM_RENAME:
2341      case MAIN_STATUS2:
2342        PaintRecessedWindow(hwnd, (HPS) 0, TRUE, FALSE);
2343        break;
2344      default:
2345        PaintRecessedWindow(hwnd, (HPS) 0, FALSE, TRUE);
2346        break;
2347      }
2348      if (id == IDM_RENAME) {
2349
2350        HPS hps;
2351
2352        hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
2353        if (hps) {
2354          PaintSTextWindow(hwnd, hps);
2355          WinEndPaint(hps);
2356        }
2357        return 0;
2358      }
2359    }
2360    break;
2361
2362  }
2363  return PFNWPStatic(hwnd, msg, mp1, mp2);
2364}
2365
2366MRESULT EXPENTRY ToolBackProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
2367{
2368  switch (msg) {
2369  case WM_CREATE:
2370    hwndToolback = hwnd;
2371    SetPresParams(hwnd,
2372                  &RGBGREY, &RGBBLACK, &RGBGREY, GetPString(IDS_8HELVTEXT));
2373    break;
2374
2375  case WM_MOUSEMOVE:
2376    shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
2377    break;
2378
2379  case WM_CONTROLPOINTER:
2380    if (!fNoFinger && SHORT1FROMMP(mp1) < 25000)
2381      return MRFROMLONG(hptrFinger);
2382    break;
2383
2384  case WM_CHAR:
2385    shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
2386    break;
2387
2388  case WM_COMMAND:
2389  case UM_COMMAND:
2390    return WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2391                                      FID_CLIENT), msg, mp1, mp2);
2392
2393  case WM_PAINT:
2394    {
2395      HPS hps;
2396      RECTL rcl;
2397
2398      hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
2399      if (hps) {
2400        WinQueryWindowRect(hwnd, &rcl);
2401        WinFillRect(hps, &rcl, CLR_PALEGRAY);
2402        WinEndPaint(hps);
2403      }
2404      PaintRecessedWindow(hwnd, (HPS) 0, TRUE, FALSE);
2405    }
2406    break;
2407
2408  case UM_SETUP:
2409    {
2410      USHORT id;
2411      TOOL *tool;
2412
2413      id = SHORT1FROMMP(mp1);
2414      tool = find_tool(id);
2415      if (tool) {
2416        del_tool(tool);
2417        WinShowWindow(WinWindowFromID(hwnd, id), FALSE);
2418        if (fToolTitles)
2419          WinShowWindow(WinWindowFromID(hwnd, id + 25000), FALSE);
2420        ResizeTools(hwnd);
2421      }
2422    }
2423    return 0;
2424
2425  case WM_CHORD:
2426    {
2427      USHORT id;
2428
2429      id = (USHORT) WinDlgBox(HWND_DESKTOP,
2430                              hwnd,
2431                              AddToolProc,
2432                              FM3ModHandle, ADDBTN_FRAME, MPVOID);
2433      if (id && id != (USHORT) - 1)
2434        WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2435                                   FID_CLIENT),
2436                   WM_COMMAND,
2437                   MPFROM2SHORT(IDM_CREATETOOL, 0), MPFROM2SHORT(id, 0));
2438    }
2439    break;
2440
2441  case WM_CONTEXTMENU:
2442    if (WinDlgBox(HWND_DESKTOP,
2443                  hwnd, ToolIODlgProc, FM3ModHandle, SVBTN_FRAME, MPVOID))
2444      BuildTools(hwnd, TRUE);
2445    return MRFROMSHORT(TRUE);
2446
2447  case WM_CLOSE:
2448    WinDestroyWindow(hwnd);
2449    return 0;
2450
2451  case WM_DESTROY:
2452    break;
2453  }
2454  return WinDefWindowProc(hwnd, msg, mp1, mp2);
2455}
2456
2457static VOID AdjustSizeOfClient(PSWP pswp, PRECTL prectl)
2458{
2459  SWP swp;
2460  RECTL rectl;
2461
2462  if (fFreeTree)
2463    return;
2464  if (pswp) {
2465    if (WinQueryWindowPos(hwndTree, &swp) &&
2466        !(swp.fl & (SWP_MINIMIZE | SWP_HIDE | SWP_MAXIMIZE))) {
2467      pswp->x = swp.cx;
2468      pswp->cx -= swp.cx;
2469    }
2470  }
2471  if (prectl) {
2472    if (WinQueryWindowPos(hwndTree, &swp) &&
2473        !(swp.fl & (SWP_MINIMIZE | SWP_HIDE | SWP_MAXIMIZE)) &&
2474        WinQueryWindowRect(hwndTree, &rectl)) {
2475      prectl->xLeft = rectl.xRight;
2476      prectl->xRight -= rectl.xRight;
2477    }
2478  }
2479}
2480
2481VOID FillClient(HWND hwndClient, PSWP pswp, PRECTL prectl, BOOL avoidtree)
2482{
2483  ULONG adjust;
2484
2485  adjust = WinQuerySysValue(HWND_DESKTOP, SV_CYICON);
2486  if (pswp)
2487    WinQueryWindowPos(hwndClient, pswp);
2488  if (prectl)
2489    WinQueryWindowRect(hwndClient, prectl);
2490  if (avoidtree && !fFreeTree)
2491    AdjustSizeOfClient(pswp, prectl);
2492  if (prectl)
2493    prectl->yBottom += adjust;
2494  if (pswp) {
2495    if (!avoidtree || fFreeTree)
2496      pswp->x = 0;
2497    pswp->y = adjust;
2498    if (pswp->cy >= adjust)
2499      pswp->cy -= adjust;
2500    else
2501      pswp->cy = 0;
2502  }
2503}
2504
2505static VOID MoveChildrenAwayFromTree(HWND hwndClient)
2506{
2507  SWP swpC, swpT, swp;
2508  USHORT id;
2509  HWND hwndChild;
2510  HENUM henum;
2511
2512  if (fFreeTree)
2513    return;
2514  WinQueryWindowPos(hwndClient, &swpC);
2515  if (swpC.fl & (SWP_MINIMIZE | SWP_HIDE))
2516    return;
2517  WinQueryWindowPos(hwndTree, &swpT);
2518  henum = WinBeginEnumWindows(hwndClient);
2519  while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2520    id = WinQueryWindowUShort(hwndChild, QWS_ID);
2521    if (!id || id == TREE_FRAME)
2522      continue;
2523    WinQueryWindowPos(hwndChild, &swp);
2524    if (!(swp.fl & (SWP_MAXIMIZE | SWP_HIDE | SWP_MINIMIZE))) {
2525      if (swp.x < swpT.cx) {
2526        swp.x = swpT.cx;
2527        if (swp.x + swp.cx > swpC.cx)
2528          swp.cx = swpC.cx - swp.x;
2529        if (swp.cx > 24)
2530          WinSetWindowPos(hwndChild, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
2531                          SWP_SIZE | SWP_MOVE | SWP_SHOW);
2532      }
2533    }
2534  }
2535  WinEndEnumWindows(henum);
2536}
2537
2538static VOID ArrangeIcons(HWND hwndClient)
2539{
2540  HENUM henum;
2541  HWND hwndChild;
2542  SWP swp;
2543
2544  henum = WinBeginEnumWindows(hwndClient);
2545  while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2546    WinQueryWindowPos(hwndChild, &swp);
2547    if (swp.fl & (SWP_MINIMIZE | SWP_HIDE)) {
2548      WinSetWindowUShort(hwndChild, QWS_XMINIMIZE, (USHORT) - 1);
2549      WinSetWindowUShort(hwndChild, QWS_YMINIMIZE, (USHORT) - 1);
2550      WinSetWindowPos(hwndChild, HWND_TOP, 0, 0, 0, 0,
2551                      SWP_MOVE | SWP_SHOW | SWP_FOCUSDEACTIVATE);
2552    }
2553  }
2554  WinEndEnumWindows(henum);
2555}
2556
2557static VOID NextChild(HWND hwndClient, BOOL previous)
2558{
2559  HENUM henum;
2560  HWND hwndActive, hwndNext, hwndPrev = (HWND) 0;
2561  BOOL next = FALSE, once = FALSE;
2562
2563  previous = !previous;
2564
2565  hwndActive = WinQueryActiveWindow(hwndClient);
2566  if (!hwndActive)
2567    next = TRUE;
2568  henum = WinBeginEnumWindows(hwndClient);
2569  for (;;) {
2570    hwndNext = WinGetNextWindow(henum);
2571    if (hwndNext) {
2572      if (!WinQueryWindowUShort(hwndNext, QWS_ID))
2573        continue;
2574      if (next)
2575        break;
2576      if (hwndNext == hwndActive) {
2577        if (!previous && hwndPrev) {
2578          hwndNext = hwndPrev;
2579          break;
2580        }
2581        else if (previous)
2582          next = TRUE;
2583      }
2584      hwndPrev = hwndNext;
2585    }
2586    else {
2587      if ((!next && previous) || once)
2588        break;
2589      else if (!previous) {
2590        hwndNext = hwndPrev;
2591        break;
2592      }
2593      else
2594        once = next = TRUE;
2595    }
2596  }
2597  WinEndEnumWindows(henum);
2598
2599  if (hwndNext && hwndNext != hwndActive) {
2600    WinSetWindowPos(hwndNext, HWND_TOP, 0, 0, 0, 0,
2601                    SWP_ZORDER | SWP_ACTIVATE);
2602    WinSetWindowPos(hwndActive, ((previous) ? HWND_BOTTOM : hwndNext), 0, 0,
2603                    0, 0, SWP_ZORDER);
2604  }
2605}
2606
2607BOOL CloseChildren(HWND hwndClient)
2608{
2609  HENUM henum;
2610  HWND hwndChild;
2611  BOOL ret = FALSE;
2612
2613  fNoTileUpdate = TRUE;
2614  henum = WinBeginEnumWindows(hwndClient);
2615  while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2616    if (hwndChild != hwndTree) {
2617      WinSendMsg(WinWindowFromID(hwndChild, FID_CLIENT),
2618                 WM_SAVEAPPLICATION, MPVOID, MPVOID);
2619      if (WinSendMsg(WinWindowFromID(hwndChild, FID_CLIENT),
2620                     WM_CLOSE, MPVOID, MPVOID)) {
2621        ret = TRUE;
2622        break;
2623      }
2624    }
2625  }
2626  WinEndEnumWindows(henum);
2627  fNoTileUpdate = FALSE;
2628  return ret;
2629}
2630
2631BOOL CloseDirCnrChildren(HWND hwndClient)
2632{
2633  /* returns TRUE if a directory container window was told to close */
2634
2635  HENUM henum;
2636  HWND hwndChild, hwndDir, hwndTemp;
2637  BOOL ret = FALSE;
2638
2639  fNoTileUpdate = TRUE;
2640  henum = WinBeginEnumWindows(hwndClient);
2641  while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2642    if (hwndChild != hwndTree) {
2643      hwndTemp = WinWindowFromID(hwndChild, FID_CLIENT);
2644      if (hwndTemp) {
2645        hwndDir = WinWindowFromID(hwndTemp, DIR_CNR);
2646        if (hwndDir) {
2647          WinSendMsg(WinWindowFromID(hwndChild, FID_CLIENT),
2648                     WM_CLOSE, MPVOID, MPVOID);
2649          ret = TRUE;
2650        }
2651      }
2652    }
2653  }
2654  WinEndEnumWindows(henum);
2655  fNoTileUpdate = FALSE;
2656  return ret;
2657}
2658
2659/** Save directory container state
2660 * @param hwndClient Client window handle
2661 * @param pszStateName State name to save, NULL to save global state
2662 * @returns TRUE if one or more directory container windows were saved
2663 * @seealso RestoreDirCnrState
2664 */
2665
2666BOOL SaveDirCnrState(HWND hwndClient, PSZ pszStateName)
2667{
2668  HENUM henum;
2669  HWND hwndChild, hwndDir, hwndC;
2670  ULONG numsaves = 0, flWindowAttr;
2671  CHAR szPrefix[20];
2672  CHAR s[80];
2673  CHAR szDir[CCHMAXPATH];
2674  SWP swp;
2675  BOOL fSaved = FALSE;
2676  DIRCNRDATA *dcd;
2677
2678  if (!pszStateName)
2679    strcpy(szPrefix, NullStr);
2680  else {
2681    if (strlen(pszStateName) > sizeof(szPrefix) - 2) {
2682      Runtime_Error(pszSrcFile, __LINE__, "SaveDirCnrState");
2683      return fSaved;;
2684    }
2685    sprintf(szPrefix, "%s.", pszStateName);
2686  }
2687
2688  henum = WinBeginEnumWindows(hwndClient);
2689  while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2690    if (hwndChild != hwndTree) {
2691      hwndC = WinWindowFromID(hwndChild, FID_CLIENT);
2692      if (hwndC) {
2693        hwndDir = WinWindowFromID(hwndC, DIR_CNR);
2694        if (hwndDir) {
2695          WinQueryWindowPos(hwndChild, &swp);
2696          *szDir = 0;
2697          WinSendMsg(hwndC, UM_CONTAINERDIR, MPFROMP(szDir), MPVOID);
2698          if (*szDir) {
2699           if (driveflags[toupper(*szDir) - 'A'] & DRIVE_NOPRESCAN)
2700             continue;
2701            sprintf(s, "%sDirCnrPos.%lu", szPrefix, numsaves);
2702            PrfWriteProfileData(fmprof, FM3Str, s, (PVOID) & swp,
2703                                sizeof(SWP));
2704            dcd =
2705              WinQueryWindowPtr(WinWindowFromID(hwndC, DIR_CNR), QWL_USER);
2706            if (dcd) {
2707              sprintf(s, "%sDirCnrSort.%lu", szPrefix, numsaves);
2708              PrfWriteProfileData(fmprof, FM3Str, s, (PVOID) & dcd->sortFlags,
2709                                  sizeof(INT));
2710              sprintf(s, "%sDirCnrFilter.%lu", szPrefix, numsaves);
2711              PrfWriteProfileData(fmprof, FM3Str, s, (PVOID) & dcd->mask,
2712                                  sizeof(MASK));
2713              sprintf(s, "%sDirCnrView.%lu", szPrefix, numsaves);
2714              flWindowAttr = dcd->flWindowAttr;
2715              if (!fLeaveTree && (flWindowAttr & CV_TREE)) {
2716                flWindowAttr &= (~(CV_TREE | CV_ICON | CV_DETAIL | CV_TEXT));
2717                if (dcd->lastattr) {
2718                  if (dcd->lastattr & CV_TEXT)
2719                    flWindowAttr |= CV_TEXT;
2720                  else if (dcd->lastattr & CV_DETAIL)
2721                    flWindowAttr |= CV_DETAIL;
2722                  else if (dcd->lastattr & CV_ICON)
2723                    flWindowAttr |= CV_ICON;
2724                  else
2725                    flWindowAttr |= CV_NAME;
2726                }
2727                else
2728                  flWindowAttr |= CV_NAME;
2729              }
2730              PrfWriteProfileData(fmprof, FM3Str, s, (PVOID) & flWindowAttr,
2731                                  sizeof(ULONG));
2732            }
2733            sprintf(s, "%sDirCnrDir.%lu", szPrefix, numsaves++);
2734            PrfWriteProfileString(fmprof, FM3Str, s, szDir);
2735            fSaved = TRUE;
2736          }
2737        }
2738      }
2739    }
2740  } // while
2741  WinEndEnumWindows(henum);
2742
2743  if (fSaved) {
2744    if (WinQueryWindowPos(hwndTree, &swp)) {
2745      sprintf(s, "%sLastTreePos", szPrefix);
2746      PrfWriteProfileData(fmprof, FM3Str, s, (PVOID) & swp, sizeof(SWP));
2747    }
2748    sprintf(s, "%sNumDirsLastTime", szPrefix);
2749    PrfWriteProfileData(fmprof, FM3Str, s, (PVOID) & numsaves, sizeof(ULONG));
2750    WinQueryWindowPos(WinQueryWindow(hwndClient, QW_PARENT), &swp);
2751    sprintf(s, "%sMySizeLastTime", szPrefix);
2752    PrfWriteProfileData(fmprof, FM3Str, s, (PVOID) & swp, sizeof(SWP));
2753  }
2754
2755  return fSaved;
2756}
2757
2758static VOID TransformSwp(PSWP pswp, double xtrans, double ytrans)
2759{
2760  SWP swp;
2761  HWND hwnd;
2762
2763  if ((LONG) pswp->x < 0L) {
2764    pswp->cx -= abs(pswp->x);
2765    pswp->x = 0;
2766  }
2767  if ((LONG) pswp->y < 0L) {
2768    pswp->cy -= abs(pswp->y);
2769    pswp->y = 0;
2770  }
2771  pswp->x = (LONG) (((double)pswp->x * 100.0) / xtrans);
2772  pswp->cx = (LONG) (((double)pswp->cx * 100.0) / xtrans);
2773  pswp->y = (LONG) (((double)pswp->y * 100.0) / ytrans);
2774  pswp->cy = (LONG) (((double)pswp->cy * 100.0) / ytrans);
2775  if (pswp->hwnd) {
2776    hwnd = WinQueryWindow(pswp->hwnd, QW_PARENT);
2777    if (hwnd) {
2778      if (WinQueryWindowPos(hwnd, &swp)) {
2779        if (pswp->x > swp.cx)
2780          pswp->x = (swp.cx > 24) ? swp.cx - 24 : swp.cx;
2781        if (pswp->y > swp.cy)
2782          pswp->y = (swp.cy > 24) ? swp.cy - 24 : swp.cy;
2783        if (pswp->x + pswp->cx > swp.cx)
2784          pswp->cx = swp.cx - pswp->x;
2785        if (pswp->y + pswp->cy > swp.cy)
2786          pswp->cy = swp.cy - pswp->y;
2787      }
2788    }
2789  }
2790}
2791
2792/** Restore directory container state
2793 * @param hwndClient Client window handle
2794 * @param pszStateName State name to restore, NULL to restore global state
2795 * @returns TRUE if one or more directory containers were opened
2796 * @seealso SaveDirCnrState
2797 */
2798
2799static BOOL RestoreDirCnrState(HWND hwndClient, PSZ pszStateName, BOOL noview)
2800{
2801  CHAR s[80];
2802  CHAR szDir[CCHMAXPATH];
2803  CHAR szPrefix[20];
2804  HWND hwndDir, hwndC;
2805  SWP swp, swpO, swpN;
2806  ULONG size, numsaves = 0L, x;
2807  double xtrans, ytrans;
2808  BOOL fRestored = FALSE;
2809  DIRCNRDATA *dcd;
2810
2811  if (!pszStateName)
2812    strcpy(szPrefix, NullStr);
2813  else {
2814    if (strlen(pszStateName) > sizeof(szPrefix) - 2) {
2815      Runtime_Error(pszSrcFile, __LINE__, "RestoreDirCnrState");
2816      return fRestored;
2817    }
2818    sprintf(szPrefix, "%s.", pszStateName);
2819  }
2820
2821  size = sizeof(SWP);
2822  sprintf(s, "%sMySizeLastTime", szPrefix);
2823  if (!PrfQueryProfileData(fmprof,
2824                           FM3Str,
2825                           s,
2826                           (PVOID) & swpO,
2827                           &size) ||
2828      size != sizeof(SWP) || !swp.cx || !swp.cy)
2829  {
2830    WinQueryWindowPos(WinQueryWindow(hwndClient, QW_PARENT), &swpO);
2831  }
2832  if (!pszStateName || !strcmp(pszStateName, GetPString(IDS_FM2TEMPTEXT)))
2833    PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2834  WinQueryWindowPos(WinQueryWindow(hwndClient, QW_PARENT), &swpN);
2835  if (swpN.fl & (SWP_MINIMIZE | SWP_HIDE))
2836    swpN = swpO;
2837  xtrans = ((double)swpO.cx * 100.0) / (double)swpN.cx;
2838  ytrans = ((double)swpO.cy * 100.0) / (double)swpN.cy;
2839  size = sizeof(SWP);
2840  sprintf(s, "%sLastTreePos", szPrefix);
2841  if (PrfQueryProfileData(fmprof, FM3Str, s, (PVOID) & swp, &size)) {
2842    if (!pszStateName || !strcmp(pszStateName, GetPString(IDS_FM2TEMPTEXT)))
2843      PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2844    swp.hwnd = hwndTree;
2845    TransformSwp(&swp, xtrans, ytrans);
2846    if (!fFreeTree) {
2847      WinQueryWindowPos(hwndClient, &swpN);
2848      swp.x = 0;
2849      swp.y = (swpN.cy - swp.cy);
2850    }
2851    if (!(swp.fl & (SWP_MINIMIZE | SWP_HIDE))) {
2852      swp.fl &= (~SWP_ACTIVATE);
2853      WinSetWindowPos(hwndTree,
2854                      HWND_TOP,
2855                      swp.x,
2856                      swp.y,
2857                      swp.cx,
2858                      swp.cy,
2859                      swp.fl | SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
2860    }
2861    else {
2862      WinSetWindowPos(hwndTree,
2863                      HWND_TOP, 0, 0, 0, 0, SWP_MINIMIZE | SWP_SHOW);
2864      WinSetWindowUShort(hwndTree, QWS_XRESTORE, (USHORT) swp.x);
2865      WinSetWindowUShort(hwndTree, QWS_CXRESTORE, (USHORT) swp.cx);
2866      WinSetWindowUShort(hwndTree, QWS_YRESTORE, (USHORT) swp.y);
2867      WinSetWindowUShort(hwndTree, QWS_CYRESTORE, (USHORT) swp.cy);
2868    }
2869  }
2870  size = sizeof(ULONG);
2871  sprintf(s, "%sNumDirsLastTime", szPrefix);
2872  if (PrfQueryProfileData(fmprof,
2873                          FM3Str, s, (PVOID) & numsaves, &size) && numsaves) {
2874    if (!pszStateName || !strcmp(pszStateName, GetPString(IDS_FM2TEMPTEXT)))
2875      PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2876    for (x = 0; x < numsaves; x++) {
2877      sprintf(s, "%sDirCnrPos.%lu", szPrefix, x);
2878      size = sizeof(SWP);
2879      if (PrfQueryProfileData(fmprof, FM3Str, s, (PVOID) & swp, &size)) {
2880        if (!pszStateName || !strcmp(pszStateName, GetPString(IDS_FM2TEMPTEXT)))
2881          PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2882        sprintf(s, "%sDirCnrDir.%lu", szPrefix, x);
2883        size = sizeof(szDir);
2884        if (PrfQueryProfileData(fmprof, FM3Str, s, (PVOID) szDir, &size)) {
2885          if (!pszStateName || !strcmp(pszStateName, GetPString(IDS_FM2TEMPTEXT)))
2886            PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2887          if (driveflags[toupper(*szDir) - 'A'] & DRIVE_NOPRESCAN) {
2888            PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2889            continue;
2890          }
2891          hwndDir = (HWND) WinSendMsg(hwndClient,
2892                                      UM_SETDIR,
2893                                      MPFROMP(szDir), MPFROMLONG(1L));
2894          if (hwndDir) {
2895            hwndC = WinWindowFromID(hwndDir, FID_CLIENT);
2896            if (hwndC) {
2897              dcd = WinQueryWindowPtr(WinWindowFromID(hwndC, DIR_CNR),
2898                                      QWL_USER);
2899              if (dcd) {
2900                size = sizeof(INT);
2901                sprintf(s, "%sDirCnrSort.%lu", szPrefix, x);
2902                if (PrfQueryProfileData(fmprof,
2903                                        FM3Str,
2904                                        s,
2905                                        (PVOID) & dcd->sortFlags,
2906                                        &size) && size == sizeof(INT)) {
2907                  if (!dcd->sortFlags)
2908                    dcd->sortFlags = SORT_PATHNAME;
2909                }
2910                if (!pszStateName || !strcmp(pszStateName, GetPString(IDS_FM2TEMPTEXT)))
2911                  PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2912                size = sizeof(MASK);
2913                sprintf(s, "%sDirCnrFilter.%lu", szPrefix, x);
2914                if (PrfQueryProfileData(fmprof,
2915                                        FM3Str,
2916                                        s,
2917                                        (PVOID) & dcd->mask, &size) && size) {
2918                  if (*dcd->mask.szMask)
2919                    WinSendMsg(WinWindowFromID(hwndC, DIR_CNR),
2920                               UM_FILTER, MPFROMP(dcd->mask.szMask), MPVOID);
2921                }
2922                *(dcd->mask.prompt) = 0;
2923                if (!pszStateName || !strcmp(pszStateName, GetPString(IDS_FM2TEMPTEXT)))
2924                  PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2925                size = sizeof(ULONG);
2926                sprintf(s, "%sDirCnrView.%lu", szPrefix, x);
2927                if (!noview) {
2928                  if (PrfQueryProfileData(fmprof,
2929                                          FM3Str,
2930                                          s,
2931                                          (PVOID) & dcd->flWindowAttr,
2932                                          &size) && size == sizeof(ULONG)) {
2933
2934                    CNRINFO cnri;
2935
2936                    memset(&cnri, 0, sizeof(CNRINFO));
2937                    cnri.cb = sizeof(CNRINFO);
2938                    if (WinSendMsg(WinWindowFromID(hwndC, DIR_CNR),
2939                                   CM_QUERYCNRINFO,
2940                                   MPFROMP(&cnri),
2941                                   MPFROMLONG(sizeof(CNRINFO)))) {
2942                      cnri.flWindowAttr = dcd->flWindowAttr;
2943                      WinSendMsg(WinWindowFromID(hwndC, DIR_CNR),
2944                                 CM_SETCNRINFO,
2945                                 MPFROMP(&cnri),
2946                                 MPFROMLONG(CMA_FLWINDOWATTR));
2947                    }
2948                  }
2949                }
2950                if (!pszStateName || !strcmp(pszStateName, GetPString(IDS_FM2TEMPTEXT)))
2951                  PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
2952              }
2953            }
2954            fRestored = TRUE;
2955            swp.hwnd = hwndDir;
2956            TransformSwp(&swp, xtrans, ytrans);
2957            if (!fAutoTile && !(swp.fl & (SWP_HIDE | SWP_MINIMIZE)))
2958              WinSetWindowPos(hwndDir,
2959                              HWND_TOP,
2960                              swp.x,
2961                              swp.y,
2962                              swp.cx,
2963                              swp.cy,
2964                              swp.fl | SWP_MOVE |
2965                              SWP_SIZE | SWP_SHOW | SWP_ZORDER |
2966                              SWP_ACTIVATE);
2967            else if (swp.fl & (SWP_HIDE | SWP_MINIMIZE)) {
2968              WinSetWindowPos(hwndDir,
2969                              HWND_TOP, 0, 0, 0, 0, SWP_MINIMIZE | SWP_SHOW);
2970              WinSetWindowUShort(hwndDir, QWS_XRESTORE, (USHORT) swp.x);
2971              WinSetWindowUShort(hwndDir, QWS_CXRESTORE, (USHORT) swp.cx);
2972              WinSetWindowUShort(hwndDir, QWS_YRESTORE, (USHORT) swp.y);
2973              WinSetWindowUShort(hwndDir, QWS_CYRESTORE, (USHORT) swp.cy);
2974            }
2975            else
2976              WinSetWindowPos(hwndDir,
2977                              HWND_TOP,
2978                              0, 0, 0, 0, SWP_ZORDER | SWP_ACTIVATE);
2979          }
2980        }
2981      }
2982    } // for
2983  }
2984  return fRestored;
2985}
2986
2987static ULONG CountChildren(HWND hwndClient, ULONG * ulNumMinChildren)
2988{
2989  HENUM henum;
2990  HWND hwndChild;
2991  SWP swp;
2992  register ULONG ulCnt = 0L;
2993  USHORT id;
2994
2995  if (ulNumMinChildren)
2996    *ulNumMinChildren = 0L;
2997  henum = WinBeginEnumWindows(hwndClient);
2998  while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2999    id = WinQueryWindowUShort(hwndChild, QWS_ID);
3000    if (!id || (!fFreeTree && id == TREE_FRAME))
3001      continue;
3002    ulCnt++;
3003    if (ulNumMinChildren) {
3004      if (WinQueryWindowPos(hwndChild, &swp) && (swp.fl & SWP_MINIMIZE))
3005        (*ulNumMinChildren)++;
3006    }
3007  }
3008  WinEndEnumWindows(henum);
3009  return ulCnt;
3010}
3011
3012VOID GetNextWindowPos(HWND hwndClient, PSWP pswp, ULONG * ulCntR,
3013                      ULONG * ulNumMinChildrenR)
3014{
3015  register ULONG ulCnt;
3016  ULONG ulNumMinChildren;
3017  RECTL Rectl;
3018  register ULONG ulXDiff, ulYDiff, ulWindowsPerStack;
3019
3020  if (!ulCntR || !ulNumMinChildrenR)
3021    ulCnt = CountChildren(hwndClient, &ulNumMinChildren);
3022  else {
3023    ulCnt = *ulCntR;
3024    ulNumMinChildren = *ulNumMinChildrenR;
3025    if (ulCnt == (ULONG) - 1L) {
3026      ulCnt = CountChildren(hwndClient, &ulNumMinChildren);
3027      /* return these values to the caller for later use */
3028      *ulCntR = ulCnt;
3029      *ulNumMinChildrenR = ulNumMinChildren;
3030    }
3031  }
3032  WinQueryWindowRect(hwndClient, &Rectl);
3033  AdjustSizeOfClient(NULL, &Rectl);
3034  if (!fFreeTree) {
3035
3036    SWP swp;
3037
3038    WinQueryWindowPos(hwndTree, &swp);
3039    if (ulNumMinChildren || (swp.fl & (SWP_HIDE | SWP_MINIMIZE)))
3040      Rectl.yBottom += WinQuerySysValue(HWND_DESKTOP, SV_CYICON) * 2;
3041  }
3042  else if (ulNumMinChildren)
3043    Rectl.yBottom += WinQuerySysValue(HWND_DESKTOP, SV_CYICON) * 2;
3044
3045  ulXDiff = WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER) +
3046    WinQuerySysValue(HWND_DESKTOP, SV_CXMINMAXBUTTON) / 2;
3047  ulYDiff = WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER) +
3048    WinQuerySysValue(HWND_DESKTOP, SV_CYMINMAXBUTTON);
3049  ulWindowsPerStack = (Rectl.yTop - Rectl.yBottom) / (3 * ulYDiff);
3050  pswp->cx = Rectl.xRight - (ulWindowsPerStack * ulXDiff);
3051  pswp->cy = (Rectl.yTop - Rectl.yBottom) - (ulWindowsPerStack * ulYDiff);
3052  ulWindowsPerStack++;
3053  pswp->x = Rectl.xLeft + ((ulCnt % ulWindowsPerStack) * ulXDiff);
3054  pswp->y = (Rectl.yTop - pswp->cy - ((ulCnt % ulWindowsPerStack) * ulYDiff));
3055}
3056
3057static VOID CascadeChildren(HWND hwndClient)
3058{
3059  ULONG ulCnt = 0L, ulNumMinChildren;
3060  HWND hwndChild;
3061  HENUM henum;
3062  SWP swp;
3063  USHORT id;
3064  RECTL Rectl;
3065
3066  WinQueryWindowPos(hwndClient, &swp);
3067  if (swp.fl & (SWP_HIDE | SWP_MINIMIZE))
3068    return;
3069
3070  CountChildren(hwndClient, &ulNumMinChildren);
3071  if (!fFreeTree) {
3072    WinQueryWindowRect(hwndClient, &Rectl);
3073    AdjustSizeOfClient(NULL, &Rectl);
3074    WinQueryWindowPos(hwndTree, &swp);
3075    if (!(swp.fl & (SWP_MAXIMIZE | SWP_HIDE | SWP_MINIMIZE))) {
3076      if (swp.y + swp.cy < Rectl.yTop - Rectl.yBottom)
3077        swp.cy = (Rectl.yTop - Rectl.yBottom) - swp.y;
3078      if (swp.x != 0)
3079        swp.x = 0;
3080      if (swp.y < 0)
3081        swp.y = 0;
3082      if (swp.x + swp.cx > Rectl.xRight - Rectl.xLeft)
3083        swp.cx = Rectl.xRight - Rectl.xLeft;
3084      WinSetWindowPos(hwndTree, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
3085                      SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_RESTORE);
3086    }
3087  }
3088  henum = WinBeginEnumWindows(hwndClient);
3089  while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
3090    id = WinQueryWindowUShort(hwndChild, QWS_ID);
3091    if (!id || (!fFreeTree && id == TREE_FRAME))
3092      continue;
3093    WinQueryWindowPos(hwndChild, &swp);
3094    if (!(swp.fl & (SWP_MINIMIZE | SWP_HIDE))) {
3095      GetNextWindowPos(hwndClient, &swp, &ulCnt, &ulNumMinChildren);
3096      WinSetWindowPos(hwndChild, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
3097                      SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_RESTORE |
3098                      SWP_ZORDER | SWP_ACTIVATE);
3099      ulCnt++;
3100    }
3101  }
3102  WinEndEnumWindows(henum);
3103}
3104
3105VOID TileChildren(HWND hwndClient, BOOL absolute)
3106{
3107  register ULONG ulChildCnt, ulSquare, ulNumRows, ulNumCols, ulExtraCols,
3108    ulWidth, ulHeight;
3109  ULONG ulNumMinChildren;
3110  RECTL Rectl;
3111  HWND hwndChild;
3112
3113  if (fNoTileUpdate || hwndClient == HWND_DESKTOP)
3114    return;
3115  {
3116    SWP swp;
3117
3118    WinQueryWindowPos(hwndClient, &swp);
3119    if (swp.fl & (SWP_HIDE | SWP_MINIMIZE))
3120      return;
3121  }
3122  ulChildCnt = CountChildren(hwndClient, &ulNumMinChildren);
3123  ulChildCnt -= ulNumMinChildren;
3124  if (!ulChildCnt)
3125    return;
3126
3127  fNoTileUpdate = TRUE;
3128
3129  for (ulSquare = 2; ulSquare * ulSquare <= ulChildCnt; ulSquare++) {
3130    ;
3131  }
3132  if (!fTileBackwards) {
3133    ulNumCols = ulSquare - 1L;
3134    ulNumRows = ulChildCnt / ulNumCols;
3135  }
3136  else {
3137    ulNumRows = ulSquare - 1L;
3138    ulNumCols = ulChildCnt / ulNumRows;
3139  }
3140  ulExtraCols = ulChildCnt % ulNumCols;
3141
3142  WinQueryWindowRect(hwndClient, &Rectl);
3143
3144  if (!fFreeTree) {
3145
3146    SWP swp;
3147
3148    WinQueryWindowPos(hwndTree, &swp);
3149    if (!(swp.fl & (SWP_MAXIMIZE | SWP_HIDE | SWP_MINIMIZE))) {
3150      if (swp.y < 0)
3151        swp.y = 0;
3152      if (swp.y + swp.cy < Rectl.yTop - Rectl.yBottom)
3153        swp.cy = (Rectl.yTop - Rectl.yBottom) - swp.y;
3154      if (swp.x != 0)
3155        swp.x = 0;
3156      if (swp.x + swp.cx > Rectl.xRight - Rectl.xLeft)
3157        swp.cx = Rectl.xRight - Rectl.xLeft;
3158      WinSetWindowPos(hwndTree,
3159                      HWND_TOP,
3160                      swp.x,
3161                      swp.y,
3162                      swp.cx,
3163                      swp.cy, SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_RESTORE);
3164      WinQueryWindowPos(hwndTree, &swp);
3165    }
3166    if (ulNumMinChildren || (swp.fl & (SWP_HIDE | SWP_MINIMIZE)))
3167      Rectl.yBottom += WinQuerySysValue(HWND_DESKTOP, SV_CYICON) * 2;
3168  }
3169  else if (ulNumMinChildren)
3170    Rectl.yBottom += WinQuerySysValue(HWND_DESKTOP, SV_CYICON) * 2;
3171
3172  AdjustSizeOfClient(NULL, &Rectl);
3173
3174  if (Rectl.xRight > 0L && (Rectl.yBottom < Rectl.yTop)) {
3175
3176    HENUM henum;
3177
3178    henum = WinBeginEnumWindows(hwndClient);
3179    if ((hwndChild = WinGetNextWindow(henum)) != (HWND) 0) {
3180
3181      ULONG ulCurRow, ulCurCol;
3182      SWP swp;
3183      USHORT id;
3184
3185      ulHeight = (Rectl.yTop - Rectl.yBottom) / ulNumRows;
3186
3187      for (ulCurRow = 0; ulCurRow < ulNumRows; ulCurRow++) {
3188        if ((ulNumRows - ulCurRow) <= ulExtraCols)
3189          ulNumCols++;
3190        for (ulCurCol = 0; ulCurCol < ulNumCols; ulCurCol++) {
3191          ulWidth = Rectl.xRight / ulNumCols;
3192
3193          while (hwndChild) {
3194            id = WinQueryWindowUShort(hwndChild, QWS_ID);
3195            if (id && (id != TREE_FRAME || fFreeTree)) {
3196              WinQueryWindowPos(hwndChild, &swp);
3197              if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE)))
3198                break;
3199            }
3200            hwndChild = WinGetNextWindow(henum);
3201          }
3202
3203          if (hwndChild) {
3204            if (!absolute && (swp.fl & SWP_MAXIMIZE)) {
3205              WinGetMaxPosition(hwndChild, &swp);
3206              WinSetWindowPos(hwndChild,
3207                              HWND_TOP,
3208                              swp.x,
3209                              swp.y,
3210                              swp.cx, swp.cy, SWP_MOVE | SWP_SIZE | SWP_SHOW);
3211              WinSetWindowUShort(hwndChild,
3212                                 QWS_XRESTORE,
3213                                 (USHORT) (ulWidth * ulCurCol) + Rectl.xLeft);
3214              WinSetWindowUShort(hwndChild,
3215                                 QWS_YRESTORE,
3216                                 (USHORT) (Rectl.yTop -
3217                                           (ulHeight * (ulCurRow + 1L))));
3218              WinSetWindowUShort(hwndChild, QWS_CXRESTORE, (USHORT) ulWidth);
3219              WinSetWindowUShort(hwndChild, QWS_CYRESTORE, (USHORT) ulHeight);
3220            }
3221            else
3222              WinSetWindowPos(hwndChild,
3223                              HWND_TOP,
3224                              (ulWidth * ulCurCol) + Rectl.xLeft,
3225                              Rectl.yTop - (ulHeight * (ulCurRow + 1L)),
3226                              ulWidth,
3227                              ulHeight,
3228                              SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_RESTORE);
3229            hwndChild = WinGetNextWindow(henum);
3230          }
3231        }
3232        if ((ulNumRows - ulCurRow) <= ulExtraCols) {
3233          ulNumCols--;
3234          ulExtraCols--;
3235        }
3236      }
3237    }
3238    WinEndEnumWindows(henum);
3239  }
3240
3241  fNoTileUpdate = FALSE;
3242}
3243
3244static VOID ResizeChildren(HWND hwndClient, SHORT oldcx, SHORT oldcy,
3245                           SHORT newcx, SHORT newcy)
3246{
3247  /*
3248   * resize all children of the client to maintain their proportional
3249   * sizes and positions
3250   */
3251
3252  if (!newcx || !newcy || !oldcx || !oldcy)
3253    return;
3254  {
3255    HENUM henum;
3256    HWND hwndChild;
3257    register LONG x, y, cx, cy, ucx, ucy, ux, uy;
3258    SWP swp;
3259
3260    henum = WinBeginEnumWindows(hwndClient);
3261    while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
3262      if (!WinQueryWindowUShort(hwndChild, QWS_ID))
3263        continue;
3264      if (WinQueryWindowPos(hwndChild, &swp)) {
3265        if (swp.fl & (SWP_MINIMIZE | SWP_HIDE)) {
3266          swp.x = WinQueryWindowUShort(hwndChild, QWS_XRESTORE);
3267          swp.y = WinQueryWindowUShort(hwndChild, QWS_YRESTORE);
3268          swp.cx = WinQueryWindowUShort(hwndChild, QWS_CXRESTORE);
3269          swp.cy = WinQueryWindowUShort(hwndChild, QWS_CYRESTORE);
3270        }
3271        else if (swp.fl & SWP_MAXIMIZE) {
3272          swp.x = WinQueryWindowUShort(hwndChild, QWS_XRESTORE);
3273          swp.y = WinQueryWindowUShort(hwndChild, QWS_YRESTORE);
3274          swp.cx = WinQueryWindowUShort(hwndChild, QWS_CXRESTORE);
3275          swp.cy = WinQueryWindowUShort(hwndChild, QWS_CYRESTORE);
3276        }
3277        cx = (swp.cx) ? (LONG) (((double)oldcx * 100.0) / (double)swp.cx) : 0;
3278        cy = (swp.cy) ? (LONG) (((double)oldcy * 100.0) / (double)swp.cy) : 0;
3279        x = (swp.x) ? (LONG) (((double)oldcx * 100.0) / (double)swp.x) : 0;
3280        y = (swp.y) ? (LONG) (((double)oldcy * 100.0) / (double)swp.y) : 0;
3281        if (x < 0)
3282          x = 0;
3283        if (y < 0)
3284          y = 0;
3285        ux = (x) ? (LONG) (((double)newcx * 100.0) / (double)x) : 0;
3286        uy = (y) ? (LONG) (((double)newcy * 100.0) / (double)y) : 0;
3287        ucx = (cx) ? (LONG) (((double)newcx * 100.0) / (double)cx) : 0;
3288        ucy = (cy) ? (LONG) (((double)newcy * 100.0) / (double)cy) : 0;
3289        if (ux + ucx > newcx)
3290          ucx = newcx - ux;
3291        if (uy + ucy > newcy)
3292          ucy = newcy - uy;
3293
3294        if (!(swp.fl & (SWP_MINIMIZE | SWP_HIDE | SWP_MAXIMIZE)))
3295          WinSetWindowPos(hwndChild, HWND_TOP, ux, uy, ucx, ucy,
3296                          SWP_MOVE | SWP_SIZE | SWP_SHOW);
3297        else if (swp.fl & (SWP_HIDE | SWP_MINIMIZE)) {
3298          WinSetWindowUShort(hwndChild, QWS_XMINIMIZE, (USHORT) - 1);
3299          WinSetWindowUShort(hwndChild, QWS_YMINIMIZE, (USHORT) - 1);
3300          WinSetWindowPos(hwndChild, HWND_TOP, 0, 0, 0, 0,
3301                          SWP_SIZE | SWP_MOVE | SWP_FOCUSDEACTIVATE);
3302          WinSetWindowUShort(hwndChild, QWS_XRESTORE, ux);
3303          WinSetWindowUShort(hwndChild, QWS_YRESTORE, uy);
3304          WinSetWindowUShort(hwndChild, QWS_CXRESTORE, ucx);
3305          WinSetWindowUShort(hwndChild, QWS_CYRESTORE, ucy);
3306        }
3307        else {
3308          WinGetMaxPosition(hwndChild, &swp);
3309          WinSetWindowPos(hwndChild, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
3310                          SWP_MOVE | SWP_SIZE | SWP_SHOW);
3311          WinSetWindowUShort(hwndChild, QWS_XRESTORE, ux);
3312          WinSetWindowUShort(hwndChild, QWS_YRESTORE, uy);
3313          WinSetWindowUShort(hwndChild, QWS_CXRESTORE, ucx);
3314          WinSetWindowUShort(hwndChild, QWS_CYRESTORE, ucy);
3315        }
3316      }
3317    }
3318    WinEndEnumWindows(henum);
3319  }
3320  if (!fFreeTree) {
3321
3322    RECTL Rectl;
3323    SWP swp;
3324
3325    WinQueryWindowRect(hwndClient, &Rectl);
3326    AdjustSizeOfClient(NULL, &Rectl);
3327    WinQueryWindowPos(hwndTree, &swp);
3328    if (!(swp.fl & (SWP_MAXIMIZE | SWP_HIDE | SWP_MINIMIZE))) {
3329      if (swp.y + swp.cy < Rectl.yTop - Rectl.yBottom)
3330        swp.cy = (Rectl.yTop - Rectl.yBottom) - swp.y;
3331      if (swp.x != 0)
3332        swp.x = 0;
3333      if (swp.y < 0)
3334        swp.y = 0;
3335      if (swp.x + swp.cx > Rectl.xRight - Rectl.xLeft)
3336        swp.cx = Rectl.xRight - Rectl.xLeft;
3337      WinSetWindowPos(hwndTree, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy,
3338                      SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_RESTORE);
3339    }
3340  }
3341}
3342
3343static VOID MinResChildren(HWND hwndClient, ULONG cmd)
3344{
3345  HENUM henum;
3346  HWND hwndChild;
3347
3348  {
3349    SWP swp;
3350
3351    WinQueryWindowPos(hwndClient, &swp);
3352    if (swp.fl & (SWP_HIDE | SWP_MINIMIZE))
3353      return;
3354  }
3355  henum = WinBeginEnumWindows(hwndClient);
3356  while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
3357    if (!WinQueryWindowUShort(hwndChild, QWS_ID))
3358      continue;
3359    WinSetWindowPos(hwndChild, HWND_TOP, 0, 0, 0, 0, cmd);
3360  }
3361}
3362
3363//=== ChildFrameButtonProc: subclass handler for WALKBUTTON and QUICKBUTTON windows ===
3364
3365static MRESULT EXPENTRY ChildFrameButtonProc(HWND hwnd,
3366                                             ULONG msg,
3367                                             MPARAM mp1, MPARAM mp2)
3368{
3369  USHORT id;
3370  static BOOL emphasized = FALSE;
3371
3372  switch (msg) {
3373  case WM_BUTTON1CLICK:
3374  case WM_CHORD:
3375    shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
3376    break;
3377
3378  case WM_MOUSEMOVE:
3379    if (fOtherHelp) {
3380      if ((!hwndBubble || WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd)
3381          && !WinQueryCapture(HWND_DESKTOP)) {
3382        id = WinQueryWindowUShort(hwnd, QWS_ID);
3383        switch (id) {
3384        case IDM_OPENWALK:
3385          MakeBubble(hwnd, FALSE, GetPString(IDS_WALKBUTTONHELP));
3386          break;
3387        case IDM_USERLIST:
3388          MakeBubble(hwnd, FALSE, GetPString(IDS_QUICKBUTTONHELP));
3389          break;
3390        }
3391      }
3392    }
3393    break;
3394
3395  case WM_BUTTON3CLICK:
3396  case WM_BUTTON2CLICK:
3397    {
3398      USHORT cmd = 0;
3399
3400      shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
3401      id = WinQueryWindowUShort(hwnd, QWS_ID);
3402      switch (id) {
3403      case IDM_OPENWALK:
3404        switch (msg) {
3405        case WM_BUTTON2CLICK:
3406          if ((shiftstate & (KC_ALT | KC_SHIFT | KC_CTRL)) ==
3407              (KC_ALT | KC_SHIFT | KC_CTRL))
3408            cmd = IDM_GREP;
3409          else if ((shiftstate & (KC_ALT | KC_CTRL)) == (KC_ALT | KC_CTRL))
3410            CascadeChildren(hwndMain);
3411
3412#ifdef NEVER
3413          else if ((shiftstate & (KC_ALT | KC_SHIFT)) == (KC_ALT | KC_SHIFT))
3414            cmd = IDM_SYSINFO;
3415#endif
3416
3417          else if (shiftstate & KC_SHIFT)
3418            cmd = IDM_WINDOWDLG;
3419          else if (shiftstate & KC_CTRL)
3420            cmd = IDM_SEEALL;
3421          else if (shiftstate & KC_ALT)
3422            TileChildren(hwndMain, TRUE);
3423          else
3424            cmd = IDM_WALKDIR;
3425          break;
3426        case WM_BUTTON3CLICK:
3427          TileChildren(hwndMain, TRUE);
3428          break;
3429        }
3430        break;
3431      case IDM_USERLIST:
3432        switch (msg) {
3433        case WM_BUTTON2CLICK:
3434          if ((shiftstate & (KC_ALT | KC_SHIFT | KC_CTRL)) ==
3435              (KC_ALT | KC_SHIFT | KC_CTRL))
3436            cmd = IDM_COLORPALETTE;
3437          else if ((shiftstate & (KC_ALT | KC_CTRL)) == (KC_ALT | KC_CTRL))
3438            cmd = IDM_HIDEMENU;
3439          else if ((shiftstate & (KC_ALT | KC_SHIFT)) == (KC_ALT | KC_SHIFT))
3440            cmd = IDM_NOTEBOOK;
3441          else if (shiftstate & KC_SHIFT)
3442            cmd = IDM_TOOLTITLES;
3443          else if (shiftstate & KC_CTRL)
3444            cmd = IDM_TEXTTOOLS;
3445          else if (shiftstate & KC_ALT)
3446            cmd = IDM_FONTPALETTE;
3447          else
3448            cmd = IDM_TOOLBAR;
3449          break;
3450        case WM_BUTTON3CLICK:
3451          cmd = IDM_DRIVEBAR;
3452          break;
3453        }
3454        break;
3455      }                                 // switch id
3456
3457      if (cmd) {
3458        PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), FID_CLIENT),
3459                WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
3460      }
3461    }
3462    break;
3463
3464  case DM_DRAGOVER:
3465    id = WinQueryWindowUShort(hwnd, QWS_ID);
3466    if (id == IDM_OPENWALK) {
3467      if (!emphasized) {
3468        emphasized = TRUE;
3469        DrawTargetEmphasis(hwnd, emphasized);
3470      }
3471      if (AcceptOneDrop(hwnd, mp1, mp2))
3472        return MRFROM2SHORT(DOR_DROP, DO_MOVE);
3473    }
3474    return MRFROM2SHORT(DOR_NEVERDROP, 0);
3475
3476  case DM_DRAGLEAVE:
3477    if (emphasized) {
3478      emphasized = FALSE;
3479      DrawTargetEmphasis(hwnd, emphasized);
3480    }
3481    break;
3482
3483  case DM_DROPHELP:
3484    DropHelp(mp1, mp2, hwnd, GetPString(IDS_OPENDROPHELP));
3485    return 0;
3486
3487  case DM_DROP:
3488    {
3489      char szFrom[CCHMAXPATH + 2];
3490
3491      if (emphasized) {
3492        emphasized = FALSE;
3493        DrawTargetEmphasis(hwnd, emphasized);
3494      }
3495      if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom))) {
3496        if (MakeValidDir(szFrom) && !FindDirCnrByName(szFrom, TRUE)) {
3497          OpenDirCnr((HWND) 0, hwndMain, hwndTree, FALSE, szFrom);
3498        }
3499      }
3500    }
3501    return 0;
3502
3503  case WM_CLOSE:
3504    WinDestroyWindow(hwnd);
3505    return 0;
3506  }
3507  return PFNWPButton(hwnd, msg, mp1, mp2);
3508}
3509
3510static MRESULT EXPENTRY MainFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
3511                                         MPARAM mp2)
3512{
3513  PFNWP oldproc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
3514  static ULONG aheight = 0L;
3515
3516  switch (msg) {
3517  case WM_ADJUSTWINDOWPOS:
3518    {
3519      SWP *pswp;
3520
3521      pswp = (SWP *) mp1;
3522      if (fDataMin && !fAmClosing) {
3523        if (pswp->fl & (SWP_HIDE | SWP_MINIMIZE)) {
3524
3525          SWP swp;
3526
3527          WinQueryWindowPos(hwnd, &swp);
3528          PostMsg(hwnd, UM_FOCUSME, MPFROMLONG(swp.fl), MPVOID);
3529          HideNote();
3530        }
3531        else if (pswp->fl & (SWP_SHOW | SWP_RESTORE)) {
3532          if (DataHwnd)
3533            PostMsg(DataHwnd, WM_CLOSE, MPVOID, MPVOID);
3534        }
3535      }
3536      if (!fAmClosing) {
3537        if (pswp->fl & (SWP_HIDE | SWP_MINIMIZE))
3538          HideNote();
3539      }
3540    }
3541    break;
3542
3543  case UM_FOCUSME:
3544    CreateDataBar(HWND_DESKTOP, (ULONG) mp1);
3545    return 0;
3546
3547  case WM_BUTTON1UP:
3548  case WM_BUTTON2UP:
3549  case WM_BUTTON3UP:
3550  case WM_MOUSEMOVE:
3551  case WM_CHORD:
3552    shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
3553    break;
3554
3555  case WM_CHAR:
3556    shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
3557    break;
3558
3559  case WM_CONTROL:
3560    return WinSendMsg(WinWindowFromID(hwnd, FID_CLIENT), UM_CONTROL, mp1,
3561                      mp2);
3562
3563  case WM_COMMAND:
3564    return WinSendMsg(WinWindowFromID(hwnd, FID_CLIENT), msg, mp1, mp2);
3565
3566  case WM_CALCFRAMERECT:
3567    {
3568      MRESULT mr;
3569      PRECTL prectl;
3570      LONG sheight = 20, bheight = 20;
3571
3572      mr = oldproc(hwnd, msg, mp1, mp2);
3573
3574      /*
3575       * Calculate the position of the client rectangle.
3576       * Otherwise, we'll see a lot of redraw when we move the
3577       * client during WM_FORMATFRAME.
3578       */
3579
3580      if (mr && mp2) {
3581        prectl = (PRECTL) mp1;
3582        if (prectl->yBottom != prectl->yTop) {
3583          {
3584            HPS hps;
3585            POINTL aptl[TXTBOX_COUNT];
3586
3587            hps = WinGetPS(hwndStatus);
3588            if (hps) {
3589              GpiQueryTextBox(hps, 6, "$`WjgT", TXTBOX_COUNT, aptl);
3590              bheight = sheight = aptl[TXTBOX_TOPLEFT].y + 6;
3591              WinReleasePS(hps);
3592            }
3593          }
3594          prectl->yBottom += (sheight + 4);
3595          prectl->yTop -= (sheight + 4);
3596          if (fMoreButtons) {
3597
3598            HPS hps;
3599            POINTL aptl[TXTBOX_COUNT];
3600
3601            hps = WinGetPS(hwndName);
3602            if (hps) {
3603              GpiQueryTextBox(hps, 6, "$`WjgT", TXTBOX_COUNT, aptl);
3604              bheight = aptl[TXTBOX_TOPLEFT].y + 6;
3605              WinReleasePS(hps);
3606            }
3607            prectl->yBottom += (bheight + 4);
3608            prectl->yTop -= (bheight + 4);
3609          }
3610          if (fToolbar) {
3611            if (!fTextTools)
3612              prectl->yTop -= ((fToolTitles) ? 50 : 40);
3613            else
3614              prectl->yTop -= 32;
3615          }
3616          if (fDrivebar) {
3617            ResizeDrives(WinWindowFromID(hwnd, MAIN_DRIVES),
3618                         ((prectl->xRight -
3619                           (WinQuerySysValue(HWND_DESKTOP,
3620                                             SV_CYSIZEBORDER) * 2)) - 4));
3621            prectl->yTop -= (16 * (DriveLines * 18));
3622          }
3623          if (fUserComboBox) {
3624            if (!aheight) {
3625
3626              SWP swpTemp;
3627
3628              WinQueryWindowPos(WinWindowFromID(hwndDrivelist, CBID_EDIT),
3629                                &swpTemp);
3630              aheight = swpTemp.cy;
3631            }
3632            prectl->yTop -= (aheight + 6L);
3633          }
3634          if (fAutoView) {
3635            AutoviewHeight = min(AutoviewHeight,
3636                                 (prectl->yTop - prectl->yBottom) - 116);
3637            AutoviewHeight = max(AutoviewHeight, 36);
3638            prectl->yBottom += (AutoviewHeight + 6);
3639          }
3640        }
3641      }
3642      return mr;
3643    }
3644
3645  case WM_FORMATFRAME:
3646    {
3647      SHORT sCount, soldCount;
3648      PSWP pswp, pswpClient, pswpNew;
3649      SWP swpClient;
3650      LONG theight = 48L, dheight = 20L, width, sheight = 20, bheight = 20;
3651
3652      sCount = (SHORT) oldproc(hwnd, msg, mp1, mp2);
3653      soldCount = sCount;
3654
3655      /*
3656       * Reformat the frame to "squeeze" the client
3657       * and make room for status window sibling beneath
3658       * and toolbar above (if toolbar's on) and userlists
3659       * (if userlists are on).
3660       */
3661
3662      pswp = (PSWP) mp1;
3663      {
3664        SHORT x;
3665
3666        for (x = 0; x < soldCount; x++) {
3667          if (WinQueryWindowUShort(pswp->hwnd, QWS_ID) == FID_CLIENT) {
3668            pswpClient = pswp;
3669            break;
3670          }
3671          pswp++;
3672        }
3673      }
3674
3675      {
3676        HPS hps;
3677        POINTL aptl[TXTBOX_COUNT];
3678
3679        hps = WinGetPS(hwndStatus);
3680        if (hps) {
3681          GpiQueryTextBox(hps, 6, "$`WjgT", TXTBOX_COUNT, aptl);
3682          bheight = sheight = aptl[TXTBOX_TOPLEFT].y + 6;
3683          WinReleasePS(hps);
3684        }
3685        if (fMoreButtons) {
3686          hps = WinGetPS(hwndName);
3687          if (hps) {
3688            GpiQueryTextBox(hps, 6, "$`WjgT", TXTBOX_COUNT, aptl);
3689            bheight = aptl[TXTBOX_TOPLEFT].y + 6;
3690            WinReleasePS(hps);
3691          }
3692        }
3693      }
3694      pswpNew = (PSWP) mp1 + soldCount;
3695      *pswpNew = *pswpClient;
3696      swpClient = *pswpClient;
3697      pswpNew->hwnd = hwndStatus;
3698      pswpNew->hwndInsertBehind = HWND_BOTTOM;
3699      pswpNew->x = swpClient.x + 3;
3700      pswpNew->y = swpClient.y + 2;
3701      if (!fSplitStatus)
3702        width = swpClient.cx - (16 + (sheight * 2) + 4);
3703      else
3704        width = (swpClient.cx - (16 + (sheight * 2) + 4)) / 2;
3705      width = max(width, 10);
3706      if (fSplitStatus)
3707        pswpNew->cx = width - 6;
3708      else
3709        pswpNew->cx = width - 8;
3710      pswpNew->cy = sheight;
3711      pswpClient->y = pswpNew->y + pswpNew->cy + 3;
3712      pswpClient->cy = (swpClient.cy - pswpNew->cy) - 3;
3713      sCount++;
3714
3715      if (fSplitStatus) {
3716        pswpNew = (PSWP) mp1 + (soldCount + 1);
3717        *pswpNew = *pswpClient;
3718        pswpNew->hwnd = hwndStatus2;
3719        pswpNew->hwndInsertBehind = HWND_BOTTOM;
3720        pswpNew->x = width + 8;
3721        pswpNew->y = swpClient.y + 2;
3722        pswpNew->cx = width - 6;
3723        pswpNew->cy = sheight;
3724        sCount++;
3725      }
3726      else {
3727        WinShowWindow(hwndStatus2, FALSE);
3728        WinSetWindowText(hwndStatus2, NullStr);
3729      }
3730
3731      if (fToolbar) {
3732        if (fTextTools)
3733          theight = 32L;
3734        else if (!fToolTitles)
3735          theight = 40L;
3736        pswpNew = (PSWP) mp1 + (soldCount + 1 + (fSplitStatus != FALSE));
3737        *pswpNew = *pswpClient;
3738        pswpNew->hwnd = WinWindowFromID(hwnd, MAIN_TOOLS);
3739        pswpNew->hwndInsertBehind = HWND_BOTTOM;
3740        pswpNew->x = swpClient.x + 2;
3741        pswpNew->y = (swpClient.y + swpClient.cy) - (theight - 2);
3742        pswpNew->cx = swpClient.cx - 4;
3743        pswpNew->cy = theight - 4;
3744        pswpClient->cy -= theight;
3745        sCount++;
3746      }
3747      else
3748        WinShowWindow(WinWindowFromID(hwnd, MAIN_TOOLS), FALSE);
3749
3750      if (fDrivebar) {
3751        ResizeDrives(WinWindowFromID(hwnd, MAIN_DRIVES), pswpClient->cx - 4);
3752        pswpNew = (PSWP) mp1 + (soldCount + 1 +
3753                                (fSplitStatus != FALSE) +
3754                                (fToolbar != FALSE));
3755        *pswpNew = *pswpClient;
3756        pswpNew->hwnd = WinWindowFromID(hwnd, MAIN_DRIVES);
3757        pswpNew->hwndInsertBehind = HWND_BOTTOM;
3758        pswpNew->x = swpClient.x + 2;
3759        dheight += ((dheight - 2) * DriveLines);
3760        pswpNew->y = (swpClient.y + swpClient.cy) - (dheight - 2);
3761        if (fToolbar)
3762          pswpNew->y -= theight;
3763        pswpNew->cx = swpClient.cx - 4;
3764        pswpNew->cy = dheight - 4;
3765        pswpClient->cy -= dheight;
3766        sCount++;
3767      }
3768      else
3769        WinShowWindow(WinWindowFromID(hwnd, MAIN_DRIVES), FALSE);
3770
3771      if (fAutoView) {
3772        pswpNew = (PSWP) mp1 + (soldCount + 1 +
3773                                (fToolbar != FALSE) +
3774                                (fDrivebar != FALSE) +
3775                                (fSplitStatus != FALSE));
3776        *pswpNew = *pswpClient;
3777        pswpNew->hwnd = (fComments) ? hwndAutoMLE : hwndAutoview;
3778        pswpNew->x = pswpClient->x + 3;
3779        pswpNew->y = pswpClient->y + 3;
3780        if (fMoreButtons)
3781          pswpNew->y += (bheight + 4);
3782        pswpNew->cx = pswpClient->cx - 6;
3783        AutoviewHeight = min(AutoviewHeight, pswpClient->cy - 116);
3784        AutoviewHeight = max(AutoviewHeight, 36);
3785        pswpNew->cy = AutoviewHeight;
3786        pswpClient->y += (AutoviewHeight + 6);
3787        pswpClient->cy -= (AutoviewHeight + 6);
3788        sCount++;
3789        WinShowWindow((fComments) ? hwndAutoview : hwndAutoMLE, FALSE);
3790      }
3791      else {
3792        WinShowWindow(hwndAutoview, FALSE);
3793        WinShowWindow(hwndAutoMLE, FALSE);
3794      }
3795
3796      pswpNew = (PSWP) mp1 + (soldCount + 1 +
3797                              (fToolbar != FALSE) +
3798                              (fDrivebar != FALSE) +
3799                              (fSplitStatus != FALSE) + (fAutoView != FALSE));
3800      *pswpNew = *pswpClient;
3801      pswpNew->hwnd = WinWindowFromID(hwnd, IDM_OPENWALK);
3802      pswpNew->x = swpClient.cx - ((sheight * 2) + 4);
3803      pswpNew->y = swpClient.y;
3804      pswpNew->cx = sheight + 4;
3805      pswpNew->cy = sheight + 4;
3806      sCount++;
3807      pswpNew = (PSWP) mp1 + (soldCount + 2 +
3808                              (fToolbar != FALSE) +
3809                              (fDrivebar != FALSE) +
3810                              (fSplitStatus != FALSE) + (fAutoView != FALSE));
3811      *pswpNew = *pswpClient;
3812      pswpNew->hwnd = WinWindowFromID(hwnd, IDM_USERLIST);
3813      pswpNew->x = swpClient.cx - (sheight + 2);
3814      pswpNew->y = swpClient.y;
3815      pswpNew->cx = sheight + 4;
3816      pswpNew->cy = sheight + 4;
3817      sCount++;
3818      pswpNew = (PSWP) mp1 + (soldCount + 3 +
3819                              (fToolbar != FALSE) +
3820                              (fDrivebar != FALSE) +
3821                              (fSplitStatus != FALSE) + (fAutoView != FALSE));
3822      *pswpNew = *pswpClient;
3823      pswpNew->hwnd = WinWindowFromID(hwnd, MAIN_LED);
3824      pswpNew->x = swpClient.cx - ((sheight * 2) + 16);
3825      pswpNew->y = swpClient.y;
3826      pswpNew->cx = 12;
3827      pswpNew->cy = 12;
3828      sCount++;
3829      pswpNew = (PSWP) mp1 + (soldCount + 4 +
3830                              (fToolbar != FALSE) +
3831                              (fDrivebar != FALSE) +
3832                              (fSplitStatus != FALSE) + (fAutoView != FALSE));
3833      *pswpNew = *pswpClient;
3834      pswpNew->hwnd = WinWindowFromID(hwnd, MAIN_LEDHDR);
3835      pswpNew->x = swpClient.cx - ((sheight * 2) + 16);
3836      pswpNew->y = swpClient.y + 12;
3837      pswpNew->cx = 12;
3838      pswpNew->cy = sheight - 8;
3839      sCount++;
3840      if (fUserComboBox) {
3841        if (!aheight) {
3842
3843          SWP swpTemp;
3844
3845          WinQueryWindowPos(WinWindowFromID(hwndDrivelist, CBID_EDIT),
3846                            &swpTemp);
3847          aheight = swpTemp.cy;
3848        }
3849        pswpNew = (PSWP) mp1 + (soldCount + 5 +
3850                                (fToolbar != FALSE) +
3851                                (fSplitStatus != FALSE) +
3852                                (fDrivebar != FALSE) + (fAutoView != FALSE));
3853        *pswpNew = *pswpClient;
3854        pswpNew->hwnd = hwndDrivelist;
3855        pswpNew->x = swpClient.x;
3856        pswpNew->cx = 48;
3857        pswpClient->cy -= (aheight + 6L);
3858        pswpNew->y = pswpClient->y;
3859        pswpNew->cy = pswpClient->cy + (aheight + 5L);
3860        sCount++;
3861        pswpNew = (PSWP) mp1 + (soldCount + 6 +
3862                                (fToolbar != FALSE) +
3863                                (fDrivebar != FALSE) +
3864                                (fSplitStatus != FALSE) +
3865                                (fAutoView != FALSE));
3866        *pswpNew = *pswpClient;
3867        pswpNew->hwnd = hwndStatelist;
3868        pswpNew->x = swpClient.x + 48;
3869        pswpNew->cx = (swpClient.cx - 48) / 7;
3870        pswpNew->y = pswpClient->y;
3871        pswpNew->cy = pswpClient->cy + (aheight + 5L);
3872        sCount++;
3873        pswpNew = (PSWP) mp1 + (soldCount + 7 +
3874                                (fToolbar != FALSE) +
3875                                (fDrivebar != FALSE) +
3876                                (fSplitStatus != FALSE) +
3877                                (fAutoView != FALSE));
3878        *pswpNew = *pswpClient;
3879        pswpNew->hwnd = hwndCmdlist;
3880        pswpNew->x = swpClient.x + 48 + ((swpClient.cx - 48) / 7);
3881        pswpNew->cx = (swpClient.cx - 48) / 5 +
3882          ((swpClient.cx - 48) / 5) - ((swpClient.cx - 48) / 7);
3883        pswpNew->y = pswpClient->y;
3884        pswpNew->cy = pswpClient->cy + (aheight + 5L);
3885        sCount++;
3886        pswpNew = (PSWP) mp1 + (soldCount + 8 +
3887                                (fToolbar != FALSE) +
3888                                (fDrivebar != FALSE) +
3889                                (fSplitStatus != FALSE) +
3890                                (fAutoView != FALSE));
3891        *pswpNew = *pswpClient;
3892        pswpNew->hwnd = hwndUserlist;
3893        pswpNew->x = swpClient.x + 48 + (((swpClient.cx - 48) / 5) * 2);
3894        pswpNew->cx = ((swpClient.x + swpClient.cx) - pswpNew->x) -
3895          ((fToolbar) ? ((swpClient.cx - 48) / 7) : 0);
3896        pswpNew->y = pswpClient->y;
3897        pswpNew->cy = pswpClient->cy + (aheight + 5L);
3898        sCount++;
3899        if (fToolbar) {
3900          pswpNew = (PSWP) mp1 + (soldCount + 9 +
3901                                  (fToolbar != FALSE) +
3902                                  (fDrivebar != FALSE) +
3903                                  (fSplitStatus != FALSE) +
3904                                  (fAutoView != FALSE));
3905          *pswpNew = *pswpClient;
3906          pswpNew->hwnd = hwndButtonlist;
3907          pswpNew->x = swpClient.cx - ((swpClient.cx - 48) / 7) + 4;
3908          pswpNew->cx = (swpClient.x + swpClient.cx) - pswpNew->x;
3909          pswpNew->y = pswpClient->y;
3910          pswpNew->cy = pswpClient->cy + (aheight + 5L);
3911          sCount++;
3912        }
3913        else
3914          WinShowWindow(hwndButtonlist, FALSE);
3915      }
3916      else {
3917        WinShowWindow(hwndUserlist, FALSE);
3918        WinShowWindow(hwndDrivelist, FALSE);
3919        WinShowWindow(hwndStatelist, FALSE);
3920        WinShowWindow(hwndButtonlist, FALSE);
3921        WinShowWindow(hwndCmdlist, FALSE);
3922      }
3923      {
3924        PSWP pswpTitlebar = (PSWP) 0, pswpMinbutton = (PSWP) 0;
3925        SHORT x;
3926
3927        pswpNew = (PSWP) mp1 + (soldCount + 5 +
3928                                (fToolbar != FALSE) +
3929                                (fDrivebar != FALSE) +
3930                                (fSplitStatus != FALSE) +
3931                                (fAutoView != FALSE) +
3932                                ((fUserComboBox != FALSE) * 4) +
3933                                (fUserComboBox != FALSE &&
3934                                 fToolbar != FALSE));
3935        pswp = (PSWP) mp1;
3936        for (x = 0; x < soldCount; x++) {
3937          if (!pswpTitlebar &&
3938              WinQueryWindowUShort(pswp->hwnd, QWS_ID) == FID_TITLEBAR)
3939            pswpTitlebar = pswp;
3940          else if (!pswpMinbutton &&
3941                   WinQueryWindowUShort(pswp->hwnd, QWS_ID) == FID_MINMAX)
3942            pswpMinbutton = pswp;
3943          if (pswpTitlebar && pswpMinbutton)
3944            break;
3945          pswp++;
3946        }
3947        if (pswpMinbutton && pswpTitlebar) {
3948          *pswpNew = *pswpMinbutton;
3949          pswpNew->hwnd = WinWindowFromID(hwnd, IDM_IDEALSIZE);
3950          pswpNew->cy = pswpMinbutton->cy + 3;
3951          pswpNew->cx = min(pswpNew->cy, (pswpMinbutton->cx / 2) + 3);
3952          pswpTitlebar->cx -= (pswpNew->cx - 1);
3953          pswpNew->x = pswpTitlebar->x + (pswpTitlebar->cx);
3954          pswpNew->y = pswpMinbutton->y - 1;
3955          sCount++;
3956        }
3957        else
3958          WinShowWindow(WinWindowFromID(hwnd, IDM_IDEALSIZE), FALSE);
3959      }
3960
3961      if (fMoreButtons) {
3962
3963        LONG lastx;
3964
3965        pswpNew = (PSWP) mp1 + (soldCount + 6 +
3966                                (fToolbar != FALSE) +
3967                                (fDrivebar != FALSE) +
3968                                (fSplitStatus != FALSE) +
3969                                (fAutoView != FALSE) +
3970                                ((fUserComboBox != FALSE) * 4) +
3971                                (fUserComboBox != FALSE &&
3972                                 fToolbar != FALSE));
3973        *pswpNew = *pswpClient;
3974        pswpNew->hwnd = hwndName;
3975        pswpNew->x = swpClient.x + 3;
3976        pswpNew->y = swpClient.y + (sheight + 6);
3977        pswpNew->cx = ((swpClient.cx / 2) + (swpClient.cx / 5)) - 3;
3978        lastx = pswpNew->x + pswpNew->cx;
3979        pswpNew->cy = bheight;
3980        pswpClient->y += (bheight + 4);
3981        pswpClient->cy -= (bheight + 4);
3982        sCount++;
3983        pswpNew = (PSWP) mp1 + (soldCount + 7 +
3984                                (fToolbar != FALSE) +
3985                                (fDrivebar != FALSE) +
3986                                (fSplitStatus != FALSE) +
3987                                (fAutoView != FALSE) +
3988                                ((fUserComboBox != FALSE) * 4) +
3989                                (fUserComboBox != FALSE &&
3990                                 fToolbar != FALSE));
3991        *pswpNew = *pswpClient;
3992        pswpNew->hwnd = hwndDate;
3993        pswpNew->x = lastx + 3;
3994        pswpNew->y = swpClient.y + (sheight + 6);
3995        pswpNew->cx = (swpClient.cx / 6) + (swpClient.cx / 16) - 3;
3996        lastx = pswpNew->x + pswpNew->cx;
3997        pswpNew->cy = bheight;
3998        sCount++;
3999        pswpNew = (PSWP) mp1 + (soldCount + 8 +
4000                                (fToolbar != FALSE) +
4001                                (fDrivebar != FALSE) +
4002                                (fSplitStatus != FALSE) +
4003                                (fAutoView != FALSE) +
4004                                ((fUserComboBox != FALSE) * 4) +
4005                                (fUserComboBox != FALSE &&
4006                                 fToolbar != FALSE));
4007        *pswpNew = *pswpClient;
4008        pswpNew->hwnd = hwndAttr;
4009        pswpNew->x = lastx + 3;
4010        pswpNew->y = swpClient.y + (sheight + 6);
4011        pswpNew->cx = (swpClient.cx - pswpNew->x) - 1;
4012        pswpNew->cy = bheight;
4013        sCount++;
4014      }
4015      else {
4016        WinShowWindow(hwndAttr, FALSE);
4017        WinShowWindow(hwndName, FALSE);
4018        WinShowWindow(hwndDate, FALSE);
4019      }
4020      return MRFROMSHORT(sCount);
4021    }
4022
4023  case WM_QUERYFRAMECTLCOUNT:
4024    {
4025      SHORT sCount;
4026
4027      sCount = (SHORT) oldproc(hwnd, msg, mp1, mp2);
4028
4029      sCount += 6;
4030      if (fSplitStatus)
4031        sCount++;
4032      if (fToolbar)
4033        sCount++;
4034      if (fUserComboBox) {
4035        sCount += 4;
4036        if (fToolbar)
4037          sCount++;
4038      }
4039      if (fDrivebar)
4040        sCount++;
4041      if (fAutoView)
4042        sCount++;
4043      if (fMoreButtons)
4044        sCount += 3;
4045      return MRFROMSHORT(sCount);
4046    }
4047
4048  case WM_CLOSE:
4049    WinSendMsg(WinWindowFromID(hwnd, FID_CLIENT), msg, mp1, mp2);
4050    return 0;
4051  }
4052  return oldproc(hwnd, msg, mp1, mp2);
4053}
4054
4055MRESULT EXPENTRY MainWMCommand(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
4056{
4057  SetShiftState();
4058  switch (SHORT1FROMMP(mp1)) {
4059  case IDM_SETTARGET:
4060    SetTargetDir(hwnd, FALSE);
4061    break;
4062
4063  case IDM_TOAUTOMLE:
4064    if (fComments && fAutoView)
4065      WinSetFocus(HWND_DESKTOP, hwndAutoMLE);
4066    break;
4067
4068  case IDM_HIDENOTEWND:
4069    HideNote();
4070    break;
4071  case IDM_SHOWNOTEWND:
4072    ShowNote();
4073    break;
4074
4075  case IDM_COMPARE:
4076    {
4077      WALK2 wa;
4078      PCNRITEM pci;
4079
4080      memset(&wa, 0, sizeof(wa));
4081      wa.size = sizeof(wa);
4082      pci =
4083        (PCNRITEM)
4084        WinSendMsg(WinWindowFromID
4085                   (WinWindowFromID(hwndTree, FID_CLIENT), TREE_CNR),
4086                   CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
4087                   MPFROMSHORT(CRA_CURSORED));
4088      if (pci && (INT) pci != -1) {
4089        strcpy(wa.szCurrentPath1, pci->szFileName);
4090        MakeValidDir(wa.szCurrentPath1);
4091      }
4092      else
4093        save_dir2(wa.szCurrentPath1);
4094      TopWindowName(hwndMain, (HWND) 0, wa.szCurrentPath2);
4095      if (!*wa.szCurrentPath2)
4096        strcpy(wa.szCurrentPath2, wa.szCurrentPath1);
4097      MakeValidDir(wa.szCurrentPath2);
4098      if (WinDlgBox(HWND_DESKTOP,
4099                    hwnd,
4100                    WalkTwoCmpDlgProc,
4101                    FM3ModHandle,
4102                    WALK2_FRAME,
4103                    MPFROMP(&wa)) &&
4104          !IsFile(wa.szCurrentPath1) && !IsFile(wa.szCurrentPath2)) {
4105        if (!*dircompare) {
4106
4107          COMPARE *cmp;
4108
4109          cmp = xmallocz(sizeof(COMPARE), pszSrcFile, __LINE__);
4110          if (cmp) {
4111            cmp->size = sizeof(COMPARE);
4112            strcpy(cmp->leftdir, wa.szCurrentPath1);
4113            strcpy(cmp->rightdir, wa.szCurrentPath2);
4114            cmp->hwndParent = hwnd;
4115            cmp->dcd.hwndParent = hwnd;
4116            WinDlgBox(HWND_DESKTOP,
4117                      HWND_DESKTOP,
4118                      CompareDlgProc, FM3ModHandle, COMP_FRAME, MPFROMP(cmp));
4119          }
4120        }
4121        else {
4122
4123          CHAR d1[] = "\"";
4124          CHAR d2[] = "\"";
4125
4126          if (!needs_quoting(wa.szCurrentPath1))
4127            *d1 = 0;
4128          if (!needs_quoting(wa.szCurrentPath2))
4129            *d2 = 0;
4130          runemf2(SEPARATE,
4131                  HWND_DESKTOP,
4132                  NULL,
4133                  NULL,
4134                  "%s %s%s%s %s%s%s",
4135                  dircompare,
4136                  d1, wa.szCurrentPath1, d1, d2, wa.szCurrentPath2, d2);
4137        }
4138      }
4139    }
4140    break;
4141
4142  case IDM_EXIT:
4143  case IDM_KILLME:
4144    PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
4145    break;
4146
4147  case IDM_CLI:
4148    if (fSplitStatus &&
4149        hwndStatus2 &&
4150        !WinIsWindow(WinQueryAnchorBlock(hwnd),
4151                     WinWindowFromID(hwndStatus2, COMMAND_LINE)))
4152      PostMsg(hwndStatus2, UM_CLICKED, MPVOID, MPVOID);
4153    break;
4154
4155  case IDM_ADDTOUSERLIST:
4156  case IDM_DELETEFROMUSERLIST:
4157    {
4158      CHAR temp[CCHMAXPATH], path[CCHMAXPATH];
4159
4160      *temp = 0;
4161      WinQueryWindowText(hwndUserlist, CCHMAXPATH, temp);
4162      bstrip(temp);
4163      if (*temp &&
4164          !DosQueryPathInfo(temp, FIL_QUERYFULLNAME, path, sizeof(path))) {
4165        if (SHORT1FROMMP(mp1) == IDM_ADDTOUSERLIST) {
4166          add_udir(TRUE, path);
4167          if (fUdirsChanged)
4168            save_udirs();
4169          WinSendMsg(hwnd, UM_FILLUSERLIST, MPVOID, MPVOID);
4170        }
4171        else {
4172          if (!remove_udir(path))
4173            Runtime_Error(pszSrcFile, __LINE__, "remove_udir");
4174          else {
4175            if (fUdirsChanged)
4176              save_udirs();
4177            WinSendMsg(hwnd, UM_FILLUSERLIST, MPVOID, MPVOID);
4178          }
4179        }
4180      }
4181    }
4182    break;
4183
4184  case IDM_SAVEDIRCNRSTATE:
4185  case IDM_DELETEDIRCNRSTATE:
4186    {
4187      CHAR szStateName[14];
4188
4189      *szStateName = 0;
4190      WinQueryWindowText(hwndStatelist, 13, szStateName);
4191      bstrip(szStateName);
4192      // Ignore request if blank or attempting to using illegal name
4193      if (*szStateName && stricmp(szStateName, GetPString(IDS_STATETEXT))) {
4194        if (SHORT1FROMMP(mp1) == IDM_SAVEDIRCNRSTATE) {
4195          // Save
4196          if (SaveDirCnrState(hwnd, szStateName)) {
4197            if (add_setup(szStateName)) {
4198              WinSendMsg(hwndStatelist, LM_INSERTITEM,
4199                         MPFROM2SHORT(LIT_SORTASCENDING, 0), MPFROMP(szStateName));
4200              save_setups();
4201            }
4202            else {
4203              saymsg(MB_ENTER | MB_ICONASTERISK, hwnd,
4204                     GetPString(IDS_WARNINGTEXT),
4205                     GetPString(IDS_EXISTSASATEXT), szStateName, "state name");
4206              WinSetWindowText(hwndStatelist, GetPString(IDS_STATETEXT));
4207            }
4208          }
4209          else {
4210            saymsg(MB_ENTER | MB_ICONASTERISK, hwnd,
4211                   GetPString(IDS_WARNINGTEXT),
4212                   "\"%s\" state save failed", szStateName);    // 15 Apr 07 SHL failed
4213            WinSetWindowText(hwndStatelist, GetPString(IDS_STATETEXT));
4214          }
4215        }
4216        else {
4217          // Delete
4218          ULONG numsaves = 0, size, x;
4219          CHAR s[80];
4220
4221          if (remove_setup(szStateName))
4222            save_setups();
4223          sprintf(s, "%s.NumDirsLastTime", szStateName);
4224          size = sizeof(ULONG);
4225          if (!PrfQueryProfileData
4226              (fmprof, FM3Str, s, (PVOID) & numsaves, &size)) {
4227            saymsg(MB_ENTER | MB_ICONASTERISK, hwnd,
4228                   GetPString(IDS_WARNINGTEXT),
4229                   GetPString(IDS_DOESNTEXISTTEXT), szStateName);
4230          }
4231          else if (!size)
4232            Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
4233          else {
4234            PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0L);
4235            for (x = 0; x < numsaves; x++) {
4236              sprintf(s, "%s.DirCnrPos.%lu", szStateName, x);
4237              PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
4238              sprintf(s, "%s.DirCnrDir.%lu", szStateName, x);
4239              PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
4240              sprintf(s, "%s.DirCnrSort.%lu", szStateName, x);
4241              PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
4242              sprintf(s, "%s.DirCnrFilter.%lu", szStateName, x);
4243              PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
4244              sprintf(s, "%s.DirCnrView.%lu", szStateName, x);
4245              PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
4246            }
4247            sprintf(s, "%s.LastTreePos", szStateName);
4248            PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
4249            sprintf(s, "%s.MySizeLastTime", szStateName);
4250            PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
4251          }
4252          PostMsg(hwnd, UM_FILLSETUPLIST, MPVOID, MPVOID);
4253        }
4254      }
4255    }
4256    break;
4257
4258  case IDM_IDEALSIZE:
4259    {
4260      SWP swp, swpD;
4261      ULONG icz = WinQuerySysValue(HWND_DESKTOP, SV_CYICON) * 2L;
4262      ULONG bsz = WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
4263
4264      WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
4265      if (swp.fl & SWP_MAXIMIZE) {
4266        WinSendMsg(WinQueryWindow(hwnd, QW_PARENT), WM_SYSCOMMAND,
4267                   MPFROM2SHORT(SC_RESTORE, 0), MPVOID);
4268        WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
4269      }
4270      WinGetMaxPosition(WinQueryWindow(hwnd, QW_PARENT), &swpD);
4271      swpD.x += bsz;
4272      swpD.cx -= (bsz * 2);
4273      swpD.y += icz;
4274      swpD.cy -= (icz + bsz);
4275      if (swp.x == swpD.x && swp.y == swpD.y &&
4276          swp.cx == swpD.cx && swp.cy == swpD.cy &&
4277          // fixme to be #defined someday
4278          WinQueryWindowUShort(hwnd, QWL_USER + 10) &&
4279          WinQueryWindowUShort(hwnd, QWL_USER + 14)) {
4280        swpD.x = WinQueryWindowUShort(hwnd, QWL_USER + 8);
4281        swpD.cx = WinQueryWindowUShort(hwnd, QWL_USER + 10);
4282        swpD.y = WinQueryWindowUShort(hwnd, QWL_USER + 12);
4283        swpD.cy = WinQueryWindowUShort(hwnd, QWL_USER + 14);
4284      }
4285      else {
4286        WinSetWindowUShort(hwnd, QWL_USER + 8, (USHORT) swp.x);
4287        WinSetWindowUShort(hwnd, QWL_USER + 10, (USHORT) swp.cx);
4288        WinSetWindowUShort(hwnd, QWL_USER + 12, (USHORT) swp.y);
4289        WinSetWindowUShort(hwnd, QWL_USER + 14, (USHORT) swp.cy);
4290      }
4291      WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP,
4292                      swpD.x, swpD.y, swpD.cx, swpD.cy, SWP_MOVE | SWP_SIZE);
4293    }
4294    break;
4295
4296  case IDM_BLINK:
4297    WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
4298                    SWP_MINIMIZE);
4299    WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
4300                    SWP_RESTORE | SWP_ZORDER);
4301    break;
4302
4303  case DID_CANCEL:
4304    {
4305      HWND hwndTop = TopWindow(hwndMain, (HWND) 0);
4306
4307      if (hwndTop)
4308        WinSetFocus(HWND_DESKTOP, hwndTop);
4309    }
4310    break;
4311
4312  case IDM_NOTEBOOK:
4313    WinDlgBox(HWND_DESKTOP,
4314              hwnd, CfgDlgProc, FM3ModHandle, CFG_FRAME, MPVOID);
4315    break;
4316
4317  case IDM_VIEWHELPS:
4318  case IDM_VIEWINFS:
4319    WinDlgBox(HWND_DESKTOP,
4320              HWND_DESKTOP,
4321              ViewInfProc,
4322              FM3ModHandle,
4323              VINF_FRAME,
4324              ((SHORT1FROMMP(mp1) == IDM_VIEWHELPS) ?
4325               MPFROMP(NullStr) : MPVOID));
4326    break;
4327
4328  case IDM_OPENWALK:
4329    {
4330      char newpath[CCHMAXPATH];
4331
4332      *newpath = 0;
4333      TopWindowName(hwnd, (HWND) 0, newpath);
4334      if (WinDlgBox(HWND_DESKTOP,
4335                    hwnd,
4336                    WalkAllDlgProc,
4337                    FM3ModHandle, WALK_FRAME, MPFROMP(newpath)) && *newpath)
4338        OpenDirCnr((HWND) 0, hwndMain, hwndTree, FALSE, newpath);
4339    }
4340    break;
4341
4342  case IDM_WINDOWDLG:
4343    WindowList(hwnd);
4344    break;
4345
4346  case IDM_HELPMOUSE:
4347  case IDM_HELPCONTEXT:
4348  case IDM_HELPHINTS:
4349  case IDM_HELPPIX:
4350  case IDM_HELPTUTOR:
4351  case IDM_HELPUSERLIST:
4352  case IDM_HELP:
4353  case IDM_HELPCONTENTS:
4354  case IDM_HELPKEYS:
4355  case IDM_HELPGENERAL:
4356    if (hwndHelp) {
4357      if (SHORT1FROMMP(mp2) == CMDSRC_MENU) {
4358
4359        RECTL rcl;
4360        ULONG icz = WinQuerySysValue(HWND_DESKTOP, SV_CYICON) * 2L;
4361
4362        WinQueryWindowRect(HWND_DESKTOP, &rcl);
4363        rcl.yBottom += icz;
4364        rcl.yTop -= icz;
4365        rcl.xLeft += icz;
4366        rcl.xRight -= icz;
4367        WinSendMsg(hwndHelp, HM_SET_COVERPAGE_SIZE, MPFROMP(&rcl), MPVOID);
4368      }
4369      else {
4370
4371        RECTL rcl;
4372
4373        WinQueryWindowRect(HWND_DESKTOP, &rcl);
4374        rcl.yBottom += 8;
4375        rcl.yTop = (rcl.yTop / 2) + (rcl.yTop / 7);
4376        rcl.xLeft = (rcl.xRight / 2) - (rcl.xRight / 7);
4377        rcl.xRight -= 8;
4378        WinSendMsg(hwndHelp, HM_SET_COVERPAGE_SIZE, MPFROMP(&rcl), MPVOID);
4379      }
4380      switch (SHORT1FROMMP(mp1)) {
4381      case IDM_HELPCONTEXT:
4382        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
4383                   MPFROM2SHORT(HELP_CONTEXT, 0), MPFROMSHORT(HM_RESOURCEID));
4384        break;
4385
4386      case IDM_HELPMOUSE:
4387        if (hwndHelp)
4388          WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
4389                     MPFROM2SHORT(HELP_MOUSE, 0), MPFROMSHORT(HM_RESOURCEID));
4390        break;
4391
4392      case IDM_HELPPIX:
4393        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
4394                   MPFROM2SHORT(HELP_BITMAP1, 0), MPFROMSHORT(HM_RESOURCEID));
4395        break;
4396
4397      case IDM_HELPTUTOR:
4398        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
4399                   MPFROM2SHORT(HELP_TUTORIAL, 0),
4400                   MPFROMSHORT(HM_RESOURCEID));
4401        break;
4402
4403      case IDM_HELPHINTS:
4404        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
4405                   MPFROM2SHORT(HELP_HINTS, 0), MPFROMSHORT(HM_RESOURCEID));
4406        break;
4407
4408      case IDM_HELPGENERAL:
4409        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
4410                   MPFROM2SHORT(HELP_MAIN, 0), MPFROMSHORT(HM_RESOURCEID));
4411        break;
4412      case IDM_HELPKEYS:
4413        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
4414                   MPFROM2SHORT(HELP_KEYS, 0), MPFROMSHORT(HM_RESOURCEID));
4415        break;
4416
4417      case IDM_HELP:
4418      case IDM_HELPCONTENTS:
4419        WinSendMsg(hwndHelp, HM_HELP_CONTENTS, MPVOID, MPVOID);
4420        break;
4421
4422      case IDM_HELPUSERLIST:
4423        WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
4424                   MPFROM2SHORT(HELP_USERLISTS, 0),
4425                   MPFROMSHORT(HM_RESOURCEID));
4426        break;
4427      }
4428    }
4429    break;
4430
4431  case IDM_EDITANYARCHIVER:
4432    EditArchiverDefinition(hwnd);
4433    break;
4434
4435  case IDM_ABOUT:
4436    WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, FM3ModHandle,
4437              ABT_FRAME, MPVOID);
4438    break;
4439
4440  case IDM_FONTPALETTE:
4441    OpenObject("<WP_FNTPAL>", Default, hwnd);
4442    break;
4443
4444  case IDM_HICOLORPALETTE:
4445  case IDM_COLORPALETTE:
4446    {
4447      CHAR *palette = "<WP_CLRPAL>";
4448      ULONG version[2];
4449
4450      if (!DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_VERSION_MINOR,
4451                           (PVOID) & version, (ULONG) sizeof(version))) {
4452        if (version[0] > 20L || (version[0] == 20L && version[1] > 29L)) {
4453          if (SHORT1FROMMP(mp1) == IDM_HICOLORPALETTE)
4454            palette = "<WP_HIRESCLRPAL>";
4455          else
4456            palette = "<WP_LORESCLRPAL>";
4457        }
4458      }
4459      OpenObject(palette, Default, hwnd);
4460    }
4461    break;
4462
4463  case IDM_SYSTEMSETUP:
4464    OpenObject("<WP_CONFIG>", Default, hwnd);
4465    break;
4466
4467  case IDM_SCHEMEPALETTE:
4468    {
4469      HOBJECT hWPSObject;
4470
4471      hWPSObject = WinQueryObject("<WP_SCHPAL>");
4472      if (hWPSObject != NULLHANDLE)
4473        WinSetObjectData(hWPSObject, "SCHEMES=Winter:PM_Winter,"
4474                         "Spring:PM_Spring,Summer:PM_Summer,"
4475                         "System:PM_System,Windows:PM_Windows;"
4476                         "OPEN=DEFAULT");
4477    }
4478    break;
4479
4480  case IDM_SYSTEMCLOCK:
4481    OpenObject("<WP_CLOCK>", Default, hwnd);
4482    break;
4483
4484#ifdef NEVER
4485  case IDM_SYSINFO:
4486    WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, SysInfoDlgProc, FM3ModHandle,
4487              SYS_FRAME, NULL);
4488    break;
4489#endif
4490
4491  case IDM_INSTANT:
4492    {
4493      CHAR path[CCHMAXPATH];
4494      PCNRITEM pci = (PCNRITEM) 0;
4495
4496      if (hwndTree)
4497        pci = (PCNRITEM) WinSendMsg(hwndTree, CM_QUERYRECORDEMPHASIS,
4498                                    MPFROMLONG(CMA_FIRST),
4499                                    MPFROMSHORT(CRA_CURSORED));
4500      if (pci && (INT) pci != -1) {
4501        strcpy(path, pci->szFileName);
4502        MakeValidDir(path);
4503      }
4504      else
4505        save_dir2(path);
4506      WinDlgBox(HWND_DESKTOP, hwnd, InstantDlgProc, FM3ModHandle,
4507                BAT_FRAME, MPFROMP(path));
4508    }
4509    break;
4510
4511  case IDM_WINFULLSCREEN:
4512  case IDM_DOSCOMMANDLINE:
4513  case IDM_COMMANDLINE:
4514    {
4515      CHAR *env = GetCmdSpec(FALSE), path[CCHMAXPATH];
4516      INT type = SEPARATE | WINDOWED;
4517
4518      *path = 0;
4519      TopWindowName(hwnd, (HWND) 0, path);
4520      if (SHORT1FROMMP(mp1) == IDM_DOSCOMMANDLINE)
4521        env = GetCmdSpec(TRUE);
4522      else if (SHORT1FROMMP(mp1) != IDM_COMMANDLINE) {
4523        env = "WINOS2.COM";
4524        type = SEPARATE | FULLSCREEN;
4525      }
4526      runemf2(type, hwnd, path, NULL, "%s", env);
4527    }
4528    break;
4529
4530  case IDM_KILLPROC:
4531    WinDlgBox(HWND_DESKTOP, hwnd, KillDlgProc, FM3ModHandle,
4532              KILL_FRAME, NULL);
4533    break;
4534
4535  case IDM_AUTOVIEWCOMMENTS:
4536  case IDM_AUTOVIEWFILE:
4537    if (SHORT1FROMMP(mp1) == IDM_AUTOVIEWFILE)
4538      fComments = FALSE;
4539    else
4540      fComments = TRUE;
4541    PrfWriteProfileData(fmprof, FM3Str, "Comments", &fComments, sizeof(BOOL));
4542    WinSetWindowText((fComments) ? hwndAutoview : hwndAutoMLE, NullStr);
4543    goto AutoChange;
4544
4545  case IDM_AUTOVIEW:
4546    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER), SHORT1FROMMP(mp1),
4547                 &fAutoView, TRUE, "AutoView");
4548  AutoChange:
4549    PostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_UPDATEFRAME,
4550            MPFROMLONG(FCF_SIZEBORDER), MPVOID);
4551    if (fAutoView) {
4552
4553      CHAR s[CCHMAXPATH];
4554      HWND hwndDir;
4555      PCNRITEM pci;
4556
4557      hwndDir = TopWindowName(hwnd, (HWND) 0, s);
4558      if (hwndDir) {
4559        hwndDir = WinWindowFromID(hwndDir, FID_CLIENT);
4560        if (hwndDir) {
4561          hwndDir = WinWindowFromID(hwndDir, DIR_CNR);
4562          if (hwndDir) {
4563            pci = (PCNRITEM) WinSendMsg(hwndDir, CM_QUERYRECORDEMPHASIS,
4564                                        MPFROMLONG(CMA_FIRST),
4565                                        MPFROMSHORT(CRA_CURSORED));
4566            if (pci && (INT) pci != -1 &&
4567                (!(driveflags[toupper(*pci->szFileName) - 'A'] & DRIVE_SLOW)))
4568              WinSendMsg(hwnd,
4569                         UM_LOADFILE,
4570                         MPFROMP(pci->szFileName),
4571                         (SHORT1FROMMP(mp1) == IDM_AUTOVIEW) ?
4572                         MPVOID : MPFROMLONG(1L));
4573          }
4574        }
4575      }
4576    }
4577    break;
4578
4579  case IDM_TEXTTOOLS:
4580    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER), SHORT1FROMMP(mp1),
4581                 &fTextTools, TRUE, "TextTools");
4582    BuildTools(hwndToolback, TRUE);
4583    PostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_UPDATEFRAME,
4584            MPFROMLONG(FCF_SIZEBORDER), MPVOID);
4585    break;
4586
4587  case IDM_TOOLTITLES:
4588    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER), SHORT1FROMMP(mp1),
4589                 &fToolTitles, TRUE, "ToolTitles");
4590    BuildTools(hwndToolback, TRUE);
4591    PostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_UPDATEFRAME,
4592            MPFROMLONG(FCF_SIZEBORDER), MPVOID);
4593    break;
4594
4595  case IDM_HIDEMENU:
4596    {
4597      HWND hwndMenu;
4598
4599      hwndMenu = WinQueryWindowULong(hwnd, QWL_USER);
4600      MenuInvisible = (MenuInvisible) ? FALSE : TRUE;
4601      if (MenuInvisible) {
4602        WinSetParent(hwndMenu, HWND_OBJECT, FALSE);
4603        WinSetMenuItemText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
4604                                           FID_SYSMENU), IDM_HIDEMENU,
4605                           GetPString(IDS_UNHIDEMENUTEXT));
4606      }
4607      else {
4608        WinSetParent(hwndMenu, WinQueryWindow(hwnd, QW_PARENT), FALSE);
4609        WinSetMenuItemText(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
4610                                           FID_SYSMENU), IDM_HIDEMENU,
4611                           GetPString(IDS_HIDEMENUTEXT));
4612      }
4613      PostMsg(WinQueryWindow(hwnd, QW_PARENT), WM_UPDATEFRAME,
4614              MPFROMLONG(FCF_MENU), MPVOID);
4615      PrfWriteProfileData(fmprof, FM3Str, "MenuInvisible",
4616                          &MenuInvisible, sizeof(BOOL));
4617    }
4618    break;
4619
4620  case IDM_SEEALL:
4621  case IDM_GREP:
4622  case IDM_COLLECTOR:
4623    {
4624      HWND hwndC;
4625      SWP swp;
4626      BOOL already = FALSE;
4627
4628      if (Collector)
4629        already = TRUE;
4630      if (!already && !fAutoTile && !fExternalCollector)
4631        GetNextWindowPos(hwnd, &swp, NULL, NULL);
4632      hwndC = StartCollector((fExternalCollector) ? HWND_DESKTOP : hwnd, 4);
4633      if (hwndC) {
4634        if (!already && !fAutoTile && !fExternalCollector)
4635          WinSetWindowPos(hwndC, HWND_TOP, swp.x, swp.y,
4636                          swp.cx, swp.cy, SWP_MOVE | SWP_SIZE |
4637                          SWP_SHOW | SWP_ZORDER);
4638        else if (fAutoTile && !already)
4639          TileChildren(hwnd, TRUE);
4640        WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0, SWP_SHOW | SWP_RESTORE |
4641                        SWP_ACTIVATE);
4642        if (SHORT1FROMMP(mp1) == IDM_GREP)
4643          PostMsg(WinWindowFromID(hwndC, FID_CLIENT), WM_COMMAND,
4644                  MPFROM2SHORT(IDM_GREP, 0), MPVOID);
4645        if (SHORT1FROMMP(mp1) == IDM_SEEALL)
4646          PostMsg(WinWindowFromID(hwndC, FID_CLIENT), WM_COMMAND,
4647                  MPFROM2SHORT(IDM_SEEALL, 0), MPVOID);
4648      }
4649    }
4650    break;
4651
4652  case IDM_TOOLLEFT:
4653  case IDM_TOOLRIGHT:
4654    {
4655      TOOL *tool;
4656
4657      if (!toolhead || !toolhead->next) {
4658        firsttool = (toolhead) ? toolhead->id : 0;
4659        break;
4660      }
4661      tool = find_tool(firsttool);
4662      if (!tool)
4663        tool = toolhead;
4664      if (SHORT1FROMMP(mp1) == IDM_TOOLRIGHT) {
4665        tool = prev_tool(tool, TRUE);
4666        firsttool = tool->id;
4667      }
4668      else {
4669        tool = next_tool(tool, TRUE);
4670        firsttool = tool->id;
4671      }
4672      ResizeTools(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
4673                                  MAIN_TOOLS));
4674    }
4675    break;
4676
4677  case IDM_CREATETOOL:
4678    BuildTools(hwndToolback, TRUE);
4679    break;
4680
4681  case IDM_TOOLBAR:
4682    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER),
4683                 IDM_TOOLSUBMENU, &fToolbar, TRUE, "Toolbar");
4684    BuildTools(hwndToolback, TRUE);
4685    WinShowWindow(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
4686                                  MAIN_TOOLS), fToolbar);
4687    WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
4688               WM_UPDATEFRAME, MPFROMLONG(FCF_SIZEBORDER), MPVOID);
4689    if (fDrivebar)
4690      WinInvalidateRect(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
4691                                        MAIN_DRIVES), NULL, TRUE);
4692    break;
4693
4694  case IDM_DRIVEBAR:
4695    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER),
4696                 IDM_DRIVEBAR, &fDrivebar, TRUE, "Drivebar");
4697    WinShowWindow(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
4698                                  MAIN_DRIVES), fDrivebar);
4699    PostMsg(WinQueryWindow(hwnd, QW_PARENT),
4700            WM_UPDATEFRAME, MPFROMLONG(FCF_SIZEBORDER), MPVOID);
4701    PostMsg(hwnd, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
4702    break;
4703
4704  case IDM_USERLIST:
4705    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER),
4706                 SHORT1FROMMP(mp1), &fUserComboBox, TRUE, "UserComboBox");
4707    WinShowWindow(hwndUserlist, fUserComboBox);
4708    PostMsg(WinQueryWindow(hwnd, QW_PARENT),
4709            WM_UPDATEFRAME, MPFROMLONG(FCF_SIZEBORDER), MPVOID);
4710    PostMsg(hwnd, UM_FILLUSERLIST, MPVOID, MPVOID);
4711    PostMsg(hwnd, UM_FILLSETUPLIST, MPVOID, MPVOID);
4712    PostMsg(hwnd, UM_FILLCMDLIST, MPVOID, MPVOID);
4713    PostMsg(hwnd, UM_FILLBUTTONLIST, MPVOID, MPVOID);
4714    break;
4715
4716  case IDM_MOREBUTTONS:
4717    WinSetWindowText(hwndName, NullStr);
4718    WinSetWindowText(hwndDate, NullStr);
4719    WinSetWindowText(hwndAttr, NullStr);
4720    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER),
4721                 SHORT1FROMMP(mp1), &fMoreButtons, TRUE, "MoreButtons");
4722    if (fMoreButtons) {
4723
4724      HWND hwndTemp;
4725
4726      hwndTemp = TopWindow(hwnd, (HWND) 0);
4727
4728      if (hwndTemp) {
4729        WinSetFocus(HWND_DESKTOP, hwnd);
4730        WinSetFocus(HWND_DESKTOP, hwndTemp);
4731      }
4732    }
4733    PostMsg(WinQueryWindow(hwnd, QW_PARENT),
4734            WM_UPDATEFRAME, MPFROMLONG(FCF_SIZEBORDER), MPVOID);
4735    break;
4736
4737  case IDM_FREETREE:
4738    if (fFreeTree) {
4739
4740      SWP swp, swpT;
4741
4742      WinQueryWindowPos(hwndTree, &swpT);
4743      WinQueryWindowPos(hwnd, &swp);
4744      WinSetWindowPos(hwndTree, HWND_TOP, 0, swp.cy - swpT.cy, 0, 0,
4745                      SWP_MOVE);
4746    }
4747    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER), SHORT1FROMMP(mp1),
4748                 &fFreeTree, TRUE, "FreeTree");
4749    if (fAutoTile)
4750      TileChildren(hwnd, TRUE);
4751    break;
4752
4753  case IDM_AUTOTILE:
4754    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER),
4755                 SHORT1FROMMP(mp1), &fAutoTile, TRUE, "AutoTile");
4756    if (fAutoTile)
4757      TileChildren(hwnd, TRUE);
4758    break;
4759
4760  case IDM_TILEBACKWARDS:
4761    SetMenuCheck(WinQueryWindowULong(hwnd, QWL_USER),
4762                 SHORT1FROMMP(mp1), &fTileBackwards, TRUE, "TileBackwards");
4763    if (fAutoTile)
4764      TileChildren(hwnd, TRUE);
4765    break;
4766
4767  case IDM_NEXTWINDOW:
4768  case IDM_PREVWINDOW:
4769    NextChild(hwnd, (SHORT1FROMMP(mp1) == IDM_PREVWINDOW));
4770    break;
4771
4772  case IDM_CASCADE:
4773    CascadeChildren(hwnd);
4774    break;
4775
4776  case IDM_TILE:
4777    TileChildren(hwnd, TRUE);
4778    break;
4779
4780  case IDM_RESTORE:
4781    MinResChildren(hwnd, SWP_RESTORE);
4782    break;
4783
4784  case IDM_MINIMIZE:
4785    MinResChildren(hwnd, SWP_MINIMIZE);
4786    break;
4787
4788  case IDM_ARRANGEICONS:
4789    ArrangeIcons(hwnd);
4790    break;
4791
4792  case IDM_INIVIEWER:
4793    StartIniEditor(hwnd, NULL, 4);
4794    break;
4795
4796  case IDM_EDITASSOC:
4797    EditAssociations(hwnd);
4798    break;
4799
4800  case IDM_EDITCOMMANDS:
4801    EditCommands(hwnd);
4802    PostMsg(hwnd, UM_FILLCMDLIST, MPVOID, MPVOID);
4803    break;
4804
4805  default:
4806    if (!SwitchCommand((HWND) WinQueryWindowULong(hwnd, QWL_USER),
4807                       SHORT1FROMMP(mp1))) {
4808      if (SHORT1FROMMP(mp1) >= IDM_COMMANDSTART &&
4809          SHORT1FROMMP(mp1) < IDM_QUICKTOOLSTART) {
4810
4811        INT x;
4812        HWND hwndCnr;
4813
4814        if (!cmdloaded)
4815          load_commands();
4816        hwndCnr = TopWindow(hwnd, (HWND) 0);
4817        hwndCnr = (HWND) WinSendMsg(WinWindowFromID(hwndCnr, FID_CLIENT),
4818                                    UM_CONTAINERHWND, MPVOID, MPVOID);
4819        if (!hwndCnr) {
4820          Runtime_Error2(pszSrcFile, __LINE__, IDS_NOWINDOWTEXT);
4821          break;
4822        }
4823        x = SHORT1FROMMP(mp1) - IDM_COMMANDSTART;
4824        if (x >= 0) {
4825          x++;
4826          RunCommand(hwndCnr, x);
4827          if (fUnHilite) {
4828
4829            PCNRITEM pci;
4830            DIRCNRDATA *dcd = NULL;
4831
4832            // 12 May 07 SHL fixme to understand?  backwards maybe? looking for DIR_CNR?
4833            if (WinQueryWindowUShort(hwndCnr, QWS_ID) != TREE_CNR)
4834              dcd = INSTDATA(hwndCnr);
4835            pci = (PCNRITEM) WinSendMsg(hwndCnr,
4836                                        CM_QUERYRECORDEMPHASIS,
4837                                        MPFROMLONG(CMA_FIRST),
4838                                        MPFROMSHORT(CRA_CURSORED));
4839            if (pci && (INT) pci != -1 &&
4840                (pci->rc.flRecordAttr & CRA_SELECTED))
4841            {
4842              UnHilite(hwnd,
4843                       TRUE,
4844                       dcd ? &dcd->lastselection : NULL,
4845                       dcd ? dcd ->ulItemsToUnHilite : 0);
4846            }
4847          }
4848        }
4849      }
4850      else if (SHORT1FROMMP(mp1) >= IDM_QUICKTOOLSTART &&
4851               SHORT1FROMMP(mp1) < IDM_QUICKTOOLSTART + 50) {
4852        if (!qtloaded)
4853          load_quicktools();
4854        if (quicktool[SHORT1FROMMP(mp1) - IDM_QUICKTOOLSTART]) {
4855          if (fToolsChanged)
4856            save_tools(NULL);
4857          if (!load_tools(quicktool[SHORT1FROMMP(mp1) - IDM_QUICKTOOLSTART]))
4858            load_tools(NULL);
4859          else {
4860            strcpy(lasttoolbox,
4861                   quicktool[SHORT1FROMMP(mp1) - IDM_QUICKTOOLSTART]);
4862            PrfWriteProfileString(fmprof, FM3Str, "LastToolBox", lasttoolbox);
4863          }
4864          BuildTools(hwndToolback, TRUE);
4865        }
4866      }
4867      else {
4868
4869        HWND hwndActive;
4870
4871        hwndActive = TopWindow(hwnd, (HWND) 0);
4872        if (hwndActive)
4873          PostMsg(WinWindowFromID(hwndActive, FID_CLIENT),
4874                  WM_COMMAND, mp1, mp2);
4875      }
4876    }
4877    break;
4878  }
4879  return 0;
4880}
4881
4882static MRESULT EXPENTRY MainWMOnce(HWND hwnd, ULONG msg, MPARAM mp1,
4883                                   MPARAM mp2)
4884{
4885  TID tid;
4886  SWP swp;
4887  PFNWP oldproc;
4888  HWND hwndTmp;
4889  HWND hwndFrame;
4890  HWND hwndSysMenu, hwndSysSubMenu, hwndMenu;
4891  USHORT idSysMenu;
4892  MENUITEM mi, mit;
4893  ULONG size;
4894  BOOL temp = FALSE;
4895
4896  switch (msg) {
4897  case WM_CREATE:
4898    WinQueryWindowProcess(hwnd, &mypid, &tid);
4899    hwndMain = hwnd;
4900    WinSetWindowUShort(hwnd, QWL_USER + 8, 0);
4901    WinSetWindowUShort(hwnd, QWL_USER + 10, 0);
4902    WinSetWindowUShort(hwnd, QWL_USER + 12, 0);
4903    WinSetWindowUShort(hwnd, QWL_USER + 16, 0);
4904    if (_beginthread(MakeMainObjWin, NULL, 245760, MPVOID) == -1) {
4905      Runtime_Error(pszSrcFile, __LINE__,
4906                    GetPString(IDS_COULDNTSTARTTHREADTEXT));
4907      PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
4908      return 0;
4909    }
4910    else
4911      DosSleep(64);
4912
4913    hwndFrame = WinQueryWindow(hwnd, QW_PARENT);
4914
4915    /*
4916     * create frame children (not client children, frame children)
4917     */
4918    DosSleep(1L);
4919    WinQueryWindowPos(hwndFrame, &swp);
4920    oldproc = WinSubclassWindow(hwndFrame, MainFrameWndProc);
4921    WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
4922    CommonCreateMainChildren(hwnd, &swp);
4923
4924    if (!WinCreateWindow(hwndFrame,
4925                         WC_BUTTON,
4926                         "I",
4927                         WS_VISIBLE | BS_PUSHBUTTON | BS_NOPOINTERFOCUS,
4928                         ((swp.cx -
4929                           WinQuerySysValue(HWND_DESKTOP,
4930                                            SV_CXMINMAXBUTTON)) -
4931                          WinQuerySysValue(HWND_DESKTOP,
4932                                           SV_CXMINMAXBUTTON) / 2) -
4933                         WinQuerySysValue(HWND_DESKTOP,
4934                                          SV_CXSIZEBORDER),
4935                         (swp.cy - WinQuerySysValue(HWND_DESKTOP,
4936                                                    SV_CYMINMAXBUTTON)) -
4937                         WinQuerySysValue(HWND_DESKTOP,
4938                                          SV_CYSIZEBORDER),
4939                         WinQuerySysValue(HWND_DESKTOP,
4940                                          SV_CXMINMAXBUTTON) / 2,
4941                         WinQuerySysValue(HWND_DESKTOP,
4942                                          SV_CYMINMAXBUTTON),
4943                         hwnd, HWND_TOP, IDM_IDEALSIZE, NULL, NULL)) {
4944      Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
4945    }
4946    else {
4947      WinSubclassWindow(WinWindowFromID(hwndFrame, IDM_IDEALSIZE),
4948                        IdealButtonProc);
4949      SetPresParams(WinWindowFromID(hwndFrame,
4950                                    IDM_IDEALSIZE),
4951                    NULL, NULL, NULL, GetPString(IDS_10SYSTEMVIOTEXT));
4952    }
4953
4954    hwndTmp = WinCreateWindow(hwndFrame,
4955                              WC_BUTTON,
4956                              "#1019",
4957                              WS_VISIBLE | BS_PUSHBUTTON | BS_NOPOINTERFOCUS |
4958                              BS_BITMAP,
4959                              swp.cx - 46,
4960                              swp.y + 2,
4961                              24,
4962                              22, hwnd, HWND_TOP, IDM_OPENWALK, NULL, NULL);
4963    if (!hwndTmp)
4964      Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
4965
4966    hwndTmp = WinCreateWindow(hwndFrame,
4967                              WC_BUTTON,
4968                              "#3062",
4969                              WS_VISIBLE | BS_PUSHBUTTON | BS_NOPOINTERFOCUS |
4970                              BS_BITMAP,
4971                              swp.cx - 22,
4972                              swp.y + 2,
4973                              24,
4974                              22, hwnd, HWND_TOP, IDM_USERLIST, NULL, NULL);
4975    if (!hwndTmp)
4976      Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
4977
4978    hwndUserlist = WinCreateWindow(hwndFrame,
4979                                   WC_COMBOBOX,
4980                                   (PSZ) NULL,
4981                                   WS_VISIBLE | CBS_DROPDOWN |
4982                                   LS_HORZSCROLL,
4983                                   (swp.x +
4984                                    WinQuerySysValue(HWND_DESKTOP,
4985                                                     SV_CXSIZEBORDER) + 48L),
4986                                   (swp.cy -
4987                                    WinQuerySysValue(HWND_DESKTOP,
4988                                                     SV_CYSIZEBORDER)) - 60,
4989                                   ((swp.cx -
4990                                     (WinQuerySysValue(HWND_DESKTOP,
4991                                                       SV_CXSIZEBORDER) *
4992                                      2)) - 64L), 60L, hwndFrame, HWND_TOP,
4993                                   MAIN_USERLIST, NULL, NULL);
4994    if (!hwndUserlist)
4995      Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
4996    hwndCmdlist = WinCreateWindow(hwndFrame,
4997                                  WC_COMBOBOX,
4998                                  (PSZ) NULL,
4999                                  WS_VISIBLE | CBS_DROPDOWN |
5000                                  LS_HORZSCROLL,
5001                                  (swp.x +
5002                                   WinQuerySysValue(HWND_DESKTOP,
5003                                                    SV_CXSIZEBORDER) + 48L),
5004                                  (swp.cy -
5005                                   WinQuerySysValue(HWND_DESKTOP,
5006                                                    SV_CYSIZEBORDER)) - 60,
5007                                  ((swp.cx -
5008                                    (WinQuerySysValue(HWND_DESKTOP,
5009                                                      SV_CXSIZEBORDER) * 2)) -
5010                                   64L), 60L, hwndFrame, HWND_TOP,
5011                                  MAIN_CMDLIST, NULL, NULL);
5012    if (!hwndCmdlist)
5013      Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
5014    WinSetWindowText(hwndCmdlist, GetPString(IDS_COMMANDSTEXT));
5015    hwndStatelist = WinCreateWindow(hwndFrame,
5016                                    WC_COMBOBOX,
5017                                    (PSZ) NULL,
5018                                    WS_VISIBLE | CBS_DROPDOWN |
5019                                    LS_HORZSCROLL,
5020                                    (swp.x +
5021                                     WinQuerySysValue(HWND_DESKTOP,
5022                                                      SV_CXSIZEBORDER) + 48L),
5023                                    (swp.cy -
5024                                     WinQuerySysValue(HWND_DESKTOP,
5025                                                      SV_CYSIZEBORDER)) - 60,
5026                                    ((swp.cx -
5027                                      (WinQuerySysValue(HWND_DESKTOP,
5028                                                        SV_CXSIZEBORDER) *
5029                                       2)) - 64L), 60L, hwndFrame, HWND_TOP,
5030                                    MAIN_SETUPLIST, NULL, NULL);
5031    if (!hwndStatelist)
5032      Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
5033    hwndDrivelist = WinCreateWindow(hwndFrame,
5034                                    WC_COMBOBOX,
5035                                    (PSZ) NULL,
5036                                    WS_VISIBLE | CBS_DROPDOWN,
5037                                    (swp.x +
5038                                     WinQuerySysValue(HWND_DESKTOP,
5039                                                      SV_CXSIZEBORDER)),
5040                                    (swp.cy -
5041                                     WinQuerySysValue(HWND_DESKTOP,
5042                                                      SV_CYSIZEBORDER)) - 60,
5043                                    48L,
5044                                    60L,
5045                                    hwndFrame,
5046                                    HWND_TOP, MAIN_DRIVELIST, NULL, NULL);
5047    if (!hwndDrivelist)
5048      Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
5049    SetPresParams(hwndDrivelist,
5050                  NULL, NULL, NULL, GetPString(IDS_10SYSTEMMONOTEXT));
5051    hwndButtonlist = WinCreateWindow(hwndFrame,
5052                                     WC_COMBOBOX,
5053                                     (PSZ) NULL,
5054                                     WS_VISIBLE | CBS_DROPDOWN |
5055                                     LS_HORZSCROLL,
5056                                     (swp.cx -
5057                                      WinQuerySysValue(HWND_DESKTOP,
5058                                                       SV_CXSIZEBORDER)) -
5059                                     164L,
5060                                     (swp.cy -
5061                                      WinQuerySysValue(HWND_DESKTOP,
5062                                                       SV_CYSIZEBORDER)) - 60,
5063                                     164L, 60L, hwndFrame, HWND_TOP,
5064                                     MAIN_BUTTONLIST, NULL, NULL);
5065    if (!hwndButtonlist)
5066      Win_Error2(hwnd, hwnd, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
5067    WinSendMsg(WinWindowFromID(hwndUserlist, CBID_EDIT),
5068               EM_SETTEXTLIMIT, MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
5069    WinSendMsg(WinWindowFromID(hwndStatelist, CBID_EDIT),
5070               EM_SETTEXTLIMIT, MPFROM2SHORT(13, 0), MPVOID);
5071    WinSendMsg(WinWindowFromID(hwndDrivelist, CBID_EDIT),
5072               EM_SETREADONLY, MPFROM2SHORT(TRUE, 0), MPVOID);
5073    WinSendMsg(WinWindowFromID(hwndButtonlist, CBID_EDIT),
5074               EM_SETREADONLY, MPFROM2SHORT(TRUE, 0), MPVOID);
5075    WinSendMsg(WinWindowFromID(hwndCmdlist, CBID_EDIT),
5076               EM_SETREADONLY, MPFROM2SHORT(TRUE, 0), MPVOID);
5077
5078    oldproc = WinSubclassWindow(WinWindowFromID(hwndUserlist, CBID_EDIT),
5079                                DropDownListProc);
5080    WinSetWindowPtr(WinWindowFromID(hwndUserlist, CBID_EDIT),
5081                    QWL_USER, (PVOID) oldproc);
5082    oldproc = WinSubclassWindow(WinWindowFromID(hwndCmdlist, CBID_EDIT),
5083                                DropDownListProc);
5084    WinSetWindowPtr(WinWindowFromID(hwndCmdlist, CBID_EDIT),
5085                    QWL_USER, (PVOID) oldproc);
5086    oldproc = WinSubclassWindow(WinWindowFromID(hwndButtonlist, CBID_EDIT),
5087                                DropDownListProc);
5088    WinSetWindowPtr(WinWindowFromID(hwndButtonlist, CBID_EDIT),
5089                    QWL_USER, (PVOID) oldproc);
5090    oldproc = WinSubclassWindow(WinWindowFromID(hwndStatelist, CBID_EDIT),
5091                                DropDownListProc);
5092    WinSetWindowPtr(WinWindowFromID(hwndStatelist, CBID_EDIT),
5093                    QWL_USER, (PVOID) oldproc);
5094    oldproc = WinSubclassWindow(WinWindowFromID(hwndDrivelist, CBID_EDIT),
5095                                DropDownListProc);
5096    WinSetWindowPtr(WinWindowFromID(hwndDrivelist, CBID_EDIT),
5097                    QWL_USER, (PVOID) oldproc);
5098    oldproc = WinSubclassWindow(hwndUserlist, DropDownListProc);
5099    WinSetWindowPtr(hwndUserlist, QWL_USER, (PVOID) oldproc);
5100    oldproc = WinSubclassWindow(hwndCmdlist, DropDownListProc);
5101    WinSetWindowPtr(hwndCmdlist, QWL_USER, (PVOID) oldproc);
5102    oldproc = WinSubclassWindow(hwndStatelist, DropDownListProc);
5103    WinSetWindowPtr(hwndStatelist, QWL_USER, (PVOID) oldproc);
5104    oldproc = WinSubclassWindow(hwndDrivelist, DropDownListProc);
5105    WinSetWindowPtr(hwndDrivelist, QWL_USER, (PVOID) oldproc);
5106    oldproc = WinSubclassWindow(hwndButtonlist, DropDownListProc);
5107    WinSetWindowPtr(hwndButtonlist, QWL_USER, (PVOID) oldproc);
5108    oldproc = WinSubclassWindow(WinWindowFromID(hwndFrame, IDM_USERLIST),
5109                                ChildFrameButtonProc);
5110    WinSetWindowPtr(WinWindowFromID(hwndFrame, IDM_USERLIST),
5111                    QWL_USER, (PVOID) oldproc);
5112    oldproc = WinSubclassWindow(WinWindowFromID(hwndFrame, IDM_OPENWALK),
5113                                ChildFrameButtonProc);
5114    WinSetWindowPtr(WinWindowFromID(hwndFrame, IDM_OPENWALK),
5115                    QWL_USER, (PVOID) oldproc);
5116    hwndMenu = WinWindowFromID(hwndFrame, FID_MENU);
5117    WinSendMsg(hwnd, UM_ADDTOMENU, MPVOID, MPVOID);
5118    SetToggleChecks(hwndMenu);
5119    SetConditionalCascade(hwndMenu, IDM_TOOLSUBMENU, IDM_TOOLBAR);
5120    SetConditionalCascade(hwndMenu, IDM_AUTOVIEWSUBMENU, IDM_AUTOVIEW);
5121    SetConditionalCascade(hwndMenu, IDM_TILEMENU, IDM_TILE);
5122    WinSetWindowULong(hwnd, QWL_USER, hwndMenu);
5123    memset(&mi, 0, sizeof(mi));
5124    memset(&mit, 0, sizeof(mit));
5125    hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU);
5126    idSysMenu = SHORT1FROMMR(WinSendMsg(hwndSysMenu,
5127                                        MM_ITEMIDFROMPOSITION,
5128                                        MPVOID, MPVOID));
5129    WinSendMsg(hwndSysMenu,
5130               MM_QUERYITEM, MPFROM2SHORT(idSysMenu, 0), MPFROMP(&mit));
5131    hwndSysSubMenu = mit.hwndSubMenu;
5132    mi.iPosition = MIT_END;
5133    mi.afStyle = MIS_SEPARATOR;
5134    mi.id = (USHORT) - 1;
5135    WinSendMsg(hwndSysSubMenu, MM_INSERTITEM, MPFROMP(&mi), MPFROMP(NULL));
5136    mi.afStyle = MIS_TEXT;
5137    mi.id = IDM_IDEALSIZE;
5138    WinSendMsg(hwndSysSubMenu,
5139               MM_INSERTITEM,
5140               MPFROMP(&mi), MPFROMP(GetPString(IDS_IDEALMENUTEXT)));
5141    mi.afStyle = MIS_TEXT;
5142    mi.id = IDM_HIDEMENU;
5143    WinSendMsg(hwndSysSubMenu,
5144               MM_INSERTITEM,
5145               MPFROMP(&mi), MPFROMP(GetPString(IDS_HIDEMENUTEXT)));
5146    SetSysMenu(hwndSysMenu);
5147
5148    size = sizeof(BOOL);
5149    if (PrfQueryProfileData(fmprof,
5150                            FM3Str,
5151                            "MenuInvisible", &temp, &size) && size && temp)
5152      WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_HIDEMENU, 0), MPVOID);
5153    size = sizeof(BOOL);
5154    if (PrfQueryProfileData(fmprof,
5155                            FM3Str, "FreeTree", &temp, &size) && size && temp)
5156      WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_FREETREE, 0), MPVOID);
5157    size = sizeof(BOOL);
5158    if (PrfQueryProfileData(fmprof,
5159                            FM3Str,
5160                            "AutoTile", &temp, &size) && size && !temp)
5161      WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_AUTOTILE, 0), MPVOID);
5162    size = sizeof(BOOL);
5163    if (PrfQueryProfileData(fmprof,
5164                            FM3Str, "Toolbar", &temp, &size) && size && !temp)
5165      WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_TOOLBAR, 0), MPVOID);
5166
5167    WinSetWindowText(WinWindowFromID(hwndFrame, FID_TITLEBAR), "FM/2");
5168    FixSwitchList(hwndFrame, NULL);
5169    break;                              // WM_CREATE
5170
5171  case UM_SETUP:
5172    /*
5173     * start up some initial children
5174     */
5175    load_tools(NULL);
5176    BuildTools(hwndToolback, TRUE);
5177    WinShowWindow(WinQueryWindow(hwnd, QW_PARENT), TRUE);
5178    PostMsg(MainObjectHwnd, UM_SETUP2, mp1, mp2);
5179    return 0;
5180
5181  case UM_SETUP2:
5182    {
5183      SWP swp;
5184      ULONG size = sizeof(SWP);
5185
5186      WinQueryWindowPos(hwnd, &swp);
5187      hwndTree = StartTreeCnr(hwnd, 0);
5188      if (!hwndTree)
5189        WinDestroyWindow(WinQueryWindow(hwnd, QW_PARENT));
5190      else {
5191        if (!fSaveState ||
5192            !PrfQueryProfileData(fmprof,
5193                                 FM3Str,
5194                                 "LastTreePos",
5195                                 &swp, &size) || size != sizeof(SWP)) {
5196
5197          INT ratio, height = 0;
5198
5199          if (!fNoTreeGap)
5200            height = WinQuerySysValue(HWND_DESKTOP, SV_CYICON) * 2;
5201          size = sizeof(ratio);
5202          if (!PrfQueryProfileData(fmprof,
5203                                   FM3Str,
5204                                   "TreeWindowRatio",
5205                                   (PVOID) & ratio,
5206                                   &size) || size < sizeof(ratio))
5207            ratio = 400;
5208          WinSetWindowPos(hwndTree,
5209                          HWND_TOP,
5210                          0,
5211                          height,
5212                          (swp.cx * 100) / ratio,
5213                          swp.cy - height,
5214                          SWP_SHOW | SWP_SIZE | SWP_MOVE |
5215                          SWP_ACTIVATE | SWP_ZORDER);
5216        }
5217        else
5218          WinSetWindowPos(hwndTree,
5219                          HWND_TOP,
5220                          swp.x,
5221                          swp.y,
5222                          swp.cx,
5223                          swp.cy,
5224                          swp.fl | SWP_MOVE | SWP_SIZE | SWP_SHOW |
5225                          SWP_ZORDER | SWP_ACTIVATE);
5226      }
5227      ResizeTools(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
5228                                  MAIN_TOOLS));
5229    }
5230    PostMsg(MainObjectHwnd, UM_SETUP3, mp1, mp2);
5231    return 0;
5232
5233  case UM_SETUP3:
5234    /* start remaining child windows */
5235    if (!fNoSaveState && fSaveState)
5236      PostMsg(MainObjectHwnd, UM_RESTORE, MPVOID, MPVOID);
5237    PostMsg(MainObjectHwnd, UM_SETUP4, mp1, mp2);
5238    return 0;
5239
5240  case UM_SETUP4:
5241    {
5242      INT argc = (INT) mp1, x;
5243      CHAR **argv = (CHAR **) mp2;
5244
5245      for (x = 1; x < argc; x++) {
5246        if (*argv[x] == '/' || *argv[x] == ';')
5247          continue;
5248        if (!IsFile(argv[x]) && !FindDirCnrByName(argv[x], FALSE))
5249          OpenDirCnr((HWND) 0, hwndMain, hwndTree, TRUE, argv[x]);
5250      }
5251    }
5252    PostMsg(MainObjectHwnd, UM_SETUP5, MPVOID, MPVOID);
5253    return 0;
5254
5255  case UM_SETUP5:
5256    if (fAutoTile)
5257      TileChildren(hwnd, TRUE);
5258    PostMsg(hwnd, UM_FILLUSERLIST, MPVOID, MPVOID);
5259    PostMsg(hwnd, UM_FILLSETUPLIST, MPVOID, MPVOID);
5260    PostMsg(hwnd, UM_FILLCMDLIST, MPVOID, MPVOID);
5261    PostMsg(hwnd, UM_FILLBUTTONLIST, MPVOID, MPVOID);
5262    {
5263      HWND hwndActive;
5264
5265      hwndActive = TopWindow(hwnd, hwndTree);
5266      if (hwndActive)
5267        WinSetWindowPos(hwndActive, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
5268    }
5269    if (fStartMinimized || fReminimize)
5270      PostMsg(hwndTree, UM_MINIMIZE, MPVOID, MPVOID);
5271    else if (fStartMaximized)
5272      PostMsg(hwndTree, UM_MAXIMIZE, MPVOID, MPVOID);
5273    fRunning = TRUE;
5274    return 0;
5275  }
5276
5277  return WinDefWindowProc(hwnd, msg, mp1, mp2);
5278}
5279
5280MRESULT EXPENTRY MainWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
5281{
5282  switch (msg) {
5283  case WM_CREATE:
5284  case UM_SETUP:
5285  case UM_SETUP2:
5286  case UM_SETUP3:
5287  case UM_SETUP4:
5288  case UM_SETUP5:
5289    return MainWMOnce(hwnd, msg, mp1, mp2);
5290
5291  case WM_CONTROLPOINTER:
5292    if (!fNoFinger &&
5293        (SHORT1FROMMP(mp1) == IDM_OPENWALK ||
5294         SHORT1FROMMP(mp1) == IDM_USERLIST))
5295      return MRFROMLONG(hptrFinger);
5296    break;
5297
5298  case UM_LOADFILE:
5299  case UM_THREADUSE:
5300  case UM_BUILDDRIVEBAR:
5301    return CommonMainWndProc(hwnd, msg, mp1, mp2);
5302
5303  case WM_BUTTON1UP:
5304  case WM_BUTTON2UP:
5305  case WM_BUTTON3UP:
5306  case WM_MOUSEMOVE:
5307    shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
5308    break;
5309
5310  case WM_CHAR:
5311    shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
5312    break;
5313
5314  case WM_MENUEND:
5315    if ((HWND) mp2 == MainPopupMenu) {
5316      WinDestroyWindow(MainPopupMenu);
5317      MainPopupMenu = (HWND) 0;
5318    }
5319    break;
5320
5321  case UM_CONTEXTMENU:
5322  case WM_CONTEXTMENU:
5323    if (CheckMenu(&MainPopupMenu, MAIN_POPUP)) {
5324      SetToggleChecks(MainPopupMenu);
5325      PopupMenu(hwnd, hwnd, MainPopupMenu);
5326    }
5327    if (msg == UM_CONTEXTMENU)
5328      return 0;
5329    return MRFROMSHORT(TRUE);
5330
5331  case UM_SETUSERLISTNAME:
5332    if (mp1) {
5333      if (fUserComboBox)
5334        WinSetWindowText(WinWindowFromID(hwndUserlist, CBID_EDIT),
5335                         (CHAR *) mp1);
5336      if (add_udir(FALSE, (CHAR *) mp1)) {
5337        if (fUserComboBox && fAutoAddDirs) {
5338          WinSendMsg(hwndUserlist, LM_INSERTITEM,
5339                     MPFROM2SHORT(LIT_SORTASCENDING, 0),
5340                     MPFROMP((CHAR *) mp1));
5341        }
5342      }
5343    }
5344    return 0;
5345
5346  case UM_ARRANGEICONS:
5347    ArrangeIcons(hwnd);
5348    return 0;
5349
5350  case WM_CHORD:
5351    PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_WINDOWDLG, 0), MPVOID);
5352    break;
5353
5354  case WM_SETFOCUS:
5355    if (mp2)
5356      PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
5357    break;
5358
5359  case UM_FOCUSME:
5360    WinSetFocus(hwndTree, TRUE);
5361    return 0;
5362
5363  case UM_RESCAN:
5364    TileChildren(hwnd, TRUE);
5365    return 0;
5366
5367  case WM_SAVEAPPLICATION:
5368    {
5369      SWP swp;
5370
5371      WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
5372      if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE))) {
5373        WinStoreWindowPos(FM2Str,
5374                          "MainWindowPos", WinQueryWindow(hwnd, QW_PARENT));
5375        if (!fNoSaveState && fSaveState)
5376          SaveDirCnrState(hwnd, NULL);
5377      }
5378    }
5379    break;
5380
5381  case MM_PORTHOLEINIT:
5382    switch (SHORT1FROMMP(mp1)) {
5383    case 0:
5384    case 1:
5385      {
5386        HWND hwndCurrent;
5387        ULONG wmsg;
5388
5389        wmsg = (SHORT1FROMMP(mp1) == 0) ? UM_FILESMENU : UM_VIEWSMENU;
5390        hwndCurrent = TopWindow(hwnd, (HWND) 0);
5391        PortholeInit((HWND) WinSendMsg(WinWindowFromID(hwndCurrent,
5392                                                       FID_CLIENT), wmsg,
5393                                       MPVOID, MPVOID), mp1, mp2);
5394      }
5395      break;
5396    }
5397    break;
5398
5399  case WM_INITMENU:
5400    switch (SHORT1FROMMP(mp1)) {
5401    case IDM_CONFIGMENU:
5402      SetToggleChecks((HWND) WinQueryWindowULong(hwnd, QWL_USER));
5403      break;
5404
5405    case IDM_WINDOWSMENU:
5406      /*
5407       * add child windows of client
5408       * and switchlist entries to end of pulldown menu
5409       */
5410      {
5411        HWND hwndMenu, hwndSubMenu;
5412        MENUITEM mi;
5413
5414        hwndMenu = WinQueryWindowULong(hwnd, QWL_USER);
5415        memset(&mi, 0, sizeof(mi));
5416        mi.iPosition = MIT_END;
5417        mi.afStyle = MIS_TEXT;
5418        if (!WinSendMsg(hwndMenu, MM_QUERYITEM,
5419                        MPFROM2SHORT(IDM_WINDOWSMENU, TRUE), MPFROMP(&mi)))
5420          break;
5421        hwndSubMenu = mi.hwndSubMenu;
5422        SetupWinList(hwndSubMenu, hwnd, WinQueryWindow(hwnd, QW_PARENT));
5423      }
5424      break;
5425
5426    default:
5427      {
5428        HWND hwndCurrent;
5429
5430        hwndCurrent = TopWindow(hwnd, (HWND) 0);
5431        if (hwndCurrent)
5432          WinSendMsg(hwndCurrent, UM_INITMENU, mp1, mp2);
5433      }
5434      break;
5435    }
5436    break;
5437
5438  case UM_ADDTOMENU:
5439    AddToMenu((CHAR *) mp1, WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
5440                                            FID_MENU));
5441    return 0;
5442
5443  case UM_FILLCMDLIST:
5444    WinSendMsg(hwndCmdlist, LM_DELETEALL, MPVOID, MPVOID);
5445    if (!cmdloaded)
5446      load_commands();
5447    if (cmdhead) {
5448
5449      LINKCMDS *info;
5450
5451      info = cmdhead;
5452      while (info) {
5453        WinSendMsg(hwndCmdlist, LM_INSERTITEM,
5454                   MPFROM2SHORT(LIT_END, 0), MPFROMP(info->title));
5455        info = info->next;
5456      }
5457    }
5458    return 0;
5459
5460  case UM_FILLSETUPLIST:
5461    WinSendMsg(hwndStatelist, LM_DELETEALL, MPVOID, MPVOID);
5462    if (fUserComboBox) {
5463      INT x;
5464
5465      if (!loadedsetups)
5466        load_setups();
5467      for (x = 0; x < MAXNUMSETUPS; x++) {
5468        if (*lastsetups[x])
5469          WinSendMsg(hwndStatelist, LM_INSERTITEM,
5470                     MPFROM2SHORT(LIT_SORTASCENDING, 0),
5471                     MPFROMP(lastsetups[x]));
5472      }
5473      WinSetWindowText(hwndStatelist, GetPString(IDS_STATETEXT));
5474    }
5475    return 0;
5476
5477  case UM_FILLBUTTONLIST:
5478    WinSendMsg(hwndButtonlist, LM_DELETEALL, MPVOID, MPVOID);
5479    if (fUserComboBox) {
5480
5481      BOOL foundit = FALSE, thisone;
5482      ULONG ulSearchCount;
5483      SHORT sSelect;
5484      FILEFINDBUF3 findbuf;
5485      HDIR hDir;
5486      CHAR *p;
5487
5488      DosError(FERR_DISABLEHARDERR);
5489      hDir = HDIR_CREATE;
5490      ulSearchCount = 1L;
5491      if (!DosFindFirst("*.TLS", &hDir, FILE_READONLY | FILE_ARCHIVED,
5492                        &findbuf, sizeof(FILEFINDBUF3),
5493                        &ulSearchCount, FIL_STANDARD)) {
5494        do {
5495          priority_bumped();
5496          if (!foundit) {
5497            thisone = FALSE;
5498            p = strrchr(lasttoolbox, '\\');
5499            if (!p)
5500              p = lasttoolbox;
5501            else
5502              p++;
5503            if (!stricmp(findbuf.achName, p))
5504              thisone = TRUE;
5505          }
5506          p = strrchr(findbuf.achName, '.');
5507          if (p)
5508            *p = 0;
5509          sSelect = (SHORT) WinSendMsg(hwndButtonlist, LM_INSERTITEM,
5510                                       MPFROM2SHORT(LIT_SORTASCENDING, 0),
5511                                       MPFROMP(findbuf.achName));
5512          if (!foundit && thisone && sSelect >= 0) {
5513            WinSendMsg(hwndButtonlist, LM_SELECTITEM,
5514                       MPFROM2SHORT(sSelect, 0), MPFROMLONG(TRUE));
5515            foundit = TRUE;
5516          }
5517        }
5518        while (!DosFindNext(hDir, &findbuf, sizeof(FILEFINDBUF3),
5519                            &ulSearchCount));
5520        DosFindClose(hDir);
5521        priority_bumped();
5522      }
5523      WinSetWindowText(hwndButtonlist, GetPString(IDS_TOOLBOXTEXT));
5524    }
5525    return 0;
5526
5527  case UM_FILLUSERLIST:
5528    WinSendMsg(hwndUserlist, LM_DELETEALL, MPVOID, MPVOID);
5529    if (fUserComboBox) {
5530      ULONG ulDriveNum;
5531      ULONG ulDriveMap;
5532      ULONG ulSearchCount;
5533      FILEFINDBUF3 findbuf;
5534      HDIR hDir;
5535      APIRET rc;
5536      LINKDIRS *info;
5537      LINKDIRS *temp;
5538
5539      if (!loadedudirs)
5540        load_udirs();
5541      DosError(FERR_DISABLEHARDERR);
5542      DosQCurDisk(&ulDriveNum, &ulDriveMap);
5543      info = udirhead;
5544      while (info) {
5545        if (IsFullName(info->path) &&
5546            !(driveflags[toupper(*info->path) - 'A'] &
5547              (DRIVE_IGNORE | DRIVE_INVALID))) {
5548          DosError(FERR_DISABLEHARDERR);
5549          hDir = HDIR_CREATE;
5550          ulSearchCount = 1L;
5551          if (!IsRoot(info->path))
5552            rc = DosFindFirst(info->path, &hDir, FILE_DIRECTORY |
5553                              MUST_HAVE_DIRECTORY | FILE_READONLY |
5554                              FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
5555                              &findbuf, sizeof(FILEFINDBUF3),
5556                              &ulSearchCount, FIL_STANDARD);
5557          else {
5558            rc = 0;
5559            findbuf.attrFile = FILE_DIRECTORY;
5560          }
5561          priority_bumped();
5562          if (!rc) {
5563            if (!IsRoot(info->path))
5564              DosFindClose(hDir);
5565            if (findbuf.attrFile & FILE_DIRECTORY)
5566              WinSendMsg(hwndUserlist, LM_INSERTITEM,
5567                         MPFROM2SHORT(LIT_SORTASCENDING, 0),
5568                         MPFROMP(info->path));
5569            else {
5570              temp = info->next;
5571              remove_udir(info->path);
5572              info = temp;
5573              continue;
5574            }
5575          }
5576          else if (!(ulDriveMap & (1L << (toupper(*info->path) - 'A')))) {
5577            temp = info->next;
5578            remove_udir(info->path);
5579            info = temp;
5580            continue;
5581          }
5582        }
5583        info = info->next;
5584      }
5585      info = ldirhead;
5586      while (info) {
5587        if (IsFullName(info->path) &&
5588            !(driveflags[toupper(*info->path) - 'A'] &
5589              (DRIVE_IGNORE | DRIVE_INVALID))) {
5590          DosError(FERR_DISABLEHARDERR);
5591          hDir = HDIR_CREATE;
5592          ulSearchCount = 1L;
5593          if (!IsRoot(info->path))
5594            rc = DosFindFirst(info->path, &hDir, FILE_DIRECTORY |
5595                              MUST_HAVE_DIRECTORY | FILE_READONLY |
5596                              FILE_ARCHIVED | FILE_SYSTEM | FILE_HIDDEN,
5597                              &findbuf, sizeof(FILEFINDBUF3),
5598                              &ulSearchCount, FIL_STANDARD);
5599          else {
5600            rc = 0;
5601            findbuf.attrFile = FILE_DIRECTORY;
5602          }
5603          priority_bumped();
5604          if (!rc) {
5605            if (!IsRoot(info->path))
5606              DosFindClose(hDir);
5607            if (findbuf.attrFile & FILE_DIRECTORY)
5608              WinSendMsg(hwndUserlist, LM_INSERTITEM,
5609                         MPFROM2SHORT(LIT_SORTASCENDING, 0),
5610                         MPFROMP(info->path));
5611            else {
5612              temp = info->next;
5613              remove_udir(info->path);
5614              info = temp;
5615              continue;
5616            }
5617          }
5618          else if (!(ulDriveMap & (1L << (toupper(*info->path) - 'A')))) {
5619            temp = info->next;
5620            remove_udir(info->path);
5621            info = temp;
5622            continue;
5623          }
5624        }
5625        info = info->next;
5626      }
5627      WinSendMsg(hwndUserlist, LM_INSERTITEM,
5628                 MPFROM2SHORT(0, 0),
5629                 MPFROMP(GetPString(IDS_NEWDIRECTORYTEXT)));
5630      WinSetWindowText(hwndUserlist, GetPString(IDS_COMMONDIRTEXT));
5631    }
5632    return 0;
5633
5634  case UM_SIZE:
5635    if (fAutoTile)
5636      TileChildren(hwnd, FALSE);
5637    else
5638      MoveChildrenAwayFromTree(hwnd);
5639    return 0;
5640
5641  case WM_SIZE:
5642    ResizeChildren(hwnd, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1),
5643                   SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
5644    break;
5645
5646  case WM_ERASEBACKGROUND:
5647    WinFillRect((HPS) mp1, (PRECTL) mp2, 0x00d0d0d0);
5648    return 0;
5649
5650  case WM_PAINT:
5651    {
5652      HPS hps;
5653      RECTL rcl;
5654
5655      hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
5656      if (hps) {
5657        WinQueryWindowRect(hwnd, &rcl);
5658        WinFillRect(hps, &rcl, CLR_PALEGRAY);
5659        WinEndPaint(hps);
5660      }
5661    }
5662    break;
5663
5664  case UM_CONTROL:
5665    switch (SHORT1FROMMP(mp1)) {
5666    case MAIN_CMDLIST:
5667    case MAIN_SETUPLIST:
5668    case MAIN_DRIVELIST:
5669    case MAIN_USERLIST:
5670    case MAIN_BUTTONLIST:
5671      switch (SHORT2FROMMP(mp1)) {
5672      case CBN_ENTER:
5673        {
5674          HWND hwndUL = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
5675                                        SHORT1FROMMP(mp1));
5676          CHAR path[CCHMAXPATH];
5677
5678          SetShiftState();
5679          WinQueryWindowText(WinWindowFromID(hwndUL, CBID_EDIT),
5680                             ((SHORT1FROMMP(mp1) == MAIN_USERLIST) ?
5681                              CCHMAXPATH : 13), path);
5682          bstrip(path);
5683          if (*path) {
5684            if (SHORT1FROMMP(mp1) == MAIN_USERLIST) {
5685              if (!strcmp(path, GetPString(IDS_NEWDIRECTORYTEXT))) {
5686                if (!LastDir ||
5687                    !WinSendMsg(WinQueryWindow(LastDir, QW_PARENT),
5688                                UM_CONTAINERDIR, MPFROMP(path), MPVOID))
5689                  save_dir2(path);
5690                if (!PMMkDir(hwnd, path, TRUE)) {
5691                  WinSetWindowText(hwndUL, GetPString(IDS_COMMONDIRTEXT));
5692                  break;
5693                }
5694              }
5695              if (!IsFile(path) && !FindDirCnrByName(path, TRUE)) {
5696
5697                HWND hwndDir;
5698
5699                if ((fUserListSwitches &&
5700                     !(shiftstate & KC_SHIFT)) ||
5701                    (!fUserListSwitches && (shiftstate & KC_SHIFT))) {
5702                  hwndDir = FindDirCnr(hwnd);
5703                  if (hwndDir) {
5704                    WinSendMsg(LastDir, UM_SETDIR, MPFROMP(path), MPVOID);
5705                    break;
5706                  }
5707                }
5708                OpenDirCnr((HWND) 0, hwndMain, hwndTree, FALSE, path);
5709              }
5710            }
5711            else if (SHORT1FROMMP(mp1) == MAIN_DRIVELIST) {
5712              ShowTreeRec(WinWindowFromID(WinWindowFromID(hwndTree,
5713                                                          FID_CLIENT),
5714                                          TREE_CNR), path, FALSE, TRUE);
5715              WinSetFocus(HWND_DESKTOP, hwndTree);
5716            }
5717            else if (SHORT1FROMMP(mp1) == MAIN_BUTTONLIST) {
5718              strcat(path, ".TLS");
5719              load_tools(path);
5720              PrfWriteProfileString(fmprof,
5721                                    FM3Str, "LastToolBox", lasttoolbox);
5722              BuildTools(hwndToolback, TRUE);
5723              WinSetWindowText(hwndButtonlist, GetPString(IDS_TOOLBOXTEXT));
5724            }
5725            else if (SHORT1FROMMP(mp1) == MAIN_SETUPLIST) {
5726
5727              CHAR s[80];
5728              ULONG size, numsaves = 0;
5729
5730              SetShiftState();
5731              size = sizeof(ULONG);
5732              sprintf(s, "%s.NumDirsLastTime", path);   // path is state name
5733              if (!PrfQueryProfileData
5734                  (fmprof, FM3Str, s, (PVOID) & numsaves, &size))
5735              {
5736                if ((WinGetLastError(WinQueryAnchorBlock(hwnd)) & 0xffff) == PMERR_NOT_IN_IDX) {
5737                  saymsg(MB_ENTER | MB_ICONASTERISK, hwnd,
5738                         GetPString(IDS_WARNINGTEXT),
5739                         GetPString(IDS_DOESNTEXISTTEXT), path);
5740                }
5741                else {
5742                  Win_Error2(hwnd, hwnd, __FILE__, __LINE__,
5743                             IDS_PRFQUERYPROFILEDATA);
5744                }
5745              }
5746              else if (!numsaves)
5747                Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
5748              else {
5749                if ((shiftstate & KC_SHIFT) == 0)
5750                  PostMsg(MainObjectHwnd, UM_RESTORE, MPVOID, MPFROMLONG(2L));
5751                {
5752                  char *temp;
5753
5754                  temp = xstrdup(path, pszSrcFile, __LINE__);
5755                  if (!temp) {
5756                    if ((shiftstate & KC_SHIFT) != 0 || fAutoTile)
5757                      PostMsg(MainObjectHwnd, UM_RESTORE, MPVOID,
5758                              MPFROMLONG(1L));
5759                  }
5760                  else {
5761                    if (!PostMsg
5762                        (MainObjectHwnd, UM_RESTORE, MPFROMP(temp), MPVOID))
5763                      free(temp);
5764                  }
5765                }
5766              }
5767              // fixme to hold restored state name for a while
5768              // WinSetWindowText(hwndStatelist, GetPString(IDS_STATETEXT));    // 15 Apr 07 SHL
5769            }
5770            else if (SHORT1FROMMP(mp1) == MAIN_CMDLIST) {
5771
5772              SHORT sSelect;
5773
5774              sSelect = (SHORT) WinSendMsg(hwndCmdlist,
5775                                           LM_QUERYSELECTION,
5776                                           MPFROMSHORT(LIT_FIRST), MPVOID);
5777              if (sSelect >= 0)
5778                WinPostMsg(hwnd,
5779                           WM_COMMAND,
5780                           MPFROM2SHORT(IDM_COMMANDSTART + sSelect, 0),
5781                           MPVOID);
5782              WinSetWindowText(hwndCmdlist, GetPString(IDS_COMMANDSTEXT));
5783            }
5784          }
5785        }
5786        break;
5787
5788      default:
5789        break;
5790      }
5791      break;
5792
5793    default:
5794      break;
5795    }
5796    return 0;
5797
5798  case WM_HELP:
5799    WinSendMsg(hwndHelp, HM_HELP_CONTENTS, MPVOID, MPVOID);
5800    break;
5801
5802  case UM_COMMAND:
5803  case WM_COMMAND:
5804
5805    return MainWMCommand(hwnd, msg, mp1, mp2);
5806
5807  case WM_CLOSE:
5808    WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
5809               WM_SYSCOMMAND, MPFROM2SHORT(SC_RESTORE, 0), MPVOID);
5810    WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
5811    fAmClosing = TRUE;
5812    WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
5813               WM_SYSCOMMAND, MPFROM2SHORT(SC_MINIMIZE, 0), MPVOID);
5814    if (CloseChildren(hwnd)) {
5815      fAmClosing = FALSE;
5816      if (fAutoTile)
5817        PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_TILE, 0), MPVOID);
5818      return 0;
5819    }
5820    if (hwndTree) {
5821      if (!PostMsg(hwndTree, WM_CLOSE, MPVOID, MPVOID))
5822        WinSendMsg(hwndTree, WM_CLOSE, MPVOID, MPVOID<