source: trunk/dll/misc.c @ 747

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

Updates to direct editting code Subject and longnme appear to work fine. The filename doesn't include the path so the edit fails

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 62.8 KB
Line 
1
2/***********************************************************************
3
4  $Id: misc.c 747 2007-07-31 00:53:43Z gyoung $
5
6  Misc GUI support functions
7
8  Copyright (c) 1993-98 M. Kimes
9  Copyright (c) 2003, 2007 Steven H. Levine
10
11  11 Jun 03 SHL Add JFS and FAT32 support
12  01 Aug 04 SHL Rework lstrip/rstrip usage
13  01 Aug 04 SHL LoadLibPath: avoid buffer overflow
14  07 Jun 05 SHL Drop obsoletes
15  24 Jul 05 SHL Beautify
16  24 Jul 05 SHL Correct longname display option
17  17 Jul 06 SHL Use Runtime_Error
18  26 Jul 06 SHL Use chop_at_crnl
19  27 Jul 06 SHL Comments, apply indent
20  29 Jul 06 SHL Use xfgets_bstripcr
21  16 Aug 06 SHL Comments
22  31 Aug 06 SHL disable_menuitem: rework args to match name - sheesh
23  10 Oct 06 GKY Add NDFS32 support
24  18 Feb 07 GKY More drive type and drive icon support
25  10 Jun 07 GKY Add IsFm2Window as part of work around PM drag limit
26  05 Jul 07 GKY Fix menu removals for WORKPLACE_PROCESS=YES
27  23 Jul 07 SHL Sync with CNRITEM updates (ticket#24)
28
29***********************************************************************/
30
31#define INCL_DOS
32#define INCL_WIN
33#define INCL_GPI
34#include <os2.h>
35
36#include <stdarg.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <ctype.h>
41#include <share.h>
42#include <malloc.h>                     // headmin
43
44#include "fm3dll.h"
45#include "fm3dlg.h"
46#include "fm3str.h"
47
48#pragma data_seg(DATA1)
49
50static PSZ pszSrcFile = __FILE__;
51
52#pragma alloc_text(MAINWND5,SetSysMenu)
53#pragma alloc_text(MISC1,BoxWindow,PaintRecessedWindow,PostMsg,PaintSTextWindow,IsFm2Window)
54#pragma alloc_text(MISC1,FixSwitchList,FindDirCnr,CurrentRecord,SetShiftState,AddToListboxBottom)
55#pragma alloc_text(CNR_MISC1,AdjustCnrColVis,AdjustCnrColsForFSType)
56#pragma alloc_text(CNR_MISC1,AdjustCnrColsForPref,SetCnrCols)
57#pragma alloc_text(CNR_MISC2,CnrDirectEdit,OpenEdit)
58#pragma alloc_text(MISC2,SetMenuCheck,disable_menuitem,SetSortChecks)
59#pragma alloc_text(MISC2,SetDetailsSwitches,SetViewMenu)
60#pragma alloc_text(MISC3,SetupCommandMenu,AdjustDetailsSwitches)
61#pragma alloc_text(MISC3,ViewHelp,GetCmdSpec)
62#pragma alloc_text(MISC3,ExecFile,SetConditionalCascade,LoadDetailsSwitches)
63#pragma alloc_text(MISC3,FreeMallocedMem,FcloseFile)
64#pragma alloc_text(MISC4,PortholeInit,CheckMenu,Broadcast,SetupWinList,SwitchCommand)
65#pragma alloc_text(MISC6,DrawTargetEmphasis,EmphasizeButton)
66#pragma alloc_text(MISC_LIBPATH,LoadLibPath)
67#pragma alloc_text(MISC_SAY,SayView,SaySort,SayFilter)
68
69#ifndef BEGIN_LIBPATH
70#define BEGIN_LIBPATH            1
71#endif
72
73#ifndef END_LIBPATH
74#define END_LIBPATH              2
75#endif
76
77#ifndef ORD_DOS32QUERYEXTLIBPATH
78#define ORD_DOS32QUERYEXTLIBPATH 874
79#endif
80
81BOOL IsFm2Window(HWND hwnd, BOOL chkTid)
82{
83    PIB *ppib;
84    TIB *ptib;
85    APIRET rc;
86
87    rc = DosGetInfoBlocks(&ptib, &ppib);
88    if (rc) {
89      Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
90                "DosGetInfoBlocks");
91    }
92    else {
93      PID pid;
94      TID tid;
95
96      if (WinQueryWindowProcess(hwnd, &pid, &tid)) {
97        if (chkTid) {
98          // Is window owned by FM2 process on same thread?
99          if (pid == ppib->pib_ulpid && tid == ptib->tib_ptib2->tib2_ultid)
100            return TRUE;
101        }
102        // Is window owned by some FM2 thread
103        else if (pid == ppib->pib_ulpid)
104          return TRUE;
105      }
106    }
107    return FALSE;
108}
109
110VOID SetShiftState(VOID)
111{
112  shiftstate = 0;
113  if (WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000)
114    shiftstate |= KC_CTRL;
115  if (WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000)
116    shiftstate |= KC_SHIFT;
117  if (WinGetKeyState(HWND_DESKTOP, VK_ALT) & 0x8000)
118    shiftstate |= KC_ALT;
119}
120
121void EmphasizeButton(HWND hwnd, BOOL on)
122{
123  HPS hps = DrgGetPS(hwnd);
124
125  // fixme to complain?
126  if (hps) {
127    POINTL ptl;
128    SWP swp;
129
130    WinQueryWindowPos(hwnd, &swp);
131    ptl.x = 1;
132    ptl.y = 1;
133    GpiMove(hps, &ptl);
134    GpiSetColor(hps, ((on) ? CLR_BLACK : CLR_PALEGRAY));
135    ptl.x = swp.cx - 2;
136    ptl.y = swp.cy - 2;
137    GpiBox(hps, DRO_OUTLINE, &ptl, 0, 0);
138    DrgReleasePS(hps);
139    if (remove) //fixme always true
140      WinInvalidateRect(hwnd, NULL, FALSE);
141  }
142}
143
144void DrawTargetEmphasis(HWND hwnd, BOOL on)
145{
146  HPS hps = DrgGetPS(WinQueryWindow(hwnd, QW_PARENT));
147
148  if (hps) {
149    BoxWindow(hwnd, hps, ((on) ? CLR_BLACK : CLR_PALEGRAY));
150    DrgReleasePS(hps);
151  }
152}
153
154void BoxWindow(HWND hwnd, HPS hps, LONG color)
155{
156  POINTL ptl;
157  SWP swp;
158  BOOL releaseme = FALSE;
159
160  if (!hps) {
161    hps = WinGetPS(WinQueryWindow(hwnd, QW_PARENT));
162    releaseme = TRUE;
163  }
164  if (hps && WinQueryWindowPos(hwnd, &swp)) {
165    ptl.x = swp.x - 2;
166    ptl.y = swp.y - 2;
167    GpiMove(hps, &ptl);
168    GpiSetColor(hps, color);
169    ptl.x = swp.x + swp.cx + 1;
170    ptl.y = swp.y + swp.cy + 1;
171    GpiBox(hps, DRO_OUTLINE, &ptl, 0, 0);
172  }
173  if (releaseme && hps)
174    WinReleasePS(hps);
175}
176
177void PaintSTextWindow(HWND hwnd, HPS hps)
178{
179  /*
180   * paint a text window such that the rightmost part of the text is
181   * always visible even if the text length exceeds the length of the
182   * window -- otherwise, paint the window so that it is left-justified
183   * and vertically centered.
184   */
185
186  char *s = NULL;
187  long len;
188  POINTL aptl[TXTBOX_COUNT], ptl;
189  RECTL rcl;
190  char *p;
191  BOOL releaseme = FALSE;
192
193  if (!hps) {
194    releaseme = TRUE;
195    hps = WinGetPS(hwnd);
196  }
197  if (hps) {
198    WinQueryWindowRect(hwnd, &rcl);
199    WinFillRect(hps, &rcl, CLR_PALEGRAY);
200    len = WinQueryWindowTextLength(hwnd);
201    if (len)
202      s = xmalloc(len + 1, pszSrcFile, __LINE__);
203    if (s) {
204      *s = 0;
205      WinQueryWindowText(hwnd, CCHMAXPATH, s);
206      if (*s) {
207        rcl.xRight -= 3;
208        p = s;
209        GpiQueryTextBox(hps, 3, "...", TXTBOX_COUNT, aptl);
210        len = aptl[TXTBOX_TOPRIGHT].x;
211        do {
212          GpiQueryTextBox(hps, strlen(p), p, TXTBOX_COUNT, aptl);
213          if (aptl[TXTBOX_TOPRIGHT].x > (rcl.xRight - ((p != s) ? len : 0)))
214            p++;
215          else
216            break;
217        }
218        while (*p);
219        if (*p) {
220          GpiSetMix(hps, FM_OVERPAINT);
221          GpiSetColor(hps, CLR_BLACK);
222          ptl.x = 3;
223          ptl.y = ((rcl.yTop / 2) -
224                   ((aptl[TXTBOX_TOPRIGHT].y +
225                     aptl[TXTBOX_BOTTOMLEFT].y) / 2));
226          GpiMove(hps, &ptl);
227          if (p != s)
228            GpiCharString(hps, 3, "...");
229          GpiCharString(hps, strlen(p), p);
230        }
231      }
232      free(s);
233    }
234    if (releaseme)
235      WinReleasePS(hps);
236  }
237}
238
239VOID PaintRecessedWindow(HWND hwnd, HPS hps, BOOL outtie, BOOL dbl)
240{
241  /*
242   * paint a recessed box around the window
243   * two pixels width required around window for painting...
244   */
245  BOOL releaseme = FALSE;
246
247  if (!hps) {
248    hps = WinGetPS(WinQueryWindow(hwnd, QW_PARENT));
249    releaseme = TRUE;
250  }
251  if (hps) {
252
253    POINTL ptl;
254    SWP swp;
255
256    WinQueryWindowPos(hwnd, &swp);
257    ptl.x = swp.x - 1;
258    ptl.y = swp.y - 1;
259    GpiMove(hps, &ptl);
260    if (!outtie)
261      GpiSetColor(hps, CLR_WHITE);
262    else
263      GpiSetColor(hps, CLR_DARKGRAY);
264    ptl.x = swp.x + swp.cx;
265    GpiLine(hps, &ptl);
266    ptl.y = swp.y + swp.cy;
267    GpiLine(hps, &ptl);
268    if (dbl) {
269      ptl.x = swp.x - 2;
270      ptl.y = swp.y - 2;
271      GpiMove(hps, &ptl);
272      ptl.x = swp.x + swp.cx + 1;
273      GpiLine(hps, &ptl);
274      ptl.y = swp.y + swp.cy + 1;
275      GpiLine(hps, &ptl);
276    }
277    if (!outtie)
278      GpiSetColor(hps, CLR_DARKGRAY);
279    else
280      GpiSetColor(hps, CLR_WHITE);
281    if (dbl) {
282      ptl.x = swp.x - 2;
283      GpiLine(hps, &ptl);
284      ptl.y = swp.y - 2;
285      GpiLine(hps, &ptl);
286      ptl.x = swp.x + swp.cx;
287      ptl.y = swp.y + swp.cy;
288      GpiMove(hps, &ptl);
289    }
290    ptl.x = swp.x - 1;
291    GpiLine(hps, &ptl);
292    ptl.y = swp.y - 1;
293    GpiLine(hps, &ptl);
294    GpiSetColor(hps, CLR_PALEGRAY);
295    ptl.x = swp.x - (2 + (dbl != FALSE));
296    ptl.y = swp.y - (2 + (dbl != FALSE));
297    GpiMove(hps, &ptl);
298    ptl.x = swp.x + swp.cx + (1 + (dbl != FALSE));
299    GpiLine(hps, &ptl);
300    ptl.y = swp.y + swp.cy + (1 + (dbl != FALSE));
301    GpiLine(hps, &ptl);
302    ptl.x = swp.x - (2 + (dbl != FALSE));
303    GpiLine(hps, &ptl);
304    ptl.y = swp.y - (2 + (dbl != FALSE));
305    GpiLine(hps, &ptl);
306    if (releaseme)
307      WinReleasePS(hps);
308  }
309}
310
311BOOL AdjustCnrColVis(HWND hwndCnr, CHAR * title, BOOL visible, BOOL toggle)
312{
313  PFIELDINFO pfi = (PFIELDINFO) WinSendMsg(hwndCnr,
314                                           CM_QUERYDETAILFIELDINFO,
315                                           MPVOID, MPFROMSHORT(CMA_FIRST));
316
317  while (pfi) {
318    if (!strcmp(pfi->pTitleData, title)) {
319      if (toggle) {
320        if (pfi->flData & CFA_INVISIBLE)
321          pfi->flData &= (~CFA_INVISIBLE);
322        else
323          pfi->flData |= CFA_INVISIBLE;
324        return !(pfi->flData & CFA_INVISIBLE);
325      }
326      else {
327        if (visible)
328          pfi->flData &= (~CFA_INVISIBLE);
329        else
330          pfi->flData |= CFA_INVISIBLE;
331      }
332      return TRUE;
333    }
334    pfi = pfi->pNextFieldInfo;
335  }
336  return FALSE;
337}
338
339BOOL AdjustCnrColRO(HWND hwndCnr, CHAR * title, BOOL readonly, BOOL toggle)
340{
341  PFIELDINFO pfi = (PFIELDINFO) WinSendMsg(hwndCnr,
342                                           CM_QUERYDETAILFIELDINFO,
343                                           MPVOID, MPFROMSHORT(CMA_FIRST));
344
345  while (pfi) {
346    if (!strcmp(pfi->pTitleData, title)) {
347      if (toggle) {
348        if (pfi->flData & CFA_FIREADONLY)
349          pfi->flData &= (~CFA_FIREADONLY);
350        else
351          pfi->flData |= CFA_FIREADONLY;
352        return (pfi->flData & CFA_FIREADONLY);
353      }
354      else {
355        if (!readonly)
356          pfi->flData &= (~CFA_FIREADONLY);
357        else
358          pfi->flData |= CFA_FIREADONLY;
359      }
360      return TRUE;
361    }
362    pfi = pfi->pNextFieldInfo;
363  }
364  return FALSE;
365}
366
367VOID AdjustCnrColsForFSType(HWND hwndCnr, CHAR * directory, DIRCNRDATA * dcd)
368{
369  CHAR FileSystem[CCHMAXPATH];
370  INT x;
371  BOOL hasCreateDT;
372  BOOL hasAccessDT;
373  BOOL hasLongNames;
374  BOOL *pBool;
375
376  if (!directory || !*directory)
377    return;
378  x = CheckDrive(toupper(*directory), FileSystem, NULL);
379  if (x != -1) {
380    if (!stricmp(FileSystem, HPFS) ||
381        !stricmp(FileSystem, JFS) ||
382        !stricmp(FileSystem, FAT32) ||
383        !stricmp(FileSystem, RAMFS) ||
384        !stricmp(FileSystem, NDFS32) ||
385        !stricmp(FileSystem, NTFS) ||
386        !stricmp(FileSystem, HPFS386)) {
387      hasCreateDT = TRUE;
388      hasAccessDT = TRUE;
389      hasLongNames = TRUE;
390    }
391    else if (!strcmp(FileSystem, CDFS) || !strcmp(FileSystem, ISOFS)) {
392      hasCreateDT = TRUE;
393      hasAccessDT = FALSE;
394      hasLongNames = FALSE;
395    }
396    else {
397      // Assume FAT
398      hasCreateDT = FALSE;
399      hasAccessDT = FALSE;
400      hasLongNames = FALSE;
401    }
402  }
403  else {
404    // Assume FAT
405    hasCreateDT = FALSE;
406    hasAccessDT = FALSE;
407    hasLongNames = FALSE;
408  }
409  pBool = (dcd) ? &dcd->detailsladate : &detailsladate;
410  AdjustCnrColVis(hwndCnr, GetPString(IDS_LADATE),
411                  (*pBool) ? hasAccessDT : FALSE, FALSE);
412  pBool = (dcd) ? &dcd->detailslatime : &detailslatime;
413  AdjustCnrColVis(hwndCnr, GetPString(IDS_LATIME),
414                  (*pBool) ? hasAccessDT : FALSE, FALSE);
415  pBool = (dcd) ? &dcd->detailscrdate : &detailscrdate;
416  AdjustCnrColVis(hwndCnr, GetPString(IDS_CRDATE),
417                  (*pBool) ? hasCreateDT : FALSE, FALSE);
418  pBool = (dcd) ? &dcd->detailscrtime : &detailscrtime;
419  AdjustCnrColVis(hwndCnr, GetPString(IDS_CRTIME),
420                  (*pBool) ? hasCreateDT : FALSE, FALSE);
421  pBool = (dcd) ? &dcd->detailslongname : &detailslongname;
422  AdjustCnrColVis(hwndCnr, GetPString(IDS_LNAME),
423                  (*pBool) ? hasLongNames : FALSE, FALSE);
424  WinSendMsg(hwndCnr, CM_INVALIDATEDETAILFIELDINFO, MPVOID, MPVOID);
425}
426
427VOID AdjustCnrColsForPref(HWND hwndCnr, CHAR * directory, DIRCNRDATA * dcd,
428                          BOOL compare)
429{
430  BOOL *bool;
431
432  bool = (dcd) ? &dcd->detailssubject : &detailssubject;
433  AdjustCnrColVis(hwndCnr, ((compare) ? GetPString(IDS_STATUS) :
434                            GetPString(IDS_SUBJ)), *bool, FALSE);
435  bool = (dcd) ? &dcd->detailsattr : &detailsattr;
436  AdjustCnrColVis(hwndCnr, GetPString(IDS_ATTR), *bool, FALSE);
437  bool = (dcd) ? &dcd->detailsicon : &detailsicon;
438  AdjustCnrColVis(hwndCnr, GetPString(IDS_ICON), *bool, FALSE);
439  bool = (dcd) ? &dcd->detailslwdate : &detailslwdate;
440  AdjustCnrColVis(hwndCnr, GetPString(IDS_LWDATE), *bool, FALSE);
441  bool = (dcd) ? &dcd->detailslwtime : &detailslwtime;
442  AdjustCnrColVis(hwndCnr, GetPString(IDS_LWTIME), *bool, FALSE);
443  bool = (dcd) ? &dcd->detailsea : &detailsea;
444  AdjustCnrColVis(hwndCnr, GetPString(IDS_EA), *bool, FALSE);
445  bool = (dcd) ? &dcd->detailssize : &detailssize;
446  AdjustCnrColVis(hwndCnr, GetPString(IDS_SIZE), *bool, FALSE);
447  if (!directory) {
448    bool = (dcd) ? &dcd->detailsladate : &detailsladate;
449    AdjustCnrColVis(hwndCnr, GetPString(IDS_LADATE), *bool, FALSE);
450    bool = (dcd) ? &dcd->detailslatime : &detailslatime;
451    AdjustCnrColVis(hwndCnr, GetPString(IDS_LATIME), *bool, FALSE);
452    bool = (dcd) ? &dcd->detailscrdate : &detailscrdate;
453    AdjustCnrColVis(hwndCnr, GetPString(IDS_CRDATE), *bool, FALSE);
454    bool = (dcd) ? &dcd->detailscrtime : &detailscrtime;
455    AdjustCnrColVis(hwndCnr, GetPString(IDS_CRTIME), *bool, FALSE);
456    bool = (dcd) ? &dcd->detailslongname : &detailslongname;
457    AdjustCnrColVis(hwndCnr, GetPString(IDS_LNAME), *bool, FALSE);
458    WinSendMsg(hwndCnr, CM_INVALIDATEDETAILFIELDINFO, MPVOID, MPVOID);
459  }
460  else
461    AdjustCnrColsForFSType(hwndCnr, directory, dcd);
462}
463
464BOOL SetCnrCols(HWND hwndCnr, BOOL compare)
465{
466  BOOL fSuccess = TRUE;
467  PFIELDINFO pfi, pfiLastLeftCol, pfiIconCol;
468
469  // Allocate storage for container column data
470
471  pfi = WinSendMsg(hwndCnr, CM_ALLOCDETAILFIELDINFO,
472                   MPFROMLONG(CONTAINER_COLUMNS), NULL);
473
474  if (pfi) {
475
476    PFIELDINFO pfiFirst;
477    FIELDINFOINSERT fii;
478
479    // Store original value of pfi so we won't lose it when it changes.
480    // This will be needed on the CM_INSERTDETAILFIELDINFO message.
481
482    pfiFirst = pfi;
483
484    // Fill in column information for the icon column
485
486    pfi->flData = CFA_BITMAPORICON | CFA_CENTER | CFA_FIREADONLY;
487    pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
488    pfi->pTitleData = GetPString(IDS_ICON);
489    pfi->offStruct = FIELDOFFSET(MINIRECORDCORE, hptrIcon);
490
491    pfiIconCol = pfi;
492
493    // Fill in column information for the file name. Note that we are
494    // using the pszDisplayName variable rather than pszFileName. We do this
495    // because the container does not always display the full path file name.
496
497    pfi = pfi->pNextFieldInfo;
498    pfi->flData = CFA_STRING | CFA_LEFT | CFA_SEPARATOR;
499    pfi->flTitle = CFA_CENTER;
500    pfi->pTitleData = GetPString(IDS_FILENAME);
501    pfi->offStruct = FIELDOFFSET(CNRITEM, pszDisplayName);
502
503    // Fill in column information for the longname.
504
505    pfi = pfi->pNextFieldInfo;
506    pfi->flData = CFA_STRING | CFA_LEFT;
507    pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
508    pfi->pTitleData = GetPString(IDS_LNAME);
509    pfi->offStruct = FIELDOFFSET(CNRITEM, pszLongname);
510
511    // Store the current pfi value as that will be used to indicate the
512    // last column in the lefthand container window (we have a splitbar)
513
514    pfiLastLeftCol = pfi;
515
516    // Fill in column info for subjects
517
518    pfi = pfi->pNextFieldInfo;
519    pfi->flData = CFA_STRING | CFA_LEFT | CFA_SEPARATOR;
520    if (compare)
521      pfi->flData |= CFA_FIREADONLY;
522    pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
523    pfi->pTitleData = (compare) ? GetPString(IDS_STATUS) :
524      GetPString(IDS_SUBJ);
525    pfi->offStruct = FIELDOFFSET(CNRITEM, pszSubject);
526
527    // Fill in column information for the file size
528
529    pfi = pfi->pNextFieldInfo;
530    pfi->flData = CFA_ULONG | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
531    pfi->flTitle = CFA_CENTER;
532    pfi->pTitleData = GetPString(IDS_SIZE);
533    pfi->offStruct = FIELDOFFSET(CNRITEM, cbFile);
534
535    // Fill in the column information for the file's ea size
536
537    pfi = pfi->pNextFieldInfo;
538    pfi->flData = CFA_ULONG | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
539    pfi->flTitle = CFA_CENTER;
540    pfi->pTitleData = GetPString(IDS_EA);
541    pfi->offStruct = FIELDOFFSET(CNRITEM, easize);
542
543    // Fill in the column information for the file attribute
544
545    pfi = pfi->pNextFieldInfo;
546    pfi->flData = CFA_STRING | CFA_CENTER | CFA_SEPARATOR | CFA_FIREADONLY;
547    pfi->flTitle = CFA_CENTER | CFA_FITITLEREADONLY;
548    pfi->pTitleData = GetPString(IDS_ATTR);
549    pfi->offStruct = FIELDOFFSET(CNRITEM, pszDispAttr);
550
551    // Fill in column information for last write file date
552
553    pfi = pfi->pNextFieldInfo;
554    pfi->flData = CFA_DATE | CFA_RIGHT | CFA_FIREADONLY;
555    pfi->flTitle = CFA_CENTER;
556    pfi->pTitleData = GetPString(IDS_LWDATE);
557    pfi->offStruct = FIELDOFFSET(CNRITEM, date);
558
559    // Fill in column information for the last write file time
560
561    pfi = pfi->pNextFieldInfo;
562    pfi->flData = CFA_TIME | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
563    pfi->flTitle = CFA_CENTER;
564    pfi->pTitleData = GetPString(IDS_LWTIME);
565    pfi->offStruct = FIELDOFFSET(CNRITEM, time);
566
567    // Fill in column information for last access file date
568
569    pfi = pfi->pNextFieldInfo;
570    pfi->flData = CFA_DATE | CFA_RIGHT | CFA_FIREADONLY;
571    pfi->flTitle = CFA_CENTER;
572    pfi->pTitleData = GetPString(IDS_LADATE);
573    pfi->offStruct = FIELDOFFSET(CNRITEM, ladate);
574
575    // Fill in column information for the last access file time
576
577    pfi = pfi->pNextFieldInfo;
578    pfi->flData = CFA_TIME | CFA_RIGHT | CFA_SEPARATOR | CFA_FIREADONLY;
579    pfi->flTitle = CFA_CENTER;
580    pfi->pTitleData = GetPString(IDS_LATIME);
581    pfi->offStruct = FIELDOFFSET(CNRITEM, latime);
582
583    // Fill in column information for create file date
584
585    pfi = pfi->pNextFieldInfo;
586    pfi->flData = CFA_DATE | CFA_RIGHT | CFA_FIREADONLY;
587    pfi->flTitle = CFA_CENTER;
588    pfi->pTitleData = GetPString(IDS_CRDATE);
589    pfi->offStruct = FIELDOFFSET(CNRITEM, crdate);
590
591    // Fill in column information for the create file time
592
593    pfi = pfi->pNextFieldInfo;
594    pfi->flData = CFA_TIME | CFA_RIGHT | CFA_FIREADONLY;
595    pfi->flTitle = CFA_CENTER;
596    pfi->pTitleData = GetPString(IDS_CRTIME);
597    pfi->offStruct = FIELDOFFSET(CNRITEM, crtime);
598
599    // Use the CM_INSERTDETAILFIELDINFO message to tell the container
600    // all the column information it needs to function properly. Place
601    // this column info first in the column list and update the display
602    // after they are inserted (fInvalidateFieldInfo = TRUE)
603
604    (void)memset(&fii, 0, sizeof(FIELDINFOINSERT));
605
606    fii.cb = sizeof(FIELDINFOINSERT);
607    fii.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
608    fii.cFieldInfoInsert = (SHORT) CONTAINER_COLUMNS;
609    fii.fInvalidateFieldInfo = TRUE;
610
611    if (!WinSendMsg(hwndCnr, CM_INSERTDETAILFIELDINFO, MPFROMP(pfiFirst),
612                    MPFROMP(&fii)))
613      fSuccess = FALSE;
614  }
615  else
616    fSuccess = FALSE;
617
618  if (fSuccess) {
619
620    CNRINFO cnri;
621    ULONG size;
622
623    // Tell the container about the splitbar and where it goes
624
625    cnri.cb = sizeof(CNRINFO);
626    cnri.pFieldInfoLast = pfiLastLeftCol;
627    cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 32;
628    cnri.pFieldInfoObject = pfiIconCol;
629    size = sizeof(LONG);
630    PrfQueryProfileData(fmprof,
631                        appname, "CnrSplitBar", &cnri.xVertSplitbar, &size);
632    if (cnri.xVertSplitbar <= 0)
633      cnri.xVertSplitbar = DIR_SPLITBAR_OFFSET - 32;
634    if (!WinSendMsg(hwndCnr, CM_SETCNRINFO, MPFROMP(&cnri),
635                    MPFROMLONG(CMA_PFIELDINFOLAST | CMA_PFIELDINFOOBJECT |
636                               CMA_XVERTSPLITBAR)))
637      fSuccess = FALSE;
638  }
639
640  return fSuccess;
641}
642
643MRESULT CnrDirectEdit(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
644{
645  switch (SHORT2FROMMP(mp1)) {
646  case CN_BEGINEDIT:
647    if (mp2) {
648      PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
649      PCNRITEM pci = (PCNRITEM) ((PCNREDITDATA) mp2)->pRecord;
650
651      if (pci &&
652          (INT) pci != -1 &&
653          !IsRoot(pci->pszFileName) &&
654          !(pci->flags & RECFLAGS_ENV) && !(pci->flags & RECFLAGS_UNDERENV)) {
655        if (!pfi || pfi->offStruct == FIELDOFFSET(CNRITEM, pszFileName)) {
656          PostMsg(hwnd, UM_FIXEDITNAME, MPFROMP(pci->pszFileName), MPVOID);
657        }
658        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, pszSubject))
659          PostMsg(hwnd, UM_FIXCNRMLE, MPFROMLONG(40), MPVOID);
660        else
661          PostMsg(hwnd, UM_FIXCNRMLE, MPFROMLONG(CCHMAXPATH), MPVOID);
662      }
663      else
664        PostMsg(hwnd, CM_CLOSEEDIT, MPVOID, MPVOID);
665    }
666    break;
667
668  case CN_REALLOCPSZ:
669    if (mp2) {
670      PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
671      PCNRITEM pci = (PCNRITEM) ((PCNREDITDATA) mp2)->pRecord;
672      CHAR szData[CCHMAXPATH], testname[CCHMAXPATH];
673      HWND hwndMLE = WinWindowFromID(hwnd, CID_MLE);
674
675      if (pci && (INT) pci != -1 && !IsRoot(pci->pszFileName)) {
676        if (pfi && pfi->offStruct == FIELDOFFSET(CNRITEM, pszSubject)) {
677
678          APIRET rc;
679          EAOP2 eaop;
680          PFEA2LIST pfealist = NULL;
681          CHAR szSubject[2048];
682          ULONG ealen;
683          USHORT len;
684          CHAR *eaval;
685          LONG retlen;
686
687          retlen = WinQueryWindowText(hwndMLE, sizeof(szSubject), szSubject);
688          szSubject[retlen + 1] = 0;
689          chop_at_crnl(szSubject);
690          bstrip(szSubject);
691          WinSetWindowText(hwndMLE, szSubject);
692          len = strlen(szSubject);
693          if (len)
694            ealen = sizeof(FEA2LIST) + 9 + len + 4;
695          else
696            ealen = sizeof(FEALIST) + 9;
697          rc = DosAllocMem((PPVOID) & pfealist, ealen + 64,
698                           OBJ_TILE | PAG_COMMIT | PAG_READ | PAG_WRITE);
699          if (rc)
700            Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile,
701                      __LINE__, GetPString(IDS_OUTOFMEMORY));
702          else {
703            memset(pfealist, 0, ealen + 1);
704            pfealist->cbList = ealen;
705            pfealist->list[0].oNextEntryOffset = 0;
706            pfealist->list[0].fEA = 0;
707            pfealist->list[0].cbName = 8;
708            strcpy(pfealist->list[0].szName, SUBJECT);
709            if (len) {
710              eaval = pfealist->list[0].szName + 9;
711              *(USHORT *) eaval = (USHORT) EAT_ASCII;
712              eaval += sizeof(USHORT);
713              *(USHORT *) eaval = (USHORT) len;
714              eaval += sizeof(USHORT);
715              memcpy(eaval, szSubject, len);
716              pfealist->list[0].cbValue = len + (sizeof(USHORT) * 2);
717            }
718            else
719              pfealist->list[0].cbValue = 0;
720            eaop.fpGEA2List = (PGEA2LIST) 0;
721            eaop.fpFEA2List = pfealist;
722            eaop.oError = 0L;
723            rc = DosSetPathInfo(pci->pszFileName,
724                                FIL_QUERYEASIZE,
725                                (PVOID) & eaop, sizeof(EAOP2), DSPI_WRTTHRU);
726            DosFreeMem(pfealist);
727            if (rc)
728              return FALSE;
729          }
730          return (MRESULT) TRUE;
731        }
732        else if (pfi && pfi->offStruct == FIELDOFFSET(CNRITEM, pszLongname)) {
733
734          CHAR longname[CCHMAXPATHCOMP];
735        LONG retlen;
736
737          *longname = 0;
738          retlen = WinQueryWindowText(hwndMLE, sizeof(longname), longname);
739          longname[retlen + 1] = 0;
740          chop_at_crnl(longname);
741          WinSetWindowText(hwndMLE, longname);
742          pci->pszFileName = xrealloc(pci->pszFileName, sizeof(longname), pszSrcFile, __LINE__);
743          return (MRESULT) WriteLongName(pci->pszFileName, longname);
744        }
745        else {
746          pci->pszFileName = pci->pszDisplayName;
747          WinQueryWindowText(hwndMLE, sizeof(szData), szData);
748          pci->pszFileName = xrealloc(pci->pszFileName, sizeof(szData), pszSrcFile, __LINE__);
749          if (strchr(szData, '?') ||
750              strchr(szData, '*') || IsRoot(pci->pszFileName))
751            return (MRESULT) FALSE;
752          /* If the text changed, rename the file system object. */
753          chop_at_crnl(szData);
754          bstrip(szData);
755          if (!IsFullName(szData))
756            Runtime_Error(pszSrcFile, __LINE__, "bad name");
757          else {
758            if (DosQueryPathInfo(szData,
759                                 FIL_QUERYFULLNAME,
760                                 testname, sizeof(testname)))
761                return FALSE;
762            if (DosQueryPathInfo(pci->pszFileName,
763                                 FIL_QUERYFULLNAME, szData, sizeof(szData)))
764              strcpy(szData, pci->pszFileName);
765            WinSetWindowText(hwndMLE, szData);
766            if (strcmp(szData, testname)) {
767              if (stricmp(szData, testname) && IsFile(testname) != -1) {
768                DosBeep(50, 100);       /* exists; disallow */
769                return (MRESULT) FALSE;
770              }
771              if (docopyf(MOVE, szData, "%s", testname))
772                Runtime_Error(pszSrcFile, __LINE__, "docopyf");
773              else {
774                CHAR *filename;
775
776                filename = xstrdup(testname, pszSrcFile, __LINE__);
777                if (filename) {
778                  if (!PostMsg(hwnd,
779                               UM_FIXEDITNAME, MPVOID, MPFROMP(filename)))
780                    free(filename);
781                }
782                if (stricmp(testname, pci->pszFileName)) {
783                  PostMsg(hwnd, UM_FIXEDITNAME, MPFROMLONG(-1), MPFROMP(pci));
784                  filename = xstrdup(pci->pszFileName, pszSrcFile, __LINE__);
785                  if (filename) {
786                    if (!PostMsg(hwnd,
787                                 UM_FIXEDITNAME, MPVOID, MPFROMP(filename)))
788                      free(filename);
789                  }
790                }
791              }
792            }
793          }
794        }
795      }
796    }
797    return FALSE;
798
799  case CN_ENDEDIT:
800    if (mp2) {
801      PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
802      PCNRITEM pci = (PCNRITEM) ((PCNREDITDATA) mp2)->pRecord;
803
804      if (pci && (INT) pci != -1 && !IsRoot(pci->pszFileName)) {
805        WinSendMsg(hwnd,
806                   CM_INVALIDATERECORD,
807                   MPFROMP(&pci),
808                   MPFROM2SHORT(1, CMA_ERASE | CMA_TEXTCHANGED));
809        if (pfi && pfi->offStruct == FIELDOFFSET(CNRITEM, pszFileName))
810          PostMsg(hwnd, UM_SORTRECORD, MPVOID, MPVOID);
811      }
812      else {
813        USHORT cmd = 0;
814
815        if (!pfi || pfi->offStruct == FIELDOFFSET(CNRITEM, pszFileName))
816          cmd = IDM_SORTSMARTNAME;
817        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, cbFile))
818          cmd = IDM_SORTSIZE;
819        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, easize))
820          cmd = IDM_SORTEASIZE;
821        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, date))
822          cmd = IDM_SORTLWDATE;
823        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, time))
824          cmd = IDM_SORTLWDATE;
825        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, ladate))
826          cmd = IDM_SORTLADATE;
827        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, latime))
828          cmd = IDM_SORTLADATE;
829        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, crdate))
830          cmd = IDM_SORTCRDATE;
831        else if (pfi->offStruct == FIELDOFFSET(CNRITEM, crtime))
832          cmd = IDM_SORTCRDATE;
833        if (cmd)
834          PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
835      }
836    }
837    break;
838  }
839  return (MRESULT) - 1;
840}
841
842BOOL SetMenuCheck(HWND hwndMenu, USHORT id, BOOL * bool, BOOL toggle,
843                  CHAR * savename)
844{
845  if (toggle) {
846    *bool = (*bool) ? FALSE : TRUE;
847    if (savename && *savename)
848      PrfWriteProfileData(fmprof, appname, savename, bool, sizeof(BOOL));
849  }
850  WinSendMsg(hwndMenu, MM_SETITEMATTR,
851             MPFROM2SHORT(id, 1),
852             MPFROM2SHORT(MIA_CHECKED, (*bool ? MIA_CHECKED : 0)));
853  return *bool;
854}
855
856//== disable_menuitem() disable or enable_menuitem ==
857
858VOID disable_menuitem(HWND hwndMenu, USHORT id, BOOL disable)
859{
860  WinSendMsg(hwndMenu, MM_SETITEMATTR,
861             MPFROM2SHORT(id, TRUE),
862             MPFROM2SHORT(MIA_DISABLED, (disable ? MIA_DISABLED : 0)));
863}
864
865//== ViewHelp() invoke view.exe, return TRUE if OK ==
866
867BOOL ViewHelp(CHAR * filename)
868{
869  CHAR s[CCHMAXPATH + 81];
870  FILE *fp;
871  INT ret = -1;
872
873  fp = _fsopen(filename, "rb", SH_DENYNO);
874  if (fp) {
875    *s = 0;
876    fread(s, 1, 3, fp);
877    if (*s != 'H' || s[1] != 'S' || s[2] != 'P') {
878      fclose(fp);
879      return FALSE;
880    }
881    fclose(fp);
882    ret = runemf2(SEPARATE | WINDOWED, HWND_DESKTOP, NULL, NULL,
883                  "VIEW.EXE \"%s\"", filename);
884  }
885
886  return (ret != -1);
887}
888
889//== ExecFile() run file, return 1 if OK 0 if skipped -1 if can't run ==
890
891INT ExecFile(HWND hwnd, CHAR * filename)
892{
893  EXECARGS ex;
894  CHAR cl[1001], path[CCHMAXPATH], *p;
895  APIRET ret;
896  static INT lastflags = 0;
897
898  strcpy(path, filename);
899  p = strrchr(path, '\\');
900  if (!p)
901    p = strrchr(path, ':');
902  if (p) {
903    if (*p == ':') {
904      p++;
905      *p = '\\';
906      p++;
907    }
908    *p = 0;
909  }
910  else
911    *path = 0;
912  *cl = 0;
913  if (needs_quoting(filename))
914    strcat(cl, "\"");
915  strcat(cl, filename);
916  if (needs_quoting(filename))
917    strcat(cl, "\"");
918  memset(&ex, 0, sizeof(ex));
919  ex.flags = lastflags;
920  ex.commandline = cl;
921  *ex.path = 0;
922  *ex.environment = 0;
923  ret = WinDlgBox(HWND_DESKTOP, hwnd, CmdLineDlgProc, FM3ModHandle,
924                  EXEC_FRAME, &ex);
925  if (ret == 1) {
926    lastflags = ex.flags;
927    return runemf2(ex.flags, hwnd, path,
928                   (*ex.environment) ? ex.environment : NULL, "%s", cl) != -1;
929  }
930  else if (ret != 0)
931    return -1;
932  return 0;
933}
934
935VOID SetDetailsSwitches(HWND hwnd, DIRCNRDATA * dcd)
936{
937  WinCheckMenuItem(hwnd, IDM_SHOWLNAMES,
938                   (dcd) ? dcd->detailslongname : detailslongname);
939  WinCheckMenuItem(hwnd, IDM_SHOWSUBJECT,
940                   (dcd) ? dcd->detailssubject : detailssubject);
941  WinCheckMenuItem(hwnd, IDM_SHOWEAS, (dcd) ? dcd->detailsea : detailsea);
942  WinCheckMenuItem(hwnd, IDM_SHOWSIZE,
943                   (dcd) ? dcd->detailssize : detailssize);
944  WinCheckMenuItem(hwnd, IDM_SHOWICON,
945                   (dcd) ? dcd->detailsicon : detailsicon);
946  WinCheckMenuItem(hwnd, IDM_SHOWLWDATE,
947                   (dcd) ? dcd->detailslwdate : detailslwdate);
948  WinCheckMenuItem(hwnd, IDM_SHOWLWTIME,
949                   (dcd) ? dcd->detailslwtime : detailslwtime);
950  WinCheckMenuItem(hwnd, IDM_SHOWLADATE,
951                   (dcd) ? dcd->detailsladate : detailsladate);
952  WinCheckMenuItem(hwnd, IDM_SHOWLATIME,
953                   (dcd) ? dcd->detailslatime : detailslatime);
954  WinCheckMenuItem(hwnd, IDM_SHOWCRDATE,
955                   (dcd) ? dcd->detailscrdate : detailscrdate);
956  WinCheckMenuItem(hwnd, IDM_SHOWCRTIME,
957                   (dcd) ? dcd->detailscrtime : detailscrtime);
958  WinCheckMenuItem(hwnd, IDM_SHOWATTR,
959                   (dcd) ? dcd->detailsattr : detailsattr);
960}
961
962VOID AdjustDetailsSwitches(HWND hwnd, HWND hwndMenu, USHORT cmd,
963                           CHAR * directory, CHAR * keyroot,
964                           DIRCNRDATA * dcd, BOOL compare)
965{
966  CHAR s[CCHMAXPATH], *eos = s;
967  BOOL *bool = NULL;
968
969  *s = 0;
970  if (keyroot) {
971    strcpy(s, keyroot);
972    strcat(s, ".");
973    eos = &s[strlen(s)];
974  }
975  switch (cmd) {
976  case IDM_SHOWLNAMES:
977    bool = (dcd) ? &dcd->detailslongname : &detailslongname;
978    strcpy(eos, "DetailsLongname");
979    break;
980  case IDM_SHOWSUBJECT:
981    bool = (dcd) ? &dcd->detailssubject : &detailssubject;
982    strcpy(eos, "DetailsSubject");
983    break;
984  case IDM_SHOWEAS:
985    bool = (dcd) ? &dcd->detailsea : &detailsea;
986    strcpy(eos, "DetailsEA");
987    break;
988  case IDM_SHOWSIZE:
989    bool = (dcd) ? &dcd->detailssize : &detailssize;
990    strcpy(eos, "DetailsSize");
991    break;
992  case IDM_SHOWICON:
993    bool = (dcd) ? &dcd->detailsicon : &detailsicon;
994    strcpy(eos, "DetailsIcon");
995    break;
996  case IDM_SHOWLWDATE:
997    bool = (dcd) ? &dcd->detailslwdate : &detailslwdate;
998    strcpy(eos, "DetailsLWDate");
999    break;
1000  case IDM_SHOWLWTIME:
1001    bool = (dcd) ? &dcd->detailslwtime : &detailslwtime;
1002    strcpy(eos, "DetailsLWTime");
1003    break;
1004  case IDM_SHOWLADATE:
1005    bool = (dcd) ? &dcd->detailsladate : &detailsladate;
1006    strcpy(eos, "DetailsLADate");
1007    break;
1008  case IDM_SHOWLATIME:
1009    bool = (dcd) ? &dcd->detailslatime : &detailslatime;
1010    strcpy(eos, "DetailsLATime");
1011    break;
1012  case IDM_SHOWCRDATE:
1013    bool = (dcd) ? &dcd->detailscrdate : &detailscrdate;
1014    strcpy(eos, "DetailsCRDate");
1015    break;
1016  case IDM_SHOWCRTIME:
1017    bool = (dcd) ? &dcd->detailscrtime : &detailscrtime;
1018    strcpy(eos, "DetailsCRTime");
1019    break;
1020  case IDM_SHOWATTR:
1021    bool = (dcd) ? &dcd->detailsattr : &detailsattr;
1022    strcpy(eos, "DetailsAttr");
1023    break;
1024  default:
1025    if (hwndMenu)
1026      SetDetailsSwitches(hwndMenu, dcd);
1027    return;
1028  }
1029  if (bool)
1030    *bool = (*bool) ? FALSE : TRUE;
1031  if (*s && bool)
1032    PrfWriteProfileData(fmprof, appname, s, bool, sizeof(BOOL));
1033  if (hwnd)
1034    AdjustCnrColsForPref(hwnd, directory, dcd, compare);
1035  if (hwndMenu)
1036    SetDetailsSwitches(hwndMenu, dcd);
1037}
1038
1039VOID SetConditionalCascade(HWND hwndMenu, USHORT id, USHORT def)
1040{
1041  MENUITEM mi;
1042
1043  mi.iPosition = MIT_END;
1044  mi.hItem = 0L;
1045  mi.hwndSubMenu = (HWND) 0;
1046  mi.afAttribute = 0;
1047  mi.afStyle = MIS_TEXT;
1048  if (WinSendMsg
1049      (hwndMenu, MM_QUERYITEM, MPFROM2SHORT(id, TRUE), MPFROMP(&mi))) {
1050    WinSetWindowBits(mi.hwndSubMenu, QWL_STYLE, MS_CONDITIONALCASCADE,
1051                     MS_CONDITIONALCASCADE);
1052    WinSendMsg(mi.hwndSubMenu, MM_SETDEFAULTITEMID, MPFROMSHORT(def), MPVOID);
1053    WinCheckMenuItem(mi.hwndSubMenu, def, TRUE);
1054  }
1055}
1056
1057VOID SetSortChecks(HWND hwndMenu, INT sortflags)
1058{
1059  WinCheckMenuItem(hwndMenu, IDM_SORTNONE, FALSE);
1060  WinCheckMenuItem(hwndMenu, IDM_SORTFIRST, FALSE);
1061  WinCheckMenuItem(hwndMenu, IDM_SORTLAST, FALSE);
1062  WinCheckMenuItem(hwndMenu, IDM_SORTSIZE, FALSE);
1063  WinCheckMenuItem(hwndMenu, IDM_SORTEASIZE, FALSE);
1064  WinCheckMenuItem(hwndMenu, IDM_SORTLWDATE, FALSE);
1065  WinCheckMenuItem(hwndMenu, IDM_SORTLADATE, FALSE);
1066  WinCheckMenuItem(hwndMenu, IDM_SORTCRDATE, FALSE);
1067  WinCheckMenuItem(hwndMenu, IDM_SORTFILENAME, FALSE);
1068  WinCheckMenuItem(hwndMenu, IDM_SORTNAME, FALSE);
1069  WinCheckMenuItem(hwndMenu, IDM_SORTSUBJECT, FALSE);
1070  WinCheckMenuItem(hwndMenu, IDM_SORTDIRSFIRST, FALSE);
1071  WinCheckMenuItem(hwndMenu, IDM_SORTDIRSLAST, FALSE);
1072  WinCheckMenuItem(hwndMenu, IDM_SORTREVERSE, FALSE);
1073  if (sortflags & SORT_FIRSTEXTENSION)
1074    WinCheckMenuItem(hwndMenu, IDM_SORTFIRST, TRUE);
1075  else if (sortflags & SORT_LASTEXTENSION)
1076    WinCheckMenuItem(hwndMenu, IDM_SORTLAST, TRUE);
1077  else if (sortflags & SORT_SIZE)
1078    WinCheckMenuItem(hwndMenu, IDM_SORTSIZE, TRUE);
1079  else if (sortflags & SORT_EASIZE)
1080    WinCheckMenuItem(hwndMenu, IDM_SORTEASIZE, TRUE);
1081  else if (sortflags & SORT_LWDATE)
1082    WinCheckMenuItem(hwndMenu, IDM_SORTLWDATE, TRUE);
1083  else if (sortflags & SORT_LADATE)
1084    WinCheckMenuItem(hwndMenu, IDM_SORTLADATE, TRUE);
1085  else if (sortflags & SORT_CRDATE)
1086    WinCheckMenuItem(hwndMenu, IDM_SORTCRDATE, TRUE);
1087  else if (sortflags & SORT_FILENAME)
1088    WinCheckMenuItem(hwndMenu, IDM_SORTFILENAME, TRUE);
1089  else if (sortflags & SORT_NOSORT)
1090    WinCheckMenuItem(hwndMenu, IDM_SORTNONE, TRUE);
1091  else if (sortflags & SORT_SUBJECT)
1092    WinCheckMenuItem(hwndMenu, IDM_SORTSUBJECT, TRUE);
1093  else
1094    WinCheckMenuItem(hwndMenu, IDM_SORTNAME, TRUE);
1095  if (sortflags & SORT_DIRSFIRST)
1096    WinCheckMenuItem(hwndMenu, IDM_SORTDIRSFIRST, TRUE);
1097  else if (sortflags & SORT_DIRSLAST)
1098    WinCheckMenuItem(hwndMenu, IDM_SORTDIRSLAST, TRUE);
1099  if (sortflags & SORT_REVERSE)
1100    WinCheckMenuItem(hwndMenu, IDM_SORTREVERSE, TRUE);
1101}
1102
1103VOID FreeMallocedMem(VOID * mem)
1104{
1105  /* for use by apps that don't use the DLLs runtime library */
1106  free(mem);
1107}
1108
1109VOID FcloseFile(FILE * fp)
1110{
1111  /* for use by apps that don't use the DLLs runtime library */
1112  fclose(fp);
1113}
1114
1115VOID SetupCommandMenu(HWND hwndMenu, HWND hwndCnr)
1116{
1117  MENUITEM mi, mit;
1118  INT x;
1119  SHORT numitems;
1120  LINKCMDS *info;
1121
1122  if (!cmdloaded)
1123    load_commands();
1124  mi.iPosition = MIT_END;
1125  mi.hwndSubMenu = (HWND) 0;
1126  mi.hItem = 0L;
1127  mi.afAttribute = 0;
1128  mi.afStyle = MIS_TEXT;
1129  memset(&mit, 0, sizeof(MENUITEM));
1130  if (WinQueryWindowUShort(hwndMenu, QWS_ID) == IDM_COMMANDSMENU)
1131    mit.hwndSubMenu = hwndMenu;
1132  else
1133    WinSendMsg(hwndMenu, MM_QUERYITEM,
1134               MPFROM2SHORT(IDM_COMMANDSMENU, TRUE), MPFROMP(&mit));
1135  if (mit.hwndSubMenu) {
1136    numitems = (SHORT) WinSendMsg(mit.hwndSubMenu, MM_QUERYITEMCOUNT,
1137                                  MPVOID, MPVOID);
1138    WinSendMsg(mit.hwndSubMenu, MM_DELETEITEM, MPFROMSHORT(-1), MPVOID);
1139    for (x = 0; x < numitems; x++)
1140      WinSendMsg(mit.hwndSubMenu, MM_DELETEITEM,
1141                 MPFROMSHORT((SHORT) (x + IDM_COMMANDSTART)), MPVOID);
1142    if (hwndCnr && cmdhead) {
1143      x = 0;
1144      info = cmdhead;
1145      while (info) {
1146
1147        CHAR s[CCHMAXPATH + 24];
1148
1149        sprintf(s,
1150                "%s%s%s",
1151                info->title,
1152                (x < 20) ? "\tCtrl + " : NullStr,
1153                (x < 20 && x > 9) ? "Shift + " : NullStr);
1154        if (x < 20)
1155          sprintf(&s[strlen(s)], "%d",
1156                  (((x % 10) + 1) == 10) ? 0 : (x % 10) + 1);
1157        mi.id = IDM_COMMANDSTART + x;
1158        mi.afAttribute = (((info->flags & ONCE) != 0) ?
1159                          MIA_CHECKED : 0) |
1160          (((info->flags & PROMPT) != 0) ? MIA_FRAMED : 0);
1161        mi.afStyle = MIS_TEXT;
1162        if (!(x % 24) && x && info->next)
1163          mi.afStyle |= MIS_BREAK;
1164        WinSendMsg(mit.hwndSubMenu, MM_INSERTITEM, MPFROMP(&mi), MPFROMP(s));
1165        x++;
1166        info = info->next;
1167      }
1168    }
1169  }
1170}
1171
1172VOID LoadDetailsSwitches(CHAR * keyroot, DIRCNRDATA * dcd)
1173{
1174  ULONG size;
1175  CHAR s[CCHMAXPATH], *eos = s;
1176  BOOL *bool;
1177
1178  *s = 0;
1179  if (keyroot) {
1180    strcpy(s, keyroot);
1181    strcat(s, ".");
1182    eos = &s[strlen(s)];
1183  }
1184  strcpy(eos, "DetailsLongname");
1185  if (dcd)
1186    bool = &dcd->detailslongname;
1187  else
1188    bool = &detailslongname;
1189  *bool = detailslongname;
1190  size = sizeof(BOOL);
1191  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1192  strcpy(eos, "DetailsSubject");
1193  if (dcd)
1194    bool = &dcd->detailssubject;
1195  else
1196    bool = &detailssubject;
1197  *bool = detailssubject;
1198  size = sizeof(BOOL);
1199  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1200  strcpy(eos, "DetailsEA");
1201  if (dcd)
1202    bool = &dcd->detailsea;
1203  else
1204    bool = &detailsea;
1205  *bool = detailsea;
1206  size = sizeof(BOOL);
1207  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1208  strcpy(eos, "DetailsSize");
1209  if (dcd)
1210    bool = &dcd->detailssize;
1211  else
1212    bool = &detailssize;
1213  *bool = detailssize;
1214  size = sizeof(BOOL);
1215  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1216  strcpy(eos, "DetailsIcon");
1217  if (dcd)
1218    bool = &dcd->detailsicon;
1219  else
1220    bool = &detailsicon;
1221  *bool = detailsicon;
1222  size = sizeof(BOOL);
1223  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1224  strcpy(eos, "DetailsAttr");
1225  if (dcd)
1226    bool = &dcd->detailsattr;
1227  else
1228    bool = &detailsattr;
1229  *bool = detailsattr;
1230  size = sizeof(BOOL);
1231  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1232  strcpy(eos, "DetailsCRDate");
1233  if (dcd)
1234    bool = &dcd->detailscrdate;
1235  else
1236    bool = &detailscrdate;
1237  *bool = detailscrdate;
1238  size = sizeof(BOOL);
1239  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1240  strcpy(eos, "DetailsCRTime");
1241  if (dcd)
1242    bool = &dcd->detailscrtime;
1243  else
1244    bool = &detailscrtime;
1245  *bool = detailscrtime;
1246  size = sizeof(BOOL);
1247  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1248  strcpy(eos, "DetailsLWDate");
1249  if (dcd)
1250    bool = &dcd->detailslwdate;
1251  else
1252    bool = &detailslwdate;
1253  *bool = detailslwdate;
1254  size = sizeof(BOOL);
1255  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1256  strcpy(eos, "DetailsLWTime");
1257  if (dcd)
1258    bool = &dcd->detailslwtime;
1259  else
1260    bool = &detailslwtime;
1261  *bool = detailslwtime;
1262  size = sizeof(BOOL);
1263  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1264  strcpy(eos, "DetailsLADate");
1265  if (dcd)
1266    bool = &dcd->detailsladate;
1267  else
1268    bool = &detailsladate;
1269  *bool = detailsladate;
1270  size = sizeof(BOOL);
1271  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1272  strcpy(eos, "DetailsLATime");
1273  if (dcd)
1274    bool = &dcd->detailslatime;
1275  else
1276    bool = &detailslatime;
1277  *bool = detailslatime;
1278  size = sizeof(BOOL);
1279  PrfQueryProfileData(fmprof, appname, s, (PVOID) bool, &size);
1280}
1281
1282HWND FindDirCnr(HWND hwndParent)
1283{
1284  HWND found, hwndDir = (HWND) 0;
1285  HENUM henum;
1286
1287  henum = WinBeginEnumWindows(hwndParent);
1288  while ((found = WinGetNextWindow(henum)) != NULLHANDLE) {
1289    hwndDir = WinWindowFromID(found, FID_CLIENT);
1290    if (hwndDir) {
1291      hwndDir = WinWindowFromID(hwndDir, DIR_CNR);
1292      if (hwndDir)
1293        break;
1294      hwndDir = (HWND) 0;
1295    }
1296  }
1297  WinEndEnumWindows(henum);
1298
1299  return hwndDir;
1300}
1301
1302VOID HeapThread(VOID * dummy)
1303{
1304  ULONG postcount;
1305  APIRET rc;
1306
1307  rc = DosCreateEventSem(NULL, &CompactSem, 0L, FALSE);
1308  if (rc)
1309    Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
1310              "DosCreateEventSem");
1311  else {
1312    priority_normal();
1313    for (;;) {
1314      if (DosWaitEventSem(CompactSem, SEM_INDEFINITE_WAIT))
1315        break;
1316      _heapmin();
1317      DosResetEventSem(CompactSem, &postcount);
1318    }
1319  }
1320}
1321
1322VOID FixSwitchList(HWND hwnd, CHAR * text)
1323{
1324  HSWITCH hswitch;
1325  SWCNTRL swctl;
1326
1327  hswitch = WinQuerySwitchHandle(hwnd, 0);
1328  if (hswitch) {
1329    if (!WinQuerySwitchEntry(hswitch, &swctl)) {
1330      strcpy(swctl.szSwtitle, "FM/2");
1331      WinChangeSwitchEntry(hswitch, &swctl);
1332    }
1333  }
1334}
1335
1336VOID QuickPopup(HWND hwnd, DIRCNRDATA * dcd, HWND hwndMenu, USHORT id)
1337{
1338  dcd->hwndLastMenu = hwndMenu;
1339  if (dcd->hwndLastMenu && !dcd->cnremphasized) {
1340    WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1341               MPFROM2SHORT(TRUE, CRA_SOURCE));
1342    dcd->cnremphasized = TRUE;
1343  }
1344  if (dcd->flWindowAttr & CV_MINI)
1345    WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
1346  if (!WinPopupMenu(hwnd, hwnd, dcd->hwndLastMenu,
1347                    8, 8, 0,
1348                    PU_HCONSTRAIN | PU_VCONSTRAIN |
1349                    PU_KEYBOARD | PU_MOUSEBUTTON1)) {
1350    if (dcd->cnremphasized) {
1351      WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1352                 MPFROM2SHORT(FALSE, CRA_SOURCE));
1353      dcd->cnremphasized = FALSE;
1354    }
1355  }
1356  else
1357    WinSendMsg(dcd->hwndLastMenu, MM_SELECTITEM,
1358               MPFROM2SHORT(id, TRUE), MPFROM2SHORT(0, FALSE));
1359}
1360
1361PMINIRECORDCORE CurrentRecord(HWND hwndCnr)
1362{
1363  SHORT attrib = (fSelectedAlways) ? CRA_SELECTED : CRA_CURSORED;
1364  PMINIRECORDCORE pmi;
1365
1366  for (;;) {
1367    pmi = (PMINIRECORDCORE) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
1368                                       MPFROMLONG(CMA_FIRST),
1369                                       MPFROMSHORT(attrib));
1370    if ((!pmi || (INT) pmi == -1) && attrib == CRA_SELECTED)    /* punt */
1371      attrib = CRA_CURSORED;
1372    else
1373      break;
1374  }
1375  return ((INT) pmi == -1) ? NULL : pmi;
1376}
1377
1378BOOL PostMsg(HWND h, ULONG msg, MPARAM mp1, MPARAM mp2)
1379{
1380  BOOL rc = WinPostMsg(h, msg, mp1, mp2);
1381
1382  if (!rc) {
1383
1384      // If window owned by some other process or some other thread?
1385      if (!IsFm2Window(h, 1)) {
1386          QMSG qmsg;
1387          for (;;) {
1388            DosSleep(1);
1389            rc = WinPostMsg(h, msg, mp1, mp2);
1390            if (rc)
1391              break;                    // OK
1392            if (!WinIsWindow((HAB) 0, h))
1393              break;                    // Window gone
1394            if (WinPeekMsg((HAB) 0, &qmsg, (HWND) 0, 0, 0, PM_NOREMOVE))
1395              break;                    // Queue has message(s)
1396          }                             // for
1397        }
1398    }
1399  return rc;
1400}
1401
1402VOID OpenEdit(HWND hwnd)
1403{
1404  CNREDITDATA ced;
1405  PCNRITEM pci;
1406  PFIELDINFO pfi;
1407
1408  pci = (PCNRITEM) WinSendMsg(hwnd,
1409                              CM_QUERYRECORDEMPHASIS,
1410                              MPFROMLONG(CMA_FIRST),
1411                              MPFROMSHORT(CRA_CURSORED));
1412  if (pci && (INT) pci != -1) {
1413    memset(&ced, 0, sizeof(ced));
1414    ced.cb = sizeof(ced);
1415    ced.hwndCnr = hwnd;
1416    ced.id = WinQueryWindowUShort(hwnd, QWS_ID);
1417    ced.pRecord = (PRECORDCORE) pci;
1418    pfi = (PFIELDINFO) WinSendMsg(hwnd,
1419                                  CM_QUERYDETAILFIELDINFO,
1420                                  MPVOID, MPFROMSHORT(CMA_FIRST));
1421    if (!pfi)
1422      WinSendMsg(hwnd, CM_OPENEDIT, MPFROMP(&ced), MPVOID);
1423    else {
1424      while (pfi && (INT) pfi != -1 &&
1425             pfi->offStruct != FIELDOFFSET(CNRITEM, pszFileName))
1426        pfi = (PFIELDINFO) WinSendMsg(hwnd,
1427                                      CM_QUERYDETAILFIELDINFO,
1428                                      MPFROMP(pfi), MPFROMSHORT(CMA_NEXT));
1429      if (pfi && (INT) pfi != -1) {
1430        ced.pFieldInfo = pfi;
1431        {
1432          CNRINFO cnri;
1433
1434          memset(&cnri, 0, sizeof(CNRINFO));
1435          cnri.cb = sizeof(CNRINFO);
1436          WinSendMsg(hwnd,
1437                     CM_QUERYCNRINFO,
1438                     MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1439          if (cnri.flWindowAttr & CV_DETAIL)
1440            ced.id = CID_LEFTDVWND;
1441        }
1442        WinSendMsg(hwnd, CM_OPENEDIT, MPFROMP(&ced), MPVOID);
1443      }
1444    }
1445  }
1446}
1447
1448#ifdef NEVER
1449VOID QuickView(HWND hwnd, CHAR * filename)
1450{
1451  if (filename && IsFile(filename) == 1) {
1452    if (TestBinary(filename) && *binview) {
1453
1454      CHAR *list[2];
1455
1456      list[0] = filename;
1457      list[1] = NULL;
1458      ExecOnList(hwnd, binview, WINDOWED | SEPARATE, NULL, list, NULL);
1459      return;
1460    }
1461    else if (*viewer) {
1462
1463      CHAR *list[2];
1464
1465      list[0] = filename;
1466      list[1] = NULL;
1467      ExecOnList(hwnd, viewer, WINDOWED | SEPARATE |
1468                 ((fViewChild) ? CHILD : 0), NULL, list, NULL);
1469      return;
1470    }
1471    StartMLEEditor(HWND_DESKTOP, 5, filename, (HWND) 0);
1472  }
1473}
1474
1475VOID QuickEdit(HWND hwnd, CHAR * filename)
1476{
1477  if (filename && IsFile(filename) == 1) {
1478    if (TestBinary(filename) && *bined) {
1479
1480      CHAR *list[2];
1481
1482      list[0] = filename;
1483      list[1] = NULL;
1484      ExecOnList(hwnd, bined, WINDOWED | SEPARATE, NULL, list, NULL);
1485      return;
1486    }
1487    else if (*editor) {
1488
1489      CHAR *list[2];
1490
1491      list[0] = filename;
1492      list[1] = NULL;
1493      ExecOnList(hwnd, editor, WINDOWED | SEPARATE, NULL, list, NULL);
1494      return;
1495    }
1496    StartMLEEditor(HWND_DESKTOP, 4, filename, (HWND) 0);
1497  }
1498}
1499#endif
1500
1501VOID PortholeInit(HWND hwndNew, MPARAM mp1, MPARAM mp2)
1502{
1503  static HWND DefMenu = (HWND) 0;
1504  HWND hwndMenu = (HWND) mp2;
1505
1506  {
1507    ULONG style;
1508
1509    style = WinQueryWindowULong(hwndMenu, QWL_STYLE);
1510    if (!(style & MS_ACTIONBAR))
1511      return;
1512  }
1513
1514  switch (SHORT1FROMMP(mp1)) {
1515  case 0:
1516    {
1517      HWND hwndNow;
1518      MENUITEM mi;
1519      ULONG ulStyle;
1520
1521      memset(&mi, 0, sizeof(mi));
1522      mi.iPosition = MIT_END;
1523      mi.afStyle = MIS_TEXT;
1524      WinSendMsg(hwndMenu, MM_QUERYITEM,
1525                 MPFROM2SHORT(IDM_FILESMENU, TRUE), MPFROMP(&mi));
1526      if (!DefMenu)
1527        DefMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, DEFMENU);
1528      hwndNow = mi.hwndSubMenu;
1529      mi.hwndSubMenu = hwndNew;
1530      if (!mi.hwndSubMenu)
1531        mi.hwndSubMenu = DefMenu;
1532      WinSetParent(hwndNow, WinQueryObjectWindow(HWND_DESKTOP), FALSE);
1533      WinSetOwner(hwndNow, WinQueryObjectWindow(HWND_DESKTOP));
1534      WinSetOwner(mi.hwndSubMenu, hwndMenu);
1535      WinSetParent(mi.hwndSubMenu, hwndMenu, FALSE);
1536      WinSetWindowUShort(mi.hwndSubMenu, QWS_ID, IDM_FILESMENU);
1537      mi.afStyle = MIS_SUBMENU;
1538      ulStyle = WinQueryWindowULong(mi.hwndSubMenu, QWL_STYLE);
1539      ulStyle &= -WS_SAVEBITS;
1540      ulStyle |= MS_POPUP | WS_CLIPSIBLINGS | WS_SAVEBITS;
1541      WinSetWindowULong(mi.hwndSubMenu, QWL_STYLE, ulStyle);
1542      WinSendMsg(hwndMenu, MM_SETITEM, MPFROM2SHORT(0, TRUE), MPFROMP(&mi));
1543    }
1544    break;
1545
1546  case 1:
1547    {
1548      HWND hwndNow;
1549      MENUITEM mi;
1550      ULONG ulStyle;
1551
1552      memset(&mi, 0, sizeof(mi));
1553      mi.iPosition = MIT_END;
1554      mi.afStyle = MIS_TEXT;
1555      WinSendMsg(hwndMenu, MM_QUERYITEM,
1556                 MPFROM2SHORT(IDM_VIEWSMENU, TRUE), MPFROMP(&mi));
1557      if (!DefMenu)
1558        DefMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, DEFMENU);
1559      hwndNow = mi.hwndSubMenu;
1560      mi.hwndSubMenu = hwndNew;
1561      if (!mi.hwndSubMenu)
1562        mi.hwndSubMenu = DefMenu;
1563      WinSetParent(hwndNow, WinQueryObjectWindow(HWND_DESKTOP), FALSE);
1564      WinSetOwner(hwndNow, WinQueryObjectWindow(HWND_DESKTOP));
1565      WinSetOwner(mi.hwndSubMenu, hwndMenu);
1566      WinSetParent(mi.hwndSubMenu, hwndMenu, FALSE);
1567      WinSetWindowUShort(mi.hwndSubMenu, QWS_ID, IDM_VIEWSMENU);
1568      mi.afStyle = MIS_SUBMENU;
1569      ulStyle = WinQueryWindowULong(mi.hwndSubMenu, QWL_STYLE);
1570      ulStyle &= -WS_SAVEBITS;
1571      ulStyle |= MS_POPUP | WS_CLIPSIBLINGS | WS_SAVEBITS;
1572      WinSetWindowULong(mi.hwndSubMenu, QWL_STYLE, ulStyle);
1573      WinSendMsg(hwndMenu, MM_SETITEM, MPFROM2SHORT(0, TRUE), MPFROMP(&mi));
1574    }
1575    break;
1576  }
1577}
1578
1579HWND CheckMenu(HWND * hwndMenu, USHORT id)
1580{
1581  /* load and adjust menus as required */
1582  if (!*hwndMenu || !WinIsWindow((HAB) 0, *hwndMenu)) {
1583    *hwndMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
1584    if (hwndMenu == &DirMenu) {
1585      WinSetWindowUShort(DirMenu, QWS_ID, IDM_FILESMENU);
1586      SetConditionalCascade(DirMenu, IDM_COMMANDSMENU, IDM_DOITYOURSELF);
1587      SetConditionalCascade(DirMenu, IDM_COPYMENU, IDM_COPY);
1588      SetConditionalCascade(DirMenu, IDM_MOVEMENU, IDM_MOVE);
1589      SetConditionalCascade(DirMenu, IDM_SAVESUBMENU, IDM_SAVETOCLIP);
1590      SetConditionalCascade(DirMenu, IDM_VIEWSUBMENU, IDM_INFO);
1591      SetConditionalCascade(DirMenu, IDM_EDITSUBMENU, IDM_ATTRS);
1592      SetConditionalCascade(DirMenu, IDM_DELETESUBMENU,
1593                            (fDefaultDeletePerm) ? IDM_PERMDELETE :
1594                            IDM_DELETE);
1595      SetConditionalCascade(DirMenu, IDM_MISCSUBMENU, IDM_SIZES);
1596      SetConditionalCascade(DirMenu, IDM_OPENSUBMENU, IDM_OPENWINDOW);
1597      if (fWorkPlace) {
1598        WinSendMsg(DirMenu, MM_DELETEITEM,
1599                   MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1600        WinSendMsg(DirMenu, MM_DELETEITEM,
1601                   MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
1602      }
1603    }
1604    else if (hwndMenu == &TreeMenu) {
1605      WinSetWindowUShort(TreeMenu, QWS_ID, IDM_FILESMENU);
1606      SetConditionalCascade(TreeMenu, IDM_COMMANDSMENU, IDM_DOITYOURSELF);
1607      SetConditionalCascade(TreeMenu, IDM_SAVESUBMENU, IDM_SAVETOCLIP);
1608      SetConditionalCascade(TreeMenu, IDM_EDITSUBMENU, IDM_ATTRS);
1609      SetConditionalCascade(TreeMenu, IDM_EXPANDSUBMENU, IDM_EXPAND);
1610      SetConditionalCascade(TreeMenu, IDM_MISCSUBMENU, IDM_SIZES);
1611      SetConditionalCascade(TreeMenu, IDM_OPENSUBMENU, IDM_OPENWINDOW);
1612      if (fWorkPlace) {
1613        WinSendMsg(TreeMenu, MM_DELETEITEM,
1614                   MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1615        WinSendMsg(TreeMenu, MM_DELETEITEM,
1616                   MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
1617      }
1618    }
1619    else if (hwndMenu == &ArcMenu) {
1620      WinSetWindowUShort(ArcMenu, QWS_ID, IDM_FILESMENU);
1621      SetConditionalCascade(ArcMenu, IDM_EXTRACTSUBMENU, IDM_EXTRACT);
1622      SetConditionalCascade(ArcMenu, IDM_EDITSUBMENU, IDM_EDIT);
1623      SetConditionalCascade(ArcMenu, IDM_VIEWSUBMENU, IDM_VIEW);
1624      if (fWorkPlace)
1625        WinSendMsg(ArcMenu, MM_DELETEITEM,
1626                   MPFROM2SHORT(IDM_FOLDERAFTEREXTRACT, TRUE), MPVOID);
1627    }
1628    else if (hwndMenu == &FileMenu) {
1629      WinSetWindowUShort(FileMenu, QWS_ID, IDM_FILESMENU);
1630      SetConditionalCascade(FileMenu, IDM_COMMANDSMENU, IDM_DOITYOURSELF);
1631      SetConditionalCascade(FileMenu, IDM_COPYMENU, IDM_COPY);
1632      SetConditionalCascade(FileMenu, IDM_MOVEMENU, IDM_MOVE);
1633      SetConditionalCascade(FileMenu, IDM_SAVESUBMENU, IDM_SAVETOCLIP);
1634      SetConditionalCascade(FileMenu, IDM_VIEWSUBMENU, IDM_VIEW);
1635      SetConditionalCascade(FileMenu, IDM_EDITSUBMENU, IDM_EDIT);
1636      SetConditionalCascade(FileMenu, IDM_COLLECTMENU, IDM_COLLECT);
1637      SetConditionalCascade(FileMenu, IDM_DELETESUBMENU,
1638                            (fDefaultDeletePerm) ? IDM_PERMDELETE :
1639                            IDM_DELETE);
1640      SetConditionalCascade(FileMenu, IDM_OPENSUBMENU, IDM_OPENDEFAULT);
1641      SetConditionalCascade(FileMenu, IDM_OBJECTSUBMENU, IDM_SHADOW);
1642      if (fWorkPlace) {
1643        WinSendMsg(FileMenu, MM_DELETEITEM,
1644                   MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1645        WinSendMsg(FileMenu, MM_DELETEITEM,
1646                   MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
1647      }
1648    }
1649    else if (hwndMenu == &DirCnrMenu) {
1650      WinSetWindowUShort(DirCnrMenu, QWS_ID, IDM_VIEWSMENU);
1651      SetConditionalCascade(DirCnrMenu, IDM_MISCSUBMENU, IDM_SIZES);
1652      SetConditionalCascade(DirCnrMenu, IDM_OPENSUBMENU, IDM_OPENSETTINGSME);
1653      if (fWorkPlace)
1654        WinSendMsg(DirCnrMenu, MM_DELETEITEM,
1655                   MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1656    }
1657    else if (hwndMenu == &TreeCnrMenu) {
1658      WinSetWindowUShort(TreeCnrMenu, QWS_ID, IDM_VIEWSMENU);
1659      SetConditionalCascade(TreeCnrMenu, IDM_PARTITIONSMENU, IDM_PARTITION);
1660    }
1661    else if (hwndMenu == &ArcCnrMenu) {
1662      WinSetWindowUShort(ArcCnrMenu, QWS_ID, IDM_VIEWSMENU);
1663      SetConditionalCascade(ArcCnrMenu, IDM_EXTRACTSUBMENU, IDM_ARCEXTRACT);
1664      if (fWorkPlace)
1665        WinSendMsg(ArcCnrMenu, MM_DELETEITEM,
1666                   MPFROM2SHORT(IDM_FOLDERAFTEREXTRACT, TRUE), MPVOID);
1667    }
1668    else if (hwndMenu == &CollectorCnrMenu) {
1669      WinSetWindowUShort(CollectorCnrMenu, QWS_ID, IDM_VIEWSMENU);
1670      SetConditionalCascade(CollectorCnrMenu, IDM_COLLECTMENU,
1671                            IDM_COLLECTFROMCLIP);
1672    }
1673    else if (hwndMenu == &CollectorFileMenu) {
1674      WinSetWindowUShort(CollectorFileMenu, QWS_ID, IDM_FILESMENU);
1675      SetConditionalCascade(CollectorFileMenu, IDM_COMMANDSMENU,
1676                            IDM_DOITYOURSELF);
1677      SetConditionalCascade(CollectorFileMenu, IDM_COPYMENU, IDM_COPY);
1678      SetConditionalCascade(CollectorFileMenu, IDM_MOVEMENU, IDM_MOVE);
1679      SetConditionalCascade(CollectorFileMenu, IDM_SAVESUBMENU,
1680                            IDM_SAVETOCLIP);
1681      SetConditionalCascade(CollectorFileMenu, IDM_VIEWSUBMENU, IDM_VIEW);
1682      SetConditionalCascade(CollectorFileMenu, IDM_EDITSUBMENU, IDM_EDIT);
1683      SetConditionalCascade(CollectorFileMenu, IDM_DELETESUBMENU,
1684                            (fDefaultDeletePerm) ? IDM_PERMDELETE :
1685                            IDM_DELETE);
1686      SetConditionalCascade(CollectorFileMenu, IDM_OPENSUBMENU,
1687                            IDM_OPENDEFAULT);
1688      SetConditionalCascade(CollectorFileMenu, IDM_OBJECTSUBMENU, IDM_SHADOW);
1689      if (fWorkPlace) {
1690        WinSendMsg(CollectorFileMenu, MM_DELETEITEM,
1691                   MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1692        WinSendMsg(CollectorFileMenu, MM_DELETEITEM,
1693                   MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
1694      }
1695    }
1696    else if (hwndMenu == &CollectorDirMenu) {
1697      WinSetWindowUShort(CollectorDirMenu, QWS_ID, IDM_FILESMENU);
1698      SetConditionalCascade(CollectorDirMenu, IDM_COMMANDSMENU,
1699                            IDM_DOITYOURSELF);
1700      SetConditionalCascade(CollectorDirMenu, IDM_COPYMENU, IDM_COPY);
1701      SetConditionalCascade(CollectorDirMenu, IDM_MOVEMENU, IDM_MOVE);
1702      SetConditionalCascade(CollectorDirMenu, IDM_SAVESUBMENU,
1703                            IDM_SAVETOCLIP);
1704      SetConditionalCascade(CollectorDirMenu, IDM_VIEWSUBMENU, IDM_INFO);
1705      SetConditionalCascade(CollectorDirMenu, IDM_EDITSUBMENU, IDM_ATTRS);
1706      SetConditionalCascade(CollectorDirMenu, IDM_DELETESUBMENU,
1707                            (fDefaultDeletePerm) ? IDM_PERMDELETE :
1708                            IDM_DELETE);
1709      SetConditionalCascade(CollectorDirMenu, IDM_MISCSUBMENU, IDM_SIZES);
1710      SetConditionalCascade(CollectorDirMenu, IDM_OPENSUBMENU,
1711                            IDM_OPENWINDOW);
1712      if (fWorkPlace) {
1713        WinSendMsg(CollectorDirMenu, MM_DELETEITEM,
1714                   MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1715        WinSendMsg(CollectorDirMenu, MM_DELETEITEM,
1716                   MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
1717      }
1718    }
1719    else if (hwndMenu == &MainPopupMenu) {
1720      WinSetWindowUShort(MainPopupMenu, QWS_ID, IDM_MAINPOPUP);
1721      SetConditionalCascade(MainPopupMenu, IDM_TOOLSUBMENU, IDM_TOOLBAR);
1722      SetConditionalCascade(MainPopupMenu, IDM_AUTOVIEWSUBMENU, IDM_AUTOVIEW);
1723    }
1724  }
1725  return *hwndMenu;
1726}
1727
1728SHORT AddToListboxBottom(HWND hwnd, CHAR * str)
1729{
1730  SHORT ln;
1731
1732  ln = (SHORT) WinSendMsg(hwnd, LM_INSERTITEM, MPFROM2SHORT(LIT_END, 0),
1733                          MPFROMP(str));
1734  if (ln)
1735    WinSendMsg(hwnd, LM_SELECTITEM, MPFROM2SHORT(ln, 0), MPVOID);
1736  return ln;
1737}
1738
1739VOID SetSysMenu(HWND hwndSysMenu)
1740{
1741  CHAR s[128], *p;
1742
1743  if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
1744                 MPFROM2SHORT(SC_RESTORE, 128), MPFROMP(s))) {
1745    p = strchr(s, '\t');
1746    if (p) {
1747      p++;
1748      strcpy(p, "Ctrl+Alt+F5");
1749      WinSetMenuItemText(hwndSysMenu, SC_RESTORE, s);
1750    }
1751  }
1752  if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
1753                 MPFROM2SHORT(SC_CLOSE, 128), MPFROMP(s))) {
1754    p = strchr(s, '\t');
1755    if (p) {
1756      p++;
1757      strcpy(p, "Ctrl+Alt+F4");
1758      WinSetMenuItemText(hwndSysMenu, SC_CLOSE, s);
1759    }
1760  }
1761  if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
1762                 MPFROM2SHORT(SC_MOVE, 128), MPFROMP(s))) {
1763    p = strchr(s, '\t');
1764    if (p) {
1765      p++;
1766      strcpy(p, "Ctrl+Alt+F7");
1767      WinSetMenuItemText(hwndSysMenu, SC_MOVE, s);
1768    }
1769  }
1770  if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
1771                 MPFROM2SHORT(SC_SIZE, 128), MPFROMP(s))) {
1772    p = strchr(s, '\t');
1773    if (p) {
1774      p++;
1775      strcpy(p, "Ctrl+Alt+F8");
1776      WinSetMenuItemText(hwndSysMenu, SC_SIZE, s);
1777    }
1778  }
1779  if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
1780                 MPFROM2SHORT(SC_MINIMIZE, 128), MPFROMP(s))) {
1781    p = strchr(s, '\t');
1782    if (p) {
1783      p++;
1784      strcpy(p, "Ctrl+Alt+F9");
1785      WinSetMenuItemText(hwndSysMenu, SC_MINIMIZE, s);
1786    }
1787  }
1788  if (WinSendMsg(hwndSysMenu,
1789                 MM_QUERYITEMTEXT,
1790                 MPFROM2SHORT(SC_MAXIMIZE, 128), MPFROMP(s))) {
1791    p = strchr(s, '\t');
1792    if (p) {
1793      p++;
1794      strcpy(p, "Ctrl+Alt+F10");
1795      WinSetMenuItemText(hwndSysMenu, SC_MAXIMIZE, s);
1796    }
1797  }
1798  if (WinSendMsg(hwndSysMenu,
1799                 MM_QUERYITEMTEXT, MPFROM2SHORT(SC_HIDE, 128), MPFROMP(s))) {
1800    p = strchr(s, '\t');
1801    if (p) {
1802      p++;
1803      strcpy(p, "Ctrl+Alt+F11");
1804      WinSetMenuItemText(hwndSysMenu, SC_HIDE, s);
1805    }
1806  }
1807}
1808
1809VOID LoadLibPath(CHAR * str, LONG len)
1810{
1811  ULONG ver[2];
1812  CHAR configsys[] = "C:\\CONFIG.SYS";
1813  static CHAR var[8192], beg[16384], end[16384];
1814  BOOL warp;
1815  FILE *fp;
1816  PFN DQELIBPATH = NULL;
1817  HMODULE hmod;
1818
1819  if (str && len) {
1820    *str = 0;
1821    if (DosQuerySysInfo(QSV_BOOT_DRIVE,
1822                        QSV_BOOT_DRIVE, (PVOID) ver, (ULONG) sizeof(ULONG)))
1823      ver[0] = 3L;
1824    *configsys = (CHAR) ver[0] + '@';
1825    if (!DosQuerySysInfo(QSV_VERSION_MAJOR,
1826                         QSV_VERSION_MINOR,
1827                         (PVOID) ver, (ULONG) sizeof(ver)) && ver[1] >= 30)
1828      warp = TRUE;
1829    *var = *beg = *end = 0;
1830    if (warp) {
1831      if (!DosLoadModule(var, sizeof(var), "DOSCALL1.DLL", &hmod)) {
1832        if (!DosQueryProcAddr(hmod,
1833                              ORD_DOS32QUERYEXTLIBPATH,
1834                              NULL, (PFN *) & DQELIBPATH)) {
1835          DQELIBPATH(beg, BEGIN_LIBPATH);
1836          DQELIBPATH(end, END_LIBPATH);
1837        }
1838        DosFreeModule(hmod);
1839      }
1840      *var = 0;
1841    }
1842    fp = xfopen(configsys, "r", pszSrcFile, __LINE__);
1843    if (fp) {
1844      while (!feof(fp)) {
1845        if (!xfgets_bstripcr(var, sizeof(var), fp, pszSrcFile, __LINE__))
1846          break;
1847        if (!strnicmp(var, "LIBPATH=", 8)) {
1848          memmove(var, var + 8, strlen(var + 8) + 1);
1849          lstrip(var);
1850          break;
1851        }
1852      }
1853      fclose(fp);
1854    }
1855    strncpy(str, beg, len);
1856    strncat(str, var, len - strlen(str));
1857    strncat(str, end, len - strlen(str));
1858    str[len - 1] = 0;
1859  }
1860}
1861
1862void SetViewMenu(HWND hwndMenu, ULONG flWindowAttr)
1863{
1864  WinCheckMenuItem(hwndMenu, IDM_MINIICONS, ((flWindowAttr & CV_MINI)));
1865  WinCheckMenuItem(hwndMenu, IDM_TEXT, ((flWindowAttr & CV_TEXT)));
1866  WinCheckMenuItem(hwndMenu, IDM_ICON, ((flWindowAttr & CV_ICON) &&
1867                                        !(flWindowAttr & CV_TREE)));
1868  WinCheckMenuItem(hwndMenu, IDM_TREEVIEW, ((flWindowAttr & CV_TREE)));
1869  WinCheckMenuItem(hwndMenu, IDM_DETAILS, ((flWindowAttr & CV_DETAIL)));
1870  WinCheckMenuItem(hwndMenu, IDM_NAME, ((flWindowAttr & CV_NAME)));
1871}
1872
1873void SaySort(HWND hwnd, INT sortflags, BOOL archive)
1874{
1875  char *s = NULL;
1876
1877  s = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
1878  if (s) {
1879    sprintf(s, "S:%s%s",
1880            (sortflags & SORT_REVERSE) ? "^" : NullStr,
1881            (sortflags & SORT_FIRSTEXTENSION) ? GetPString(IDS_FIRSTX) :
1882            (sortflags & SORT_LASTEXTENSION) ? GetPString(IDS_LASTX) :
1883            (sortflags & SORT_SIZE) ? "Size" :
1884            (sortflags & SORT_EASIZE) ? (archive ==
1885                                         0) ? GetPString(IDS_EASIZE) :
1886            GetPString(IDS_CSIZE) : (sortflags & SORT_LWDATE) ? (archive
1887                                                                 ==
1888                                                                 0) ?
1889            GetPString(IDS_LWDATE) : GetPString(IDS_DATE) : (sortflags &
1890                                                             SORT_LADATE)
1891            ? GetPString(IDS_LADATE) : (sortflags & SORT_CRDATE) ?
1892            GetPString(IDS_CRDATE) : (sortflags & SORT_PATHNAME) ?
1893            GetPString(IDS_PATH) : (sortflags & SORT_NOSORT) ?
1894            GetPString(IDS_NONE) : (sortflags & SORT_SUBJECT) ?
1895            GetPString(IDS_SUBJ) : GetPString(IDS_NAME));
1896    WinSetWindowText(hwnd, s);
1897    free(s);
1898  }
1899}
1900
1901void SayView(HWND hwnd, ULONG flWindowAttr)
1902{
1903  char *s = NULL;
1904
1905  s = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
1906  if (s) {
1907    sprintf(s, "V:%s%s",
1908            (flWindowAttr & CV_TREE) ? GetPString(IDS_TREE) :
1909            (flWindowAttr & CV_NAME) ? GetPString(IDS_NAME) :
1910            (flWindowAttr & CV_DETAIL) ? GetPString(IDS_DETAIL) :
1911            (flWindowAttr & CV_TEXT) ? GetPString(IDS_TEXT) :
1912            GetPString(IDS_ICON),
1913            ((flWindowAttr & CV_MINI) &&
1914             !(flWindowAttr & CV_TEXT)) ? GetPString(IDS_MINI) : NullStr);
1915    WinSetWindowText(hwnd, s);
1916    free(s);
1917  }
1918}
1919
1920void SayFilter(HWND hwnd, MASK * mask, BOOL archive)
1921{
1922  char *s = NULL;
1923
1924  s = xmalloc(CCHMAXPATH * 2, pszSrcFile, __LINE__);
1925  if (s) {
1926    sprintf(s, "F:%s%s",
1927            mask->szMask,
1928            (!archive && (mask->attrFile != ALLATTRS ||
1929                          mask->antiattr != 0)) ? " " : NullStr,
1930            (!archive && (mask->attrFile != ALLATTRS ||
1931                          mask->antiattr !=
1932                          0)) ? GetPString(IDS_ATTRTEXT) : NullStr);
1933    if (!s[2])
1934      sprintf(s, "F:%s", GetPString(IDS_ALLTEXT));
1935    WinSetWindowText(hwnd, s);
1936    free(s);
1937  }
1938}
1939
1940char *GetCmdSpec(BOOL dos)
1941{
1942  char *cmspec;
1943
1944  if (!dos) {
1945    cmspec = getenv("OS2_SHELL");
1946    if (!cmspec)
1947      cmspec = getenv("COMSPEC");
1948    if (!cmspec)
1949      cmspec = "CMD.EXE";
1950  }
1951  else {
1952    cmspec = getenv("DOS_SHELL");
1953    if (!cmspec)
1954      cmspec = "COMMAND.COM";
1955  }
1956  return cmspec;
1957}
1958
1959void Broadcast(HAB hab, HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1960{
1961  if (hwndMain)
1962    WinBroadcastMsg(hwndMain, msg, mp1, mp2, BMSG_SEND | BMSG_FRAMEONLY);
1963  if (hwnd &&
1964      hwnd != HWND_DESKTOP &&
1965      hwnd != hwndMain &&
1966      hwnd != WinQueryDesktopWindow(hab, NULLHANDLE) &&
1967      WinIsWindow(hab, hwnd) && (!hwndMain || !WinIsChild(hwnd, hwndMain)))
1968    WinSendMsg(hwnd, msg, mp1, mp2);
1969}
1970
1971void SetupWinList(HWND hwndMenu, HWND hwndTop, HWND hwndFrame)
1972{
1973  /*
1974   * add switchlist entries to end of pulldown menu
1975   */
1976
1977  SHORT sItemCount, x = 0, y = 0;
1978  MENUITEM mi;
1979
1980  sItemCount = (SHORT) WinSendMsg(hwndMenu,
1981                                  MM_QUERYITEMCOUNT, MPVOID, MPVOID);
1982
1983  /* clean out old additions */
1984  while ((SHORT) WinSendMsg(hwndMenu,
1985                            MM_DELETEITEM,
1986                            MPFROM2SHORT(IDM_SWITCHSTART + x++,
1987                                         TRUE), MPVOID) < sItemCount)
1988    sItemCount--;
1989  x = 0;
1990  while ((SHORT) WinSendMsg(hwndMenu,
1991                            MM_DELETEITEM,
1992                            MPFROM2SHORT(IDM_WINDOWSTART + x++,
1993                                         TRUE), MPVOID) < sItemCount)
1994    sItemCount--;
1995
1996  x = 0;
1997  if (hwndTop) {
1998
1999    char wtext[CCHMAXPATH + 8];
2000    HENUM henum;
2001    HWND hwndChild;
2002
2003    /* add children of the main FM/2 client */
2004    henum = WinBeginEnumWindows(hwndTop);
2005    memset(&mi, 0, sizeof(mi));
2006    while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2007      if (WinQueryWindowUShort(hwndChild, QWS_ID) && hwndChild != hwndFrame) {
2008        *wtext = 0;
2009        WinQueryWindowText(hwndChild, CCHMAXPATH + 8, wtext);
2010        if (*wtext) {
2011          wtext[CCHMAXPATH + 7] = 0;
2012          mi.afStyle = MIS_TEXT;
2013          if (!((x + sItemCount) % 28))
2014            mi.afStyle |= MIS_BREAK;
2015          mi.id = IDM_WINDOWSTART + x;
2016          mi.iPosition = MIT_END;
2017          if ((SHORT) WinSendMsg(hwndMenu,
2018                                 MM_INSERTITEM,
2019                                 MPFROMP(&mi), MPFROMP(wtext)) >= 0)
2020            x++;
2021        }
2022      }
2023    }
2024    WinEndEnumWindows(henum);
2025  }
2026
2027  /* add external FM/2 windows */
2028  {
2029    PSWBLOCK pswb;
2030    ULONG ulSize, ulcEntries;
2031    HWND hwndTopFrame;
2032    register INT i;
2033
2034    hwndTopFrame = (hwndTop) ? WinQueryWindow(hwndTop, QW_PARENT) : (HWND) 0;
2035    /* Get the switch list information */
2036    x = 0;
2037    ulcEntries = WinQuerySwitchList(0, NULL, 0);
2038    ulSize = sizeof(SWBLOCK) + sizeof(HSWITCH) + (ulcEntries + 4L) *
2039      (LONG) sizeof(SWENTRY);
2040    /* Allocate memory for list */
2041    pswb = xmalloc(ulSize, pszSrcFile, __LINE__);
2042    if (pswb) {
2043      /* Put the info in the list */
2044      ulcEntries = WinQuerySwitchList(0, pswb, ulSize - sizeof(SWENTRY));
2045      /* do the dirty deed */
2046      memset(&mi, 0, sizeof(mi));
2047      for (i = 0; i < pswb->cswentry; i++) {
2048        if (pswb->aswentry[i].swctl.uchVisibility == SWL_VISIBLE &&
2049            pswb->aswentry[i].swctl.fbJump == SWL_JUMPABLE &&
2050            (pswb->aswentry[i].swctl.idProcess != mypid ||
2051             !hwndFrame ||
2052             pswb->aswentry[i].swctl.hwnd != hwndFrame) &&
2053            (pswb->aswentry[i].swctl.idProcess != mypid ||
2054             !hwndTopFrame ||
2055             pswb->aswentry[i].swctl.hwnd != hwndTopFrame ||
2056             !WinIsChild(hwndFrame, hwndTop))) {
2057          if (!strnicmp(pswb->aswentry[i].swctl.szSwtitle, "AV/2", 4)
2058              || !stricmp(pswb->aswentry[i].swctl.szSwtitle, "File Manager/2")
2059              || !stricmp(pswb->aswentry[i].swctl.szSwtitle, "Collector")
2060              || !strnicmp(pswb->aswentry[i].swctl.szSwtitle, "VTree", 5)
2061              || !strnicmp(pswb->aswentry[i].swctl.szSwtitle, "VDir", 4)
2062              || !strnicmp(pswb->aswentry[i].swctl.szSwtitle, FM2Str, 4)) {
2063            mi.afStyle = MIS_TEXT;
2064            if (x && !(x % 28))
2065              mi.afStyle |= MIS_BREAK;
2066            mi.id = IDM_SWITCHSTART + y;
2067            mi.iPosition = MIT_END;
2068            switches[y] = pswb->aswentry[i].hswitch;
2069            if ((SHORT) WinSendMsg(hwndMenu,
2070                                   MM_INSERTITEM,
2071                                   MPFROMP(&mi),
2072                                   MPFROMP(pswb->aswentry[i].
2073                                           swctl.szSwtitle)) >= 0) {
2074              y++;
2075              x++;
2076            }
2077          }
2078        }
2079      }
2080      numswitches = y;
2081      free(pswb);
2082      DosPostEventSem(CompactSem);
2083    }
2084  }
2085}
2086
2087BOOL SwitchCommand(HWND hwndMenu, USHORT cmd)
2088{
2089  BOOL ret = FALSE;
2090
2091  if (hwndMain && hwndMenu && cmd >= IDM_WINDOWSTART && cmd < IDM_SWITCHSTART) {
2092    /*
2093     * select a child window (of client)
2094     */
2095
2096    MENUITEM mi;
2097    HWND hwndSubMenu = (HWND) 0, hwndChild;
2098    CHAR s[CCHMAXPATH + 8];
2099
2100    if (WinQueryWindowUShort(hwndMenu, QWS_ID) != IDM_WINDOWSMENU) {
2101      memset(&mi, 0, sizeof(mi));
2102      mi.iPosition = MIT_END;
2103      mi.afStyle = MIS_TEXT;
2104      if (WinSendMsg(hwndMenu,
2105                     MM_QUERYITEM,
2106                     MPFROM2SHORT(IDM_WINDOWSMENU, TRUE), MPFROMP(&mi)))
2107        hwndSubMenu = mi.hwndSubMenu;
2108    }
2109    else
2110      hwndSubMenu = hwndMenu;
2111    if (hwndSubMenu) {
2112      *s = 0;
2113      if (WinSendMsg(hwndSubMenu,
2114                     MM_QUERYITEMTEXT,
2115                     MPFROM2SHORT(cmd, CCHMAXPATH + 8), MPFROMP(s)) && *s) {
2116
2117        HENUM henum;
2118        CHAR checkText[CCHMAXPATH + 8];
2119        SWP swp;
2120
2121        s[CCHMAXPATH + 7] = 0;
2122        henum = WinBeginEnumWindows(hwndMain);
2123        while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2124          if (WinQueryWindowUShort(hwndChild, QWS_ID)) {
2125            *checkText = 0;
2126            WinQueryWindowText(hwndChild, CCHMAXPATH + 8, checkText);
2127            checkText[CCHMAXPATH + 7] = 0;
2128            if (!stricmp(checkText, s)) {
2129              if (WinQueryWindowPos(hwndChild, &swp)) {
2130                if (swp.fl & (SWP_MINIMIZE | SWP_HIDE))
2131                  WinSetWindowPos(hwndChild,
2132                                  HWND_TOP,
2133                                  0, 0, 0, 0, SWP_RESTORE | SWP_ZORDER);
2134              }
2135              WinSetActiveWindow(HWND_DESKTOP, hwndChild);
2136              ret = TRUE;
2137              break;
2138            }
2139          }
2140        }
2141        WinEndEnumWindows(henum);
2142      }
2143    }
2144  }
2145  else if (cmd >= IDM_SWITCHSTART && cmd < IDM_SWITCHSTART + 499) {
2146    if (cmd - IDM_SWITCHSTART < numswitches) {
2147      WinSwitchToProgram(switches[cmd - IDM_SWITCHSTART]);
2148      ret = TRUE;
2149    }
2150  }
2151
2152  return ret;
2153}
Note: See TracBrowser for help on using the repository browser.