source: trunk/dll/misc.c@ 1486

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

Initial changes to commands handling. Allows you to reorder commands menu without breaking toolbars and changing hotkeys. Fixes the environment so it is used and so it is deleted if the command is deleted. Allows for user defined bitmaps in toolbars which are named based on the text or the the ID of the command.The new commands.dat will not be usable with earlier versions of FM/2

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 77.3 KB
Line 
1/***********************************************************************
2
3 $Id: misc.c 1486 2009-12-17 00:36:04Z gyoung $
4
5 Misc GUI support functions
6
7 Copyright (c) 1993-98 M. Kimes
8 Copyright (c) 2003, 2009 Steven H. Levine
9
10 11 Jun 03 SHL Add JFS and FAT32 support
11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 01 Aug 04 SHL LoadLibPath: avoid buffer overflow
13 07 Jun 05 SHL Drop obsoletes
14 24 Jul 05 SHL Beautify
15 24 Jul 05 SHL Correct longname display option
16 17 Jul 06 SHL Use Runtime_Error
17 26 Jul 06 SHL Use chop_at_crnl
18 27 Jul 06 SHL Comments, apply indent
19 29 Jul 06 SHL Use xfgets_bstripcr
20 16 Aug 06 SHL Comments
21 31 Aug 06 SHL disable_menuitem: rework args to match name - sheesh
22 10 Oct 06 GKY Add NDFS32 support
23 18 Feb 07 GKY More drive type and drive icon support
24 10 Jun 07 GKY Add IsFm2Window as part of work around PM drag limit
25 05 Jul 07 GKY Fix menu removals for WORKPLACE_PROCESS=YES
26 23 Jul 07 SHL Sync with CNRITEM updates (ticket#24)
27 31 Jul 07 SHL Clean up and report errors (ticket#24)
28 03 Aug 07 GKY Direct editting fixed (ticket#24)
29 06 Aug 07 SHL Use BldQuotedFileName
30 06 Aug 07 GKY Increase Subject EA to 1024
31 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
32 14 Aug 07 SHL Delete obsoletes
33 14 Aug 07 SHL Move #pragma alloc_text to end for OpenWatcom compat
34 01 Sep 07 GKY Use xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
35 05 Nov 07 GKY Use commafmtULL to display file sizes for large file support
36 22 Nov 07 GKY Use CopyPresParams to fix presparam inconsistencies in menus
37 12 Jan 08 SHL Document SetConditionalCascade
38 13 Jan 08 GKY Get Subjectwidth/Subjectleft working in the collector.
39 19 Jan 08 JBS Ticket 150: fix/improve save and restore of dir cnr state at FM/2 close/reopen
40 21 Jan 08 GKY Stop reallocating NullStr by direct editing of empty subject and longname strings.
41 29 Feb 08 GKY Use xfree where appropriate
42 08 Mar 08 JBS Ticket 230: Replace prefixless INI keys for default directory containers with
43 keys using a "DirCnr." prefix
44 19 Jun 08 JBS Ticket 239: Fix LoadDetailsSwitches so INI file is read correctly and details
45 switches are set correctly.
46 11 Jul 08 JBS Ticket 230: Simplified code and eliminated some local variables by incorporating
47 all the details view settings (both the global variables and those in the
48 DIRCNRDATA struct) into a new struct: DETAILS_SETTINGS.
49 17 Jul 08 SHL Add GetTidForWindow for Fortify support
50 20 Jul 08 GKY Add save/append filename to clipboard.
51 Change menu wording to make these easier to find
52 23 Aug 08 GKY Add CheckDriveSpaceAvail To pre check drive space to prevent failures
53 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
54 28 Dec 08 GKY Check for LVM.EXE and remove Refresh removable media menu item as appropriate
55 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
56 08 Mar 09 GKY Renamed commafmt.h i18nutil.h
57 08 Mar 09 GKY Additional strings move to PCSZs in init.c
58 08 Mar 09 GKY Add WriteDetailsSwitches and use LoadDetailsSwitches to replace in line code
59 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
60 28 Mar 09 GKY Add RemoveOldCnrSwitches to remove pre 3.16 style ini keys;
61 add State.version key for check
62 12 Jul 09 GKY Add xDosQueryAppType and 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
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 info = cmdhead;
1324 while (info) {
1325 WinSendMsg(mit.hwndSubMenu, MM_DELETEITEM,
1326 MPFROMSHORT((SHORT) (info->ID)), MPVOID);
1327 info = info->next;
1328 }
1329 if (hwndCnr && cmdhead) {
1330 x = 0;
1331 info = cmdhead;
1332 while (info) {
1333
1334 CHAR s[CCHMAXPATH + 24];
1335
1336 sprintf(s,
1337 "%s {%i} %s%s",
1338 info->title, info->ID,
1339 info->HotKeyID ? "\tCtrl + " : NullStr,
1340 info->HotKeyID && info->HotKeyID > 4310 ? "Shift + " : NullStr);
1341 if (info->HotKeyID)
1342 sprintf(&s[strlen(s)], "%d",
1343 (((info->HotKeyID - 4301) % 10) + 1) == 10 ? 0 :
1344 ((info->HotKeyID - 4301) % 10) + 1);
1345 mi.id = info->ID; //IDM_COMMANDSTART + x;
1346 mi.afAttribute = (info->flags & ONCE ? MIA_CHECKED : 0) |
1347 (info->flags & PROMPT ? MIA_FRAMED : 0);
1348 mi.afStyle = MIS_TEXT;
1349 if (!(x % 24) && x && info->next)
1350 mi.afStyle |= MIS_BREAK;
1351 WinSendMsg(mit.hwndSubMenu, MM_INSERTITEM, MPFROMP(&mi), MPFROMP(s));
1352 x++;
1353 info = info->next;
1354 }
1355 }
1356 }
1357}
1358
1359/**
1360 * Loads all the detail switches from the ini file
1361 * state if TRUE skips global only settings
1362 * keyroot shouldn't pass trailing dot
1363 */
1364VOID LoadDetailsSwitches(PCSZ keyroot, DETAILS_SETTINGS *pds, BOOL state)
1365{
1366 ULONG size;
1367 CHAR s[CCHMAXPATH], *eos = s;
1368
1369 strcpy(s, keyroot);
1370 strcat(s, ".");
1371 eos = &s[strlen(s)];
1372 strcpy(eos, "DetailsLongname");
1373 pds->detailslongname = dsDirCnrDefault.detailslongname;
1374 size = sizeof(BOOL);
1375 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailslongname, &size);
1376 strcpy(eos, "DetailsSubject");
1377 pds->detailssubject = dsDirCnrDefault.detailssubject;
1378 size = sizeof(BOOL);
1379 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailssubject, &size);
1380 strcpy(eos, "DetailsEA");
1381 pds->detailsea = dsDirCnrDefault.detailsea;
1382 size = sizeof(BOOL);
1383 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailsea, &size);
1384 strcpy(eos, "DetailsSize");
1385 pds->detailssize = dsDirCnrDefault.detailssize;
1386 size = sizeof(BOOL);
1387 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailssize, &size);
1388 strcpy(eos, "DetailsIcon");
1389 pds->detailsicon = dsDirCnrDefault.detailsicon;
1390 size = sizeof(BOOL);
1391 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailsicon, &size);
1392 strcpy(eos, "DetailsAttr");
1393 pds->detailsattr = dsDirCnrDefault.detailsattr;
1394 size = sizeof(BOOL);
1395 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailsattr, &size);
1396 strcpy(eos, "DetailsCRDate");
1397 pds->detailscrdate = dsDirCnrDefault.detailscrdate;
1398 size = sizeof(BOOL);
1399 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailscrdate, &size);
1400 strcpy(eos, "DetailsCRTime");
1401 pds->detailscrtime = dsDirCnrDefault.detailscrtime;
1402 size = sizeof(BOOL);
1403 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailscrtime, &size);
1404 strcpy(eos, "DetailsLWDate");
1405 pds->detailslwdate = dsDirCnrDefault.detailslwdate;
1406 size = sizeof(BOOL);
1407 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailslwdate, &size);
1408 strcpy(eos, "DetailsLWTime");
1409 pds->detailslwtime = dsDirCnrDefault.detailslwtime;
1410 size = sizeof(BOOL);
1411 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailslwtime, &size);
1412 strcpy(eos, "DetailsLADate");
1413 pds->detailsladate = dsDirCnrDefault.detailsladate;
1414 size = sizeof(BOOL);
1415 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailsladate, &size);
1416 strcpy(eos, "DetailsLATime");
1417 pds->detailslatime = dsDirCnrDefault.detailslatime;
1418 size = sizeof(BOOL);
1419 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->detailslatime, &size);
1420 if (!state) {
1421 strcpy(eos, "SubjectInLeftPane");
1422 pds->fSubjectInLeftPane = dsDirCnrDefault.fSubjectInLeftPane;
1423 size = sizeof(BOOL);
1424 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->fSubjectInLeftPane, &size);
1425 strcpy(eos, "SubjectLengthMax");
1426 pds->fSubjectLengthMax = dsDirCnrDefault.fSubjectLengthMax;
1427 size = sizeof(BOOL);
1428 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->fSubjectLengthMax, &size);
1429 if (pds->fSubjectLengthMax)
1430 pds->SubjectDisplayWidth = 0;
1431 else {
1432 strcpy(eos, "SubjectDisplayWidth");
1433 pds->SubjectDisplayWidth = dsDirCnrDefault.SubjectDisplayWidth;
1434 size = sizeof(ULONG);
1435 PrfQueryProfileData(fmprof, appname, s, (PVOID) &pds->SubjectDisplayWidth, &size);
1436 if (pds->SubjectDisplayWidth < 50)
1437 pds->SubjectDisplayWidth = 0;
1438 else if (pds->SubjectDisplayWidth > 1000)
1439 pds->SubjectDisplayWidth = 1000;
1440 }
1441 }
1442}
1443
1444/**
1445 * Writes all the detail switches to the ini file
1446 * state if TRUE skips global only settings
1447 * keyroot shouldn't pass trailing dot
1448 */
1449VOID WriteDetailsSwitches(PCSZ keyroot, DETAILS_SETTINGS *pds, BOOL state)
1450{
1451 CHAR s[CCHMAXPATH], *eos = s;
1452
1453 strcpy(s, keyroot);
1454 strcat(s, ".");
1455 eos = &s[strlen(s)];
1456 strcpy(eos, "DetailsLongname");
1457 PrfWriteProfileData(fmprof, appname, s, &pds->detailslongname, sizeof(BOOL));
1458 strcpy(eos, "DetailsSubject");
1459 PrfWriteProfileData(fmprof, appname, s, &pds->detailssubject, sizeof(BOOL));
1460 strcpy(eos, "DetailsEA");
1461 PrfWriteProfileData(fmprof, appname, s, &pds->detailsea, sizeof(BOOL));
1462 strcpy(eos, "DetailsSize");
1463 PrfWriteProfileData(fmprof, appname, s, &pds->detailssize, sizeof(BOOL));
1464 strcpy(eos, "DetailsIcon");
1465 PrfWriteProfileData(fmprof, appname, s, &pds->detailsicon, sizeof(BOOL));
1466 strcpy(eos, "DetailsAttr");
1467 PrfWriteProfileData(fmprof, appname, s, &pds->detailsattr, sizeof(BOOL));
1468 strcpy(eos, "DetailsCRDate");
1469 PrfWriteProfileData(fmprof, appname, s, &pds->detailscrdate, sizeof(BOOL));
1470 strcpy(eos, "DetailsCRTime");
1471 PrfWriteProfileData(fmprof, appname, s, &pds->detailscrtime, sizeof(BOOL));
1472 strcpy(eos, "DetailsLWDate");
1473 PrfWriteProfileData(fmprof, appname, s, &pds->detailslwdate, sizeof(BOOL));
1474 strcpy(eos, "DetailsLWTime");
1475 PrfWriteProfileData(fmprof, appname, s, &pds->detailslwtime, sizeof(BOOL));
1476 strcpy(eos, "DetailsLADate");
1477 PrfWriteProfileData(fmprof, appname, s, &pds->detailsladate, sizeof(BOOL));
1478 strcpy(eos, "DetailsLATime");
1479 PrfWriteProfileData(fmprof, appname, s, &pds->detailslatime, sizeof(BOOL));
1480 if (!state) {
1481 strcpy(eos, "SubjectInLeftPane");
1482 PrfWriteProfileData(fmprof, appname, s, &pds->fSubjectInLeftPane, sizeof(BOOL));
1483 strcpy(eos, "SubjectLengthMax");
1484 PrfWriteProfileData(fmprof, appname, s, &pds->fSubjectLengthMax, sizeof(BOOL));
1485 strcpy(eos, "SubjectDisplayWidth");
1486 PrfWriteProfileData(fmprof, appname, s, &pds->SubjectDisplayWidth, sizeof(ULONG));
1487 }
1488}
1489
1490/**
1491 * Removes the ini entries when a state is deleted
1492 * statename should be NULL for the shutdown state
1493 * (avoids removing global state settings like toolbar)
1494 * keyroot shouldn't pass the trailing dot
1495 */
1496VOID RemoveCnrSwitches(PCSZ keyroot, PCSZ statename)
1497{
1498 CHAR s[CCHMAXPATH], *eos = s;
1499
1500 strcpy(s, keyroot);
1501 strcat(s, ".");
1502 eos = &s[strlen(s)];
1503 DeletePresParams(s);
1504 strcpy(eos, "DetailsLongname");
1505 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1506 strcpy(eos, "DetailsSubject");
1507 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1508 strcpy(eos, "DetailsEA");
1509 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1510 strcpy(eos, "DetailsSize");
1511 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1512 strcpy(eos, "DetailsIcon");
1513 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1514 strcpy(eos, "DetailsAttr");
1515 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1516 strcpy(eos, "DetailsCRDate");
1517 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1518 strcpy(eos, "DetailsCRTime");
1519 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1520 strcpy(eos, "DetailsLWDate");
1521 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1522 strcpy(eos, "DetailsLWTime");
1523 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1524 strcpy(eos, "DetailsLADate");
1525 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1526 strcpy(eos, "DetailsLATime");
1527 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1528
1529#ifdef NEVER
1530 // activate this code if we ever allow setting of subject location/length per container GKY 3-28-09
1531 strcpy(eos, "SubjectInLeftPane");
1532 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1533 strcpy(eos, "SubjectLengthMax");
1534 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1535 strcpy(eos, "SubjectDisplayWidth");
1536 PrfWriteProfileData(fmprof, appname, s, NULL, 0);
1537#endif
1538
1539 strcpy(eos, "Pos");;
1540 PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
1541 strcpy(eos, "Sort");
1542 PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
1543 strcpy(eos, "Filter");
1544 PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
1545 strcpy(eos, "View");
1546 PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
1547 strcpy(eos, "Dir");
1548 PrfWriteProfileString(fmprof, FM3Str, s, NULL);
1549 if (statename && strstr(s, ".0.")) {
1550 strcpy(s, statename);
1551 strcat(s, ".");
1552 eos = &s[strlen(s)];
1553 strcpy(eos, "LastTreePos");
1554 PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
1555 strcpy(eos, "MySizeLastTime");
1556 PrfWriteProfileData(fmprof, FM3Str, s, NULL, 0);
1557 strcpy(eos, "Toolbar");
1558 PrfWriteProfileString(fmprof, FM3Str, s, NULL);
1559 strcpy(eos, "TargetDir");
1560 PrfWriteProfileString(fmprof, FM3Str, s, NULL);
1561 }
1562
1563}
1564
1565/**
1566 * Removes the pre 3.16 style ini entries when a state is deleted
1567 */
1568VOID RemoveOldCnrSwitches(PCSZ szPrefix, ULONG ulTemp)
1569{
1570 CHAR szKey[STATE_NAME_MAX_BYTES + 80];
1571
1572 sprintf(szKey, "%sDirCnrPos.%lu", szPrefix, ulTemp);
1573 PrfWriteProfileData(fmprof, FM3Str, szKey, NULL, 0);
1574 sprintf(szKey, "%sDirCnrSort.%lu", szPrefix, ulTemp);
1575 PrfWriteProfileData(fmprof, FM3Str, szKey, NULL, 0);
1576 sprintf(szKey, "%sDirCnrFilter.%lu", szPrefix, ulTemp);
1577 PrfWriteProfileData(fmprof, FM3Str, szKey, NULL, 0);
1578 sprintf(szKey, "%sDirCnrView.%lu", szPrefix, ulTemp);
1579 PrfWriteProfileData(fmprof, FM3Str, szKey, NULL, 0);
1580 sprintf(szKey, "%sDirCnrDir.%lu", szPrefix, ulTemp);
1581 PrfWriteProfileString(fmprof, FM3Str, szKey, NULL);
1582 sprintf(szKey, "%sDirCnr.%lu.", szPrefix, ulTemp);
1583}
1584
1585HWND FindDirCnr(HWND hwndParent)
1586{
1587 HWND found, hwndDir = (HWND) 0;
1588 HENUM henum;
1589
1590 henum = WinBeginEnumWindows(hwndParent);
1591 while ((found = WinGetNextWindow(henum)) != NULLHANDLE) {
1592 hwndDir = WinWindowFromID(found, FID_CLIENT);
1593 if (hwndDir) {
1594 hwndDir = WinWindowFromID(hwndDir, DIR_CNR);
1595 if (hwndDir)
1596 break;
1597 hwndDir = (HWND) 0;
1598 }
1599 }
1600 WinEndEnumWindows(henum);
1601
1602 return hwndDir;
1603}
1604
1605VOID HeapThread(VOID * dummy)
1606{
1607 ULONG postcount;
1608 APIRET rc;
1609
1610 rc = DosCreateEventSem(NULL, &CompactSem, 0L, FALSE);
1611 if (rc)
1612 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
1613 "DosCreateEventSem");
1614 else {
1615 priority_normal();
1616 for (;;) {
1617 if (DosWaitEventSem(CompactSem, SEM_INDEFINITE_WAIT))
1618 break;
1619 _heapmin();
1620 DosResetEventSem(CompactSem, &postcount);
1621 }
1622 }
1623}
1624
1625VOID FixSwitchList(HWND hwnd, PCSZ text)
1626{
1627 HSWITCH hswitch;
1628 SWCNTRL swctl;
1629
1630 hswitch = WinQuerySwitchHandle(hwnd, 0);
1631 if (hswitch) {
1632 if (!WinQuerySwitchEntry(hswitch, &swctl)) {
1633 strcpy(swctl.szSwtitle, "FM/2");
1634 WinChangeSwitchEntry(hswitch, &swctl);
1635 }
1636 }
1637}
1638
1639VOID QuickPopup(HWND hwnd, DIRCNRDATA * dcd, HWND hwndMenu, USHORT id)
1640{
1641 dcd->hwndLastMenu = hwndMenu;
1642 if (dcd->hwndLastMenu && !dcd->cnremphasized) {
1643 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1644 MPFROM2SHORT(TRUE, CRA_SOURCE));
1645 dcd->cnremphasized = TRUE;
1646 }
1647 if (dcd->flWindowAttr & CV_MINI)
1648 WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
1649 if (!WinPopupMenu(hwnd, hwnd, dcd->hwndLastMenu,
1650 8, 8, 0,
1651 PU_HCONSTRAIN | PU_VCONSTRAIN |
1652 PU_KEYBOARD | PU_MOUSEBUTTON1)) {
1653 if (dcd->cnremphasized) {
1654 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1655 MPFROM2SHORT(FALSE, CRA_SOURCE));
1656 dcd->cnremphasized = FALSE;
1657 }
1658 }
1659 else
1660 WinSendMsg(dcd->hwndLastMenu, MM_SELECTITEM,
1661 MPFROM2SHORT(id, TRUE), MPFROM2SHORT(0, FALSE));
1662}
1663
1664PMINIRECORDCORE CurrentRecord(HWND hwndCnr)
1665{
1666 SHORT attrib = fSelectedAlways ? CRA_SELECTED : CRA_CURSORED;
1667 PMINIRECORDCORE pmi;
1668
1669 for (;;) {
1670 pmi = (PMINIRECORDCORE) WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS,
1671 MPFROMLONG(CMA_FIRST),
1672 MPFROMSHORT(attrib));
1673 if ((!pmi || (INT) pmi == -1) && attrib == CRA_SELECTED) /* punt */
1674 attrib = CRA_CURSORED;
1675 else
1676 break;
1677 }
1678 return ((INT)pmi == -1) ? NULL : pmi;
1679}
1680
1681BOOL PostMsg(HWND h, ULONG msg, MPARAM mp1, MPARAM mp2)
1682{
1683 BOOL rc = WinPostMsg(h, msg, mp1, mp2);
1684
1685 if (!rc) {
1686
1687 // If window owned by some other process or some other thread?
1688 if (!IsFm2Window(h, 1)) {
1689 QMSG qmsg;
1690 for (;;) {
1691 DosSleep(1);
1692 rc = WinPostMsg(h, msg, mp1, mp2);
1693 if (rc)
1694 break; // OK
1695 if (!WinIsWindow((HAB) 0, h))
1696 break; // Window gone
1697 if (WinPeekMsg((HAB) 0, &qmsg, (HWND) 0, 0, 0, PM_NOREMOVE))
1698 break; // Queue has message(s)
1699 } // for
1700 }
1701 }
1702 return rc;
1703}
1704
1705VOID OpenEdit(HWND hwnd)
1706{
1707 CNREDITDATA ced;
1708 PCNRITEM pci;
1709 PFIELDINFO pfi;
1710
1711 pci = (PCNRITEM) WinSendMsg(hwnd,
1712 CM_QUERYRECORDEMPHASIS,
1713 MPFROMLONG(CMA_FIRST),
1714 MPFROMSHORT(CRA_CURSORED));
1715 if (pci && (INT) pci != -1) {
1716 memset(&ced, 0, sizeof(ced));
1717 ced.cb = sizeof(ced);
1718 ced.hwndCnr = hwnd;
1719 ced.id = WinQueryWindowUShort(hwnd, QWS_ID);
1720 ced.pRecord = (PRECORDCORE) pci;
1721 pfi = (PFIELDINFO) WinSendMsg(hwnd,
1722 CM_QUERYDETAILFIELDINFO,
1723 MPVOID, MPFROMSHORT(CMA_FIRST));
1724 if (!pfi)
1725 WinSendMsg(hwnd, CM_OPENEDIT, MPFROMP(&ced), MPVOID);
1726 else {
1727 while (pfi && (INT) pfi != -1 &&
1728 pfi->offStruct != FIELDOFFSET(CNRITEM, pszFileName))
1729 pfi = (PFIELDINFO) WinSendMsg(hwnd,
1730 CM_QUERYDETAILFIELDINFO,
1731 MPFROMP(pfi), MPFROMSHORT(CMA_NEXT));
1732 if (pfi && (INT) pfi != -1) {
1733 ced.pFieldInfo = pfi;
1734 {
1735 CNRINFO cnri;
1736
1737 memset(&cnri, 0, sizeof(CNRINFO));
1738 cnri.cb = sizeof(CNRINFO);
1739 WinSendMsg(hwnd,
1740 CM_QUERYCNRINFO,
1741 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1742 if (cnri.flWindowAttr & CV_DETAIL)
1743 ced.id = CID_LEFTDVWND;
1744 }
1745 WinSendMsg(hwnd, CM_OPENEDIT, MPFROMP(&ced), MPVOID);
1746 }
1747 }
1748 }
1749}
1750
1751#ifdef NEVER
1752VOID QuickView(HWND hwnd, PCSZ filename)
1753{
1754 if (filename && IsFile(filename) == 1) {
1755 if (TestBinary(filename) && *binview) {
1756
1757 CHAR *list[2];
1758
1759 list[0] = filename;
1760 list[1] = NULL;
1761 ExecOnList(hwnd, binview, WINDOWED | SEPARATE, NULL, list, NULL,
1762 pszSrcFile, __LINE__);
1763 return;
1764 }
1765 else if (*viewer) {
1766
1767 CHAR *list[2];
1768
1769 list[0] = filename;
1770 list[1] = NULL;
1771 ExecOnList(hwnd, viewer,
1772 WINDOWED | SEPARATE | (fViewChild ? CHILD : 0),
1773 NULL, list, NULL, pszSrcFile, __LINE__);
1774 return;
1775 }
1776 StartMLEEditor(HWND_DESKTOP, 5, filename, (HWND) 0);
1777 }
1778}
1779
1780VOID QuickEdit(HWND hwnd, CHAR * filename)
1781{
1782 if (filename && IsFile(filename) == 1) {
1783 if (TestBinary(filename) && *bined) {
1784
1785 CHAR *list[2];
1786
1787 list[0] = filename;
1788 list[1] = NULL;
1789 ExecOnList(hwnd, bined, WINDOWED | SEPARATE, NULL, list, NULL,
1790 pszSrcFile, __LINE__);
1791 return;
1792 }
1793 else if (*editor) {
1794
1795 CHAR *list[2];
1796
1797 list[0] = filename;
1798 list[1] = NULL;
1799 ExecOnList(hwnd, editor, WINDOWED | SEPARATE, NULL, list, NULL,
1800 pszSrcFile, __LINE__);
1801 return;
1802 }
1803 StartMLEEditor(HWND_DESKTOP, 4, filename, (HWND) 0);
1804 }
1805}
1806#endif
1807
1808VOID PortholeInit(HWND hwndNew, MPARAM mp1, MPARAM mp2)
1809{
1810 static HWND DefMenu = (HWND) 0;
1811 HWND hwndMenu = (HWND) mp2;
1812
1813 {
1814 ULONG style;
1815
1816 style = WinQueryWindowULong(hwndMenu, QWL_STYLE);
1817 if (!(style & MS_ACTIONBAR))
1818 return;
1819 }
1820
1821 switch (SHORT1FROMMP(mp1)) {
1822 case 0:
1823 {
1824 HWND hwndNow;
1825 MENUITEM mi;
1826 ULONG ulStyle;
1827
1828 memset(&mi, 0, sizeof(mi));
1829 mi.iPosition = MIT_END;
1830 mi.afStyle = MIS_TEXT;
1831 WinSendMsg(hwndMenu, MM_QUERYITEM,
1832 MPFROM2SHORT(IDM_FILESMENU, TRUE), MPFROMP(&mi));
1833 if (!DefMenu)
1834 DefMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, DEFMENU);
1835 hwndNow = mi.hwndSubMenu;
1836 mi.hwndSubMenu = hwndNew;
1837 if (!mi.hwndSubMenu)
1838 mi.hwndSubMenu = DefMenu;
1839 WinSetParent(hwndNow, WinQueryObjectWindow(HWND_DESKTOP), FALSE);
1840 WinSetOwner(hwndNow, WinQueryObjectWindow(HWND_DESKTOP));
1841 WinSetOwner(mi.hwndSubMenu, hwndMenu);
1842 WinSetParent(mi.hwndSubMenu, hwndMenu, FALSE);
1843 WinSetWindowUShort(mi.hwndSubMenu, QWS_ID, IDM_FILESMENU);
1844 mi.afStyle = MIS_SUBMENU;
1845 ulStyle = WinQueryWindowULong(mi.hwndSubMenu, QWL_STYLE);
1846 ulStyle &= -WS_SAVEBITS;
1847 ulStyle |= MS_POPUP | WS_CLIPSIBLINGS | WS_SAVEBITS;
1848 WinSetWindowULong(mi.hwndSubMenu, QWL_STYLE, ulStyle);
1849 WinSendMsg(hwndMenu, MM_SETITEM, MPFROM2SHORT(0, TRUE), MPFROMP(&mi));
1850 }
1851 break;
1852
1853 case 1:
1854 {
1855 HWND hwndNow;
1856 MENUITEM mi;
1857 ULONG ulStyle;
1858
1859 memset(&mi, 0, sizeof(mi));
1860 mi.iPosition = MIT_END;
1861 mi.afStyle = MIS_TEXT;
1862 WinSendMsg(hwndMenu, MM_QUERYITEM,
1863 MPFROM2SHORT(IDM_VIEWSMENU, TRUE), MPFROMP(&mi));
1864 if (!DefMenu)
1865 DefMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, DEFMENU);
1866 hwndNow = mi.hwndSubMenu;
1867 mi.hwndSubMenu = hwndNew;
1868 if (!mi.hwndSubMenu)
1869 mi.hwndSubMenu = DefMenu;
1870 WinSetParent(hwndNow, WinQueryObjectWindow(HWND_DESKTOP), FALSE);
1871 WinSetOwner(hwndNow, WinQueryObjectWindow(HWND_DESKTOP));
1872 WinSetOwner(mi.hwndSubMenu, hwndMenu);
1873 WinSetParent(mi.hwndSubMenu, hwndMenu, FALSE);
1874 WinSetWindowUShort(mi.hwndSubMenu, QWS_ID, IDM_VIEWSMENU);
1875 mi.afStyle = MIS_SUBMENU;
1876 ulStyle = WinQueryWindowULong(mi.hwndSubMenu, QWL_STYLE);
1877 ulStyle &= -WS_SAVEBITS;
1878 ulStyle |= MS_POPUP | WS_CLIPSIBLINGS | WS_SAVEBITS;
1879 WinSetWindowULong(mi.hwndSubMenu, QWL_STYLE, ulStyle);
1880 WinSendMsg(hwndMenu, MM_SETITEM, MPFROM2SHORT(0, TRUE), MPFROMP(&mi));
1881 }
1882 break;
1883 }
1884}
1885
1886HWND CheckMenu(HWND hwnd, HWND * hwndMenu, USHORT id)
1887{
1888 /* load and adjust menus as required */
1889 if (!*hwndMenu || !WinIsWindow((HAB) 0, *hwndMenu)) {
1890 *hwndMenu = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
1891 CopyPresParams(*hwndMenu, hwnd);
1892 if (hwndMenu == &DirMenu) {
1893 WinSetWindowUShort(DirMenu, QWS_ID, IDM_FILESMENU);
1894 SetConditionalCascade(DirMenu, IDM_COMMANDSMENU, IDM_DOITYOURSELF);
1895 SetConditionalCascade(DirMenu, IDM_COPYMENU, IDM_COPY);
1896 SetConditionalCascade(DirMenu, IDM_MOVEMENU, IDM_MOVE);
1897 SetConditionalCascade(DirMenu, IDM_SAVESUBMENU, IDM_SAVETOCLIP);
1898 SetConditionalCascade(DirMenu, IDM_VIEWSUBMENU, IDM_INFO);
1899 SetConditionalCascade(DirMenu, IDM_EDITSUBMENU, IDM_ATTRS);
1900 SetConditionalCascade(DirMenu, IDM_DELETESUBMENU,
1901 fDefaultDeletePerm ? IDM_PERMDELETE : IDM_DELETE);
1902 SetConditionalCascade(DirMenu, IDM_MISCSUBMENU, IDM_SIZES);
1903 SetConditionalCascade(DirMenu, IDM_OPENSUBMENU, IDM_OPENWINDOW);
1904 if (fWorkPlace) {
1905 WinSendMsg(DirMenu, MM_DELETEITEM,
1906 MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1907 WinSendMsg(DirMenu, MM_DELETEITEM,
1908 MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
1909 }
1910 }
1911 else if (hwndMenu == &TreeMenu) {
1912 WinSetWindowUShort(TreeMenu, QWS_ID, IDM_FILESMENU);
1913 SetConditionalCascade(TreeMenu, IDM_COMMANDSMENU, IDM_DOITYOURSELF);
1914 SetConditionalCascade(TreeMenu, IDM_SAVESUBMENU, IDM_SAVETOCLIP);
1915 SetConditionalCascade(TreeMenu, IDM_EDITSUBMENU, IDM_ATTRS);
1916 SetConditionalCascade(TreeMenu, IDM_EXPANDSUBMENU, IDM_EXPAND);
1917 SetConditionalCascade(TreeMenu, IDM_MISCSUBMENU, IDM_SIZES);
1918 SetConditionalCascade(TreeMenu, IDM_OPENSUBMENU, IDM_OPENWINDOW);
1919 if (fWorkPlace) {
1920 WinSendMsg(TreeMenu, MM_DELETEITEM,
1921 MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1922 WinSendMsg(TreeMenu, MM_DELETEITEM,
1923 MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
1924 }
1925 if (!fLVM)
1926 WinSendMsg(TreeMenu, MM_DELETEITEM,
1927 MPFROM2SHORT(IDM_REFRESHREMOVABLES, TRUE), MPVOID);
1928 }
1929 else if (hwndMenu == &ArcMenu) {
1930 WinSetWindowUShort(ArcMenu, QWS_ID, IDM_FILESMENU);
1931 SetConditionalCascade(ArcMenu, IDM_EXTRACTSUBMENU, IDM_EXTRACT);
1932 SetConditionalCascade(ArcMenu, IDM_EDITSUBMENU, IDM_EDIT);
1933 SetConditionalCascade(ArcMenu, IDM_VIEWSUBMENU, IDM_VIEW);
1934 if (fWorkPlace)
1935 WinSendMsg(ArcMenu, MM_DELETEITEM,
1936 MPFROM2SHORT(IDM_FOLDERAFTEREXTRACT, TRUE), MPVOID);
1937 }
1938 else if (hwndMenu == &FileMenu) {
1939 WinSetWindowUShort(FileMenu, QWS_ID, IDM_FILESMENU);
1940 SetConditionalCascade(FileMenu, IDM_COMMANDSMENU, IDM_DOITYOURSELF);
1941 SetConditionalCascade(FileMenu, IDM_COPYMENU, IDM_COPY);
1942 SetConditionalCascade(FileMenu, IDM_MOVEMENU, IDM_MOVE);
1943 SetConditionalCascade(FileMenu, IDM_SAVESUBMENU, IDM_SAVETOCLIP);
1944 SetConditionalCascade(FileMenu, IDM_VIEWSUBMENU, IDM_VIEW);
1945 SetConditionalCascade(FileMenu, IDM_EDITSUBMENU, IDM_EDIT);
1946 SetConditionalCascade(FileMenu, IDM_COLLECTMENU, IDM_COLLECT);
1947 SetConditionalCascade(FileMenu, IDM_DELETESUBMENU,
1948 fDefaultDeletePerm ? IDM_PERMDELETE : IDM_DELETE);
1949 SetConditionalCascade(FileMenu, IDM_OPENSUBMENU, IDM_OPENDEFAULT);
1950 SetConditionalCascade(FileMenu, IDM_OBJECTSUBMENU, IDM_SHADOW);
1951 if (fWorkPlace) {
1952 WinSendMsg(FileMenu, MM_DELETEITEM,
1953 MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1954 WinSendMsg(FileMenu, MM_DELETEITEM,
1955 MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
1956 }
1957 if (!fLVM)
1958 WinSendMsg(FileMenu, MM_DELETEITEM,
1959 MPFROM2SHORT(IDM_REFRESHREMOVABLES, TRUE), MPVOID);
1960 }
1961 else if (hwndMenu == &DirCnrMenu) {
1962 WinSetWindowUShort(DirCnrMenu, QWS_ID, IDM_VIEWSMENU);
1963 SetConditionalCascade(DirCnrMenu, IDM_MISCSUBMENU, IDM_SIZES);
1964 SetConditionalCascade(DirCnrMenu, IDM_OPENSUBMENU, IDM_OPENSETTINGSME);
1965 if (fWorkPlace)
1966 WinSendMsg(DirCnrMenu, MM_DELETEITEM,
1967 MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
1968 }
1969 else if (hwndMenu == &TreeCnrMenu) {
1970 WinSetWindowUShort(TreeCnrMenu, QWS_ID, IDM_VIEWSMENU);
1971 if (!fLVM)
1972 WinSendMsg(TreeCnrMenu, MM_DELETEITEM,
1973 MPFROM2SHORT(IDM_REFRESHREMOVABLES, TRUE), MPVOID);
1974 }
1975 else if (hwndMenu == &ArcCnrMenu) {
1976 WinSetWindowUShort(ArcCnrMenu, QWS_ID, IDM_VIEWSMENU);
1977 SetConditionalCascade(ArcCnrMenu, IDM_EXTRACTSUBMENU, IDM_ARCEXTRACT);
1978 if (fWorkPlace)
1979 WinSendMsg(ArcCnrMenu, MM_DELETEITEM,
1980 MPFROM2SHORT(IDM_FOLDERAFTEREXTRACT, TRUE), MPVOID);
1981 }
1982 else if (hwndMenu == &CollectorCnrMenu) {
1983 WinSetWindowUShort(CollectorCnrMenu, QWS_ID, IDM_VIEWSMENU);
1984 SetConditionalCascade(CollectorCnrMenu, IDM_COLLECTMENU,
1985 IDM_COLLECTFROMCLIP);
1986 }
1987 else if (hwndMenu == &CollectorFileMenu) {
1988 WinSetWindowUShort(CollectorFileMenu, QWS_ID, IDM_FILESMENU);
1989 SetConditionalCascade(CollectorFileMenu, IDM_COMMANDSMENU,
1990 IDM_DOITYOURSELF);
1991 SetConditionalCascade(CollectorFileMenu, IDM_COPYMENU, IDM_COPY);
1992 SetConditionalCascade(CollectorFileMenu, IDM_MOVEMENU, IDM_MOVE);
1993 SetConditionalCascade(CollectorFileMenu, IDM_SAVESUBMENU,
1994 IDM_SAVETOCLIP);
1995 SetConditionalCascade(CollectorFileMenu, IDM_VIEWSUBMENU, IDM_VIEW);
1996 SetConditionalCascade(CollectorFileMenu, IDM_EDITSUBMENU, IDM_EDIT);
1997 SetConditionalCascade(CollectorFileMenu, IDM_DELETESUBMENU,
1998 fDefaultDeletePerm ? IDM_PERMDELETE : IDM_DELETE);
1999 SetConditionalCascade(CollectorFileMenu, IDM_OPENSUBMENU,
2000 IDM_OPENDEFAULT);
2001 SetConditionalCascade(CollectorFileMenu, IDM_OBJECTSUBMENU, IDM_SHADOW);
2002 if (fWorkPlace) {
2003 WinSendMsg(CollectorFileMenu, MM_DELETEITEM,
2004 MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
2005 WinSendMsg(CollectorFileMenu, MM_DELETEITEM,
2006 MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
2007 }
2008 }
2009 else if (hwndMenu == &CollectorDirMenu) {
2010 WinSetWindowUShort(CollectorDirMenu, QWS_ID, IDM_FILESMENU);
2011 SetConditionalCascade(CollectorDirMenu, IDM_COMMANDSMENU,
2012 IDM_DOITYOURSELF);
2013 SetConditionalCascade(CollectorDirMenu, IDM_COPYMENU, IDM_COPY);
2014 SetConditionalCascade(CollectorDirMenu, IDM_MOVEMENU, IDM_MOVE);
2015 SetConditionalCascade(CollectorDirMenu, IDM_SAVESUBMENU,
2016 IDM_SAVETOCLIP);
2017 SetConditionalCascade(CollectorDirMenu, IDM_VIEWSUBMENU, IDM_INFO);
2018 SetConditionalCascade(CollectorDirMenu, IDM_EDITSUBMENU, IDM_ATTRS);
2019 SetConditionalCascade(CollectorDirMenu, IDM_DELETESUBMENU,
2020 fDefaultDeletePerm ? IDM_PERMDELETE : IDM_DELETE);
2021 SetConditionalCascade(CollectorDirMenu, IDM_MISCSUBMENU, IDM_SIZES);
2022 SetConditionalCascade(CollectorDirMenu, IDM_OPENSUBMENU,
2023 IDM_OPENWINDOW);
2024 if (fWorkPlace) {
2025 WinSendMsg(CollectorDirMenu, MM_DELETEITEM,
2026 MPFROM2SHORT(IDM_OPENSUBMENU, TRUE), MPVOID);
2027 WinSendMsg(CollectorDirMenu, MM_DELETEITEM,
2028 MPFROM2SHORT(IDM_OBJECTSUBMENU, TRUE), MPVOID);
2029 }
2030 }
2031 else if (hwndMenu == &MainPopupMenu) {
2032 WinSetWindowUShort(MainPopupMenu, QWS_ID, IDM_MAINPOPUP);
2033 SetConditionalCascade(MainPopupMenu, IDM_TOOLSUBMENU, IDM_TOOLBAR);
2034 SetConditionalCascade(MainPopupMenu, IDM_AUTOVIEWSUBMENU, IDM_AUTOVIEW);
2035 }
2036 }
2037 CopyPresParams(*hwndMenu, hwnd);
2038 return *hwndMenu;
2039}
2040
2041SHORT AddToListboxBottom(HWND hwnd, PCSZ str)
2042{
2043 SHORT ln;
2044
2045 ln = (SHORT) WinSendMsg(hwnd, LM_INSERTITEM, MPFROM2SHORT(LIT_END, 0),
2046 MPFROMP(str));
2047 if (ln)
2048 WinSendMsg(hwnd, LM_SELECTITEM, MPFROM2SHORT(ln, 0), MPVOID);
2049 return ln;
2050}
2051
2052VOID SetSysMenu(HWND hwndSysMenu)
2053{
2054 CHAR s[128], *p;
2055
2056 if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
2057 MPFROM2SHORT(SC_RESTORE, 128), MPFROMP(s))) {
2058 p = strchr(s, '\t');
2059 if (p) {
2060 p++;
2061 strcpy(p, "Ctrl+Alt+F5");
2062 WinSetMenuItemText(hwndSysMenu, SC_RESTORE, s);
2063 }
2064 }
2065 if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
2066 MPFROM2SHORT(SC_CLOSE, 128), MPFROMP(s))) {
2067 p = strchr(s, '\t');
2068 if (p) {
2069 p++;
2070 strcpy(p, "Ctrl+Alt+F4");
2071 WinSetMenuItemText(hwndSysMenu, SC_CLOSE, s);
2072 }
2073 }
2074 if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
2075 MPFROM2SHORT(SC_MOVE, 128), MPFROMP(s))) {
2076 p = strchr(s, '\t');
2077 if (p) {
2078 p++;
2079 strcpy(p, "Ctrl+Alt+F7");
2080 WinSetMenuItemText(hwndSysMenu, SC_MOVE, s);
2081 }
2082 }
2083 if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
2084 MPFROM2SHORT(SC_SIZE, 128), MPFROMP(s))) {
2085 p = strchr(s, '\t');
2086 if (p) {
2087 p++;
2088 strcpy(p, "Ctrl+Alt+F8");
2089 WinSetMenuItemText(hwndSysMenu, SC_SIZE, s);
2090 }
2091 }
2092 if (WinSendMsg(hwndSysMenu, MM_QUERYITEMTEXT,
2093 MPFROM2SHORT(SC_MINIMIZE, 128), MPFROMP(s))) {
2094 p = strchr(s, '\t');
2095 if (p) {
2096 p++;
2097 strcpy(p, "Ctrl+Alt+F9");
2098 WinSetMenuItemText(hwndSysMenu, SC_MINIMIZE, s);
2099 }
2100 }
2101 if (WinSendMsg(hwndSysMenu,
2102 MM_QUERYITEMTEXT,
2103 MPFROM2SHORT(SC_MAXIMIZE, 128), MPFROMP(s))) {
2104 p = strchr(s, '\t');
2105 if (p) {
2106 p++;
2107 strcpy(p, "Ctrl+Alt+F10");
2108 WinSetMenuItemText(hwndSysMenu, SC_MAXIMIZE, s);
2109 }
2110 }
2111 if (WinSendMsg(hwndSysMenu,
2112 MM_QUERYITEMTEXT, MPFROM2SHORT(SC_HIDE, 128), MPFROMP(s))) {
2113 p = strchr(s, '\t');
2114 if (p) {
2115 p++;
2116 strcpy(p, "Ctrl+Alt+F11");
2117 WinSetMenuItemText(hwndSysMenu, SC_HIDE, s);
2118 }
2119 }
2120}
2121
2122VOID LoadLibPath(PSZ str, LONG len)
2123{
2124 ULONG ver[2];
2125 CHAR configsys[] = "C:\\CONFIG.SYS";
2126 static CHAR var[8192], beg[16384], end[16384];
2127 BOOL warp;
2128 FILE *fp;
2129 PFN DQELIBPATH = NULL;
2130 HMODULE hmod;
2131
2132 if (str && len) {
2133 *str = 0;
2134 if (DosQuerySysInfo(QSV_BOOT_DRIVE,
2135 QSV_BOOT_DRIVE, (PVOID) ver, (ULONG) sizeof(ULONG)))
2136 ver[0] = 3L;
2137 *configsys = (CHAR) ver[0] + '@';
2138 if (!DosQuerySysInfo(QSV_VERSION_MAJOR,
2139 QSV_VERSION_MINOR,
2140 (PVOID) ver, (ULONG) sizeof(ver)) && ver[1] >= 30)
2141 warp = TRUE;
2142 *var = *beg = *end = 0;
2143 if (warp) {
2144 if (!DosLoadModule(var, sizeof(var), "DOSCALL1.DLL", &hmod)) {
2145 if (!DosQueryProcAddr(hmod,
2146 ORD_DOS32QUERYEXTLIBPATH,
2147 NULL, (PFN *) & DQELIBPATH)) {
2148 DQELIBPATH(beg, BEGIN_LIBPATH);
2149 DQELIBPATH(end, END_LIBPATH);
2150 }
2151 DosFreeModule(hmod);
2152 }
2153 *var = 0;
2154 }
2155 fp = xfopen(configsys, "r", pszSrcFile, __LINE__);
2156 if (fp) {
2157 while (!feof(fp)) {
2158 if (!xfgets_bstripcr(var, sizeof(var), fp, pszSrcFile, __LINE__))
2159 break;
2160 if (!strnicmp(var, "LIBPATH=", 8)) {
2161 memmove(var, var + 8, strlen(var + 8) + 1);
2162 lstrip(var);
2163 break;
2164 }
2165 }
2166 fclose(fp);
2167 }
2168 strncpy(str, beg, len);
2169 strncat(str, var, len - strlen(str));
2170 strncat(str, end, len - strlen(str));
2171 str[len - 1] = 0;
2172 }
2173}
2174
2175void SetViewMenu(HWND hwndMenu, ULONG flWindowAttr)
2176{
2177 WinCheckMenuItem(hwndMenu, IDM_MINIICONS, ((flWindowAttr & CV_MINI)));
2178 WinCheckMenuItem(hwndMenu, IDM_TEXT, ((flWindowAttr & CV_TEXT)));
2179 WinCheckMenuItem(hwndMenu, IDM_ICON, ((flWindowAttr & CV_ICON) &&
2180 !(flWindowAttr & CV_TREE)));
2181 WinCheckMenuItem(hwndMenu, IDM_TREEVIEW, ((flWindowAttr & CV_TREE)));
2182 WinCheckMenuItem(hwndMenu, IDM_DETAILS, ((flWindowAttr & CV_DETAIL)));
2183 WinCheckMenuItem(hwndMenu, IDM_NAME, ((flWindowAttr & CV_NAME)));
2184}
2185
2186void SaySort(HWND hwnd, INT sortflags, BOOL archive)
2187{
2188 char *s = NULL;
2189
2190 s = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
2191 if (s) {
2192 sprintf(s, "S:%s%s",
2193 sortflags & SORT_REVERSE ? "^" : NullStr,
2194 (sortflags & SORT_FIRSTEXTENSION) ?
2195 GetPString(IDS_FIRSTX) : (sortflags & SORT_LASTEXTENSION) ?
2196 GetPString(IDS_LASTX) : (sortflags & SORT_SIZE) ?
2197 "Size" : (sortflags & SORT_EASIZE) ?
2198 (archive == 0) ?
2199 GetPString(IDS_EASIZE) : GetPString(IDS_CSIZE) :
2200 (sortflags & SORT_LWDATE) ?
2201 (archive == 0) ?
2202 GetPString(IDS_LWDATE) : GetPString(IDS_DATE) :
2203 (sortflags & SORT_LADATE) ?
2204 GetPString(IDS_LADATE) : (sortflags & SORT_CRDATE) ?
2205 GetPString(IDS_CRDATE) :
2206 (sortflags & SORT_PATHNAME) ?
2207 GetPString(IDS_PATH) : (sortflags & SORT_NOSORT) ?
2208 GetPString(IDS_NONE) : (sortflags & SORT_SUBJECT) ?
2209 GetPString(IDS_SUBJ) : GetPString(IDS_NAME));
2210 WinSetWindowText(hwnd, s);
2211 free(s);
2212 }
2213}
2214
2215void SayView(HWND hwnd, ULONG flWindowAttr)
2216{
2217 char *s = NULL;
2218
2219 s = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
2220 if (s) {
2221 sprintf(s, "V:%s%s",
2222 (flWindowAttr & CV_TREE) ? GetPString(IDS_TREE) :
2223 (flWindowAttr & CV_NAME) ? GetPString(IDS_NAME) :
2224 (flWindowAttr & CV_DETAIL) ? GetPString(IDS_DETAIL) :
2225 (flWindowAttr & CV_TEXT) ? GetPString(IDS_TEXT) :
2226 GetPString(IDS_ICON),
2227 ((flWindowAttr & CV_MINI) &&
2228 !(flWindowAttr & CV_TEXT)) ? GetPString(IDS_MINI) : NullStr);
2229 WinSetWindowText(hwnd, s);
2230 free(s);
2231 }
2232}
2233
2234void SayFilter(HWND hwnd, MASK * mask, BOOL archive)
2235{
2236 char *s = NULL;
2237
2238 s = xmalloc(CCHMAXPATH * 2, pszSrcFile, __LINE__);
2239 if (s) {
2240 sprintf(s, "F:%s%s",
2241 mask->szMask,
2242 (!archive && (mask->attrFile != ALLATTRS ||
2243 mask->antiattr != 0)) ? " " : NullStr,
2244 (!archive && (mask->attrFile != ALLATTRS ||
2245 mask->antiattr !=
2246 0)) ? GetPString(IDS_ATTRTEXT) : NullStr);
2247 if (!s[2])
2248 sprintf(s, "F:%s", GetPString(IDS_ALLTEXT));
2249 WinSetWindowText(hwnd, s);
2250 free(s);
2251 }
2252}
2253
2254char *GetCmdSpec(BOOL dos)
2255{
2256 char *cmspec;
2257
2258 if (!dos) {
2259 cmspec = getenv("OS2_SHELL");
2260 if (!cmspec)
2261 cmspec = getenv("COMSPEC");
2262 if (!cmspec)
2263 cmspec = "CMD.EXE";
2264 }
2265 else {
2266 cmspec = getenv("DOS_SHELL");
2267 if (!cmspec)
2268 cmspec = "COMMAND.COM";
2269 }
2270 return cmspec;
2271}
2272
2273void Broadcast(HAB hab, HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
2274{
2275 if (hwndMain)
2276 WinBroadcastMsg(hwndMain, msg, mp1, mp2, BMSG_SEND | BMSG_FRAMEONLY);
2277 if (hwnd &&
2278 hwnd != HWND_DESKTOP &&
2279 hwnd != hwndMain &&
2280 hwnd != WinQueryDesktopWindow(hab, NULLHANDLE) &&
2281 WinIsWindow(hab, hwnd) && (!hwndMain || !WinIsChild(hwnd, hwndMain)))
2282 WinSendMsg(hwnd, msg, mp1, mp2);
2283}
2284
2285void SetupWinList(HWND hwndMenu, HWND hwndTop, HWND hwndFrame)
2286{
2287 /*
2288 * add switchlist entries to end of pulldown menu
2289 */
2290
2291 SHORT sItemCount, x = 0, y = 0;
2292 MENUITEM mi;
2293
2294 sItemCount = (SHORT) WinSendMsg(hwndMenu,
2295 MM_QUERYITEMCOUNT, MPVOID, MPVOID);
2296
2297 /* clean out old additions */
2298 while ((SHORT) WinSendMsg(hwndMenu,
2299 MM_DELETEITEM,
2300 MPFROM2SHORT(IDM_SWITCHSTART + x++,
2301 TRUE), MPVOID) < sItemCount)
2302 sItemCount--;
2303 x = 0;
2304 while ((SHORT) WinSendMsg(hwndMenu,
2305 MM_DELETEITEM,
2306 MPFROM2SHORT(IDM_WINDOWSTART + x++,
2307 TRUE), MPVOID) < sItemCount)
2308 sItemCount--;
2309
2310 x = 0;
2311 if (hwndTop) {
2312
2313 char wtext[CCHMAXPATH + 8];
2314 HENUM henum;
2315 HWND hwndChild;
2316
2317 /* add children of the main FM/2 client */
2318 henum = WinBeginEnumWindows(hwndTop);
2319 memset(&mi, 0, sizeof(mi));
2320 while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2321 if (WinQueryWindowUShort(hwndChild, QWS_ID) && hwndChild != hwndFrame) {
2322 *wtext = 0;
2323 WinQueryWindowText(hwndChild, CCHMAXPATH + 8, wtext);
2324 if (*wtext) {
2325 wtext[CCHMAXPATH + 7] = 0;
2326 mi.afStyle = MIS_TEXT;
2327 if (!((x + sItemCount) % 28))
2328 mi.afStyle |= MIS_BREAK;
2329 mi.id = IDM_WINDOWSTART + x;
2330 mi.iPosition = MIT_END;
2331 if ((SHORT) WinSendMsg(hwndMenu,
2332 MM_INSERTITEM,
2333 MPFROMP(&mi), MPFROMP(wtext)) >= 0)
2334 x++;
2335 }
2336 }
2337 }
2338 WinEndEnumWindows(henum);
2339 }
2340
2341 /* add external FM/2 windows */
2342 {
2343 PSWBLOCK pswb;
2344 ULONG ulSize, ulcEntries;
2345 HWND hwndTopFrame;
2346 register INT i;
2347
2348 hwndTopFrame = hwndTop ? WinQueryWindow(hwndTop, QW_PARENT) : (HWND)0;
2349 /* Get the switch list information */
2350 x = 0;
2351 ulcEntries = WinQuerySwitchList(0, NULL, 0);
2352 ulSize = sizeof(SWBLOCK) + sizeof(HSWITCH) + (ulcEntries + 4L) *
2353 (LONG) sizeof(SWENTRY);
2354 /* Allocate memory for list */
2355 pswb = xmalloc(ulSize, pszSrcFile, __LINE__);
2356 if (pswb) {
2357 /* Put the info in the list */
2358 ulcEntries = WinQuerySwitchList(0, pswb, ulSize - sizeof(SWENTRY));
2359 /* do the dirty deed */
2360 memset(&mi, 0, sizeof(mi));
2361 for (i = 0; i < pswb->cswentry; i++) {
2362 if (pswb->aswentry[i].swctl.uchVisibility == SWL_VISIBLE &&
2363 pswb->aswentry[i].swctl.fbJump == SWL_JUMPABLE &&
2364 (pswb->aswentry[i].swctl.idProcess != mypid ||
2365 !hwndFrame ||
2366 pswb->aswentry[i].swctl.hwnd != hwndFrame) &&
2367 (pswb->aswentry[i].swctl.idProcess != mypid ||
2368 !hwndTopFrame ||
2369 pswb->aswentry[i].swctl.hwnd != hwndTopFrame ||
2370 !WinIsChild(hwndFrame, hwndTop))) {
2371 if (!strnicmp(pswb->aswentry[i].swctl.szSwtitle, "AV/2", 4)
2372 || !stricmp(pswb->aswentry[i].swctl.szSwtitle, "File Manager/2")
2373 || !stricmp(pswb->aswentry[i].swctl.szSwtitle, PCSZ_COLLECTOR)
2374 || !strnicmp(pswb->aswentry[i].swctl.szSwtitle, "VTree", 5)
2375 || !strnicmp(pswb->aswentry[i].swctl.szSwtitle, "VDir", 4)
2376 || !strnicmp(pswb->aswentry[i].swctl.szSwtitle, FM2Str, 4)) {
2377 mi.afStyle = MIS_TEXT;
2378 if (x && !(x % 28))
2379 mi.afStyle |= MIS_BREAK;
2380 mi.id = IDM_SWITCHSTART + y;
2381 mi.iPosition = MIT_END;
2382 switches[y] = pswb->aswentry[i].hswitch;
2383 if ((SHORT) WinSendMsg(hwndMenu,
2384 MM_INSERTITEM,
2385 MPFROMP(&mi),
2386 MPFROMP(pswb->aswentry[i].
2387 swctl.szSwtitle)) >= 0) {
2388 y++;
2389 x++;
2390 }
2391 }
2392 }
2393 }
2394 numswitches = y;
2395 free(pswb);
2396 DosPostEventSem(CompactSem);
2397 }
2398 }
2399}
2400
2401BOOL SwitchCommand(HWND hwndMenu, USHORT cmd)
2402{
2403 BOOL ret = FALSE;
2404
2405 if (hwndMain && hwndMenu && cmd >= IDM_WINDOWSTART && cmd < IDM_SWITCHSTART) {
2406 /*
2407 * select a child window (of client)
2408 */
2409
2410 MENUITEM mi;
2411 HWND hwndSubMenu = (HWND) 0, hwndChild;
2412 CHAR s[CCHMAXPATH + 8];
2413
2414 if (WinQueryWindowUShort(hwndMenu, QWS_ID) != IDM_WINDOWSMENU) {
2415 memset(&mi, 0, sizeof(mi));
2416 mi.iPosition = MIT_END;
2417 mi.afStyle = MIS_TEXT;
2418 if (WinSendMsg(hwndMenu,
2419 MM_QUERYITEM,
2420 MPFROM2SHORT(IDM_WINDOWSMENU, TRUE), MPFROMP(&mi)))
2421 hwndSubMenu = mi.hwndSubMenu;
2422 }
2423 else
2424 hwndSubMenu = hwndMenu;
2425 if (hwndSubMenu) {
2426 *s = 0;
2427 if (WinSendMsg(hwndSubMenu,
2428 MM_QUERYITEMTEXT,
2429 MPFROM2SHORT(cmd, CCHMAXPATH + 8), MPFROMP(s)) && *s) {
2430
2431 HENUM henum;
2432 CHAR checkText[CCHMAXPATH + 8];
2433 SWP swp;
2434
2435 s[CCHMAXPATH + 7] = 0;
2436 henum = WinBeginEnumWindows(hwndMain);
2437 while ((hwndChild = WinGetNextWindow(henum)) != NULLHANDLE) {
2438 if (WinQueryWindowUShort(hwndChild, QWS_ID)) {
2439 *checkText = 0;
2440 WinQueryWindowText(hwndChild, CCHMAXPATH + 8, checkText);
2441 checkText[CCHMAXPATH + 7] = 0;
2442 if (!stricmp(checkText, s)) {
2443 if (WinQueryWindowPos(hwndChild, &swp)) {
2444 if (swp.fl & (SWP_MINIMIZE | SWP_HIDE))
2445 WinSetWindowPos(hwndChild,
2446 HWND_TOP,
2447 0, 0, 0, 0, SWP_RESTORE | SWP_ZORDER);
2448 }
2449 WinSetActiveWindow(HWND_DESKTOP, hwndChild);
2450 ret = TRUE;
2451 break;
2452 }
2453 }
2454 }
2455 WinEndEnumWindows(henum);
2456 }
2457 }
2458 }
2459 else if (cmd >= IDM_SWITCHSTART && cmd < IDM_SWITCHSTART + 499) {
2460 if (cmd - IDM_SWITCHSTART < numswitches) {
2461 WinSwitchToProgram(switches[cmd - IDM_SWITCHSTART]);
2462 ret = TRUE;
2463 }
2464 }
2465
2466 return ret;
2467}
2468
2469/** CheckDriveSpaceAvail
2470 * Take space needed and checks that drive has at least 1000 bits in excess of the required space.
2471 * Returns 0 if sufficient space is available; 1 if the drive is full & 2 on abort of operation
2472 * when the drive would have less than ullFreeSpaceWhenComplete remaining or has insufficient space.
2473 */
2474
2475INT CheckDriveSpaceAvail(PCSZ pTargetPath, ULONGLONG ullSpaceNeeded,
2476 ULONGLONG ullFreeSpaceWhenComplete)
2477{
2478 FSALLOCATE fsa;
2479 ULONGLONG ullFreeQty;
2480 APIRET ret;
2481
2482 DosQueryFSInfo(toupper(*pTargetPath) - 'A' + 1, FSIL_ALLOC, &fsa, sizeof(FSALLOCATE));
2483 ullFreeQty = (ULONGLONG) fsa.cUnitAvail * (fsa.cSectorUnit * fsa.cbSector);
2484 if (ullFreeQty > ullSpaceNeeded + ullFreeSpaceWhenComplete)
2485 return 0;
2486 else if (ullFreeQty < ullSpaceNeeded + 1024) {
2487 CHAR szKB[20];
2488
2489 CommaFmtULL(szKB, sizeof(szKB),
2490 ullFreeQty - ullSpaceNeeded, ' ');
2491 if (ullFreeSpaceWhenComplete == 0) {
2492 saymsg(MB_OK,
2493 HWND_DESKTOP,
2494 NullStr,
2495 GetPString(IDS_DRIVESPACELIMITEDTMPSAVE),
2496 pTargetPath);
2497 return 0;
2498 }
2499 else {
2500 if (ullFreeQty > ullSpaceNeeded) {
2501 ret = saymsg(MB_YESNO,
2502 HWND_DESKTOP,
2503 NullStr,
2504 GetPString(IDS_DRIVESPACELIMITED),
2505 pTargetPath,
2506 szKB);
2507 if (ret == MBID_YES)
2508 return 0;
2509 else
2510 return 2;
2511 }
2512 else {
2513 saymsg(MB_OK,
2514 HWND_DESKTOP,
2515 NullStr,
2516 GetPString(IDS_DRIVESPACEEXCEEDED),
2517 pTargetPath);
2518 return 2;
2519 }
2520 }
2521 }
2522 else
2523 return 1;
2524}
2525
2526#pragma alloc_text(MAINWND5,SetSysMenu)
2527#pragma alloc_text(MISC1,BoxWindow,PaintRecessedWindow,PostMsg,PaintSTextWindow,IsFm2Window)
2528#pragma alloc_text(MISC1,FixSwitchList,FindDirCnr,CurrentRecord,SetShiftState,AddToListboxBottom)
2529#pragma alloc_text(MISC1,CheckDriveSpaceAvail)
2530
2531#ifdef FORTIFY
2532#pragma alloc_text(MISC1,GetTidForWindow)
2533#endif // FORTIFY
2534
2535#pragma alloc_text(CNR_MISC1,AdjustCnrColVis,AdjustCnrColsForFSType)
2536#pragma alloc_text(CNR_MISC1,AdjustCnrColsForPref,SetCnrCols)
2537#pragma alloc_text(CNR_MISC2,CnrDirectEdit,OpenEdit)
2538#pragma alloc_text(MISC2,SetMenuCheck,disable_menuitem,SetSortChecks)
2539#pragma alloc_text(MISC2,SetDetailsSwitches,SetViewMenu)
2540#pragma alloc_text(MISC3,SetupCommandMenu,AdjustDetailsSwitches)
2541#pragma alloc_text(MISC3,ViewHelp,GetCmdSpec)
2542#pragma alloc_text(MISC3,ExecFile,SetConditionalCascade,LoadDetailsSwitches,WriteDetailsSwitches)
2543#pragma alloc_text(MISC4,PortholeInit,CheckMenu,Broadcast,SetupWinList,SwitchCommand)
2544#pragma alloc_text(MISC6,DrawTargetEmphasis,EmphasizeButton)
2545#pragma alloc_text(MISC_LIBPATH,LoadLibPath)
2546#pragma alloc_text(MISC_SAY,SayView,SaySort,SayFilter)
2547
Note: See TracBrowser for help on using the repository browser.