source: trunk/dll/misc.c@ 1439

Last change on this file since 1439 was 1439, checked in by Gregg Young, 16 years ago

Changes to allow high mem loading of dll; Refactor .LONGNAME and .SUBJECT EA fetch to FetchCommonEAs. Add szFSType to FillInRecordFromFSA use to bypass EA scan and size formatting for tree container; Fix labels/FS type to work on scan on NOPRESCAN Drives; Fixed dbl directory names on restore of dir cnrs; (Tickets 47, 339, 363, 368, 369, 370)

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