source: trunk/dll/misc.c @ 751

Last change on this file since 751 was 751, checked in by Steven Levine, 13 years ago

Sync rest of code with CNRITEM mods
Sync code with ARCITEM mods
Get compare dialog working
Still some issues with status display
Still some issues with directory sizes tree display
Heap check diagnostic code mostly enabled

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