source: trunk/dll/misc.c@ 1112

Last change on this file since 1112 was 1112, checked in by Gregg Young, 17 years ago

Check free space on TMP & FM2 save directory drives at start up (Ticket 268)

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