source: trunk/dll/mainwnd.c @ 618

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

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

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