source: trunk/dll/misc.c@ 1409

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

Rename some container ini keys consolidate inline code in WriteDetailsSwitches, LoadDetailsSwitches and RemoveCnrSwitches (Ticket 343, 345, 347) Save changes to detail switches for compare directories (Ticket 346). Move additional messages to PCSZs (Ticket 6). Comments and minor code clean up.

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