source: trunk/dll/misc.c@ 1410

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

Add code to delete old style ini keys when a state is deleted.

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