source: trunk/dll/misc.c@ 1829

Last change on this file since 1829 was 1829, checked in by Gregg Young, 10 years ago

Fix CN_REALLOCPSZ file name editing code to: 1) Actually reallocate the buffer. 2) Point pci->pszDisplayName into the new buffer 3) Eliminate the possibility of updating the container before CN_ENDEDIT is called. 4) Only call RemoveCnrItems for tree container and collector. Ticket [557]

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