source: trunk/dll/misc.c@ 1444

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

Rework of drivebar to rescan all drives and refresh media buttons and menu items grey out inappropriate menu items. Streamline Tree scan code and use semaphores to serialize access. Add NOEASUPPORT and LOCALHD driveflag; .LONGNAME usage fixes; (Tickets 377-386)

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