source: trunk/dll/treecnr.c@ 1882

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

ExpandAll on a CDROM drive caused directory not found errors. Changed waits so they are longer on removable drives errors are gone performance on hard drives is unchanged.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 97.7 KB
Line 
1
2/***********************************************************************
3
4 $Id: treecnr.c 1882 2015-10-12 19:59:34Z gyoung $
5
6 Tree containers
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2015 Steven H. Levine
10
11 16 Oct 02 SHL Handle large partitions
12 11 Jun 03 SHL Add JFS and FAT32 support
13 25 May 05 SHL Rename comnam to szCommonName and fix typo
14 25 May 05 SHL Use ULONGLONG and CommaFmtULL
15 26 May 05 SHL More large file formatting updates
16 05 Jun 05 SHL Use QWL_USER
17 06 Aug 05 SHL Renames
18 08 Dec 05 SHL TreeCnrWndProc: disable menu items if drive not ready
19 17 Jul 06 SHL Use Runtime_Error
20 15 Aug 06 SHL Rework SetMask args
21 31 Aug 06 JS Add more partitioning menu items
22 22 Oct 06 GKY Add NDFS32 support
23 29 Dec 06 GKY Fixed menu gray out for remote drives (added variable "remote")
24 29 Dec 06 GKY Enabled edit of drive flags on "not ready" drives
25 18 Feb 07 GKY More drive type and icon support
26 08 Mar 07 SHL Ensure drive icon updates after drive flags change
27 09 Mar 07 GKY Use SelectDriveIcon
28 30 Mar 07 GKY Remove GetPString for window class names
29 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
30 06 Apr 07 GKY Add some error checking in drag/drop
31 19 Apr 07 SHL Sync with AcceptOneDrop GetOneDrop mods
32 19 Apr 07 SHL Add more drag/drop error checking
33 12 May 07 SHL Use dcd->ulItemsToUnHilite; sync with UnHilite arg mods
34 10 Jun 07 GKY Add CheckPmDrgLimit including IsFm2Window as part of work around PM drag limit
35 10 Jun 07 GKY Mouse button 3 white space click to fail silently
36 05 Jul 07 SHL Disable leftover debug code
37 02 Aug 07 SHL Sync with CNRITEM mods
38 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
39 14 Aug 07 SHL Revert ShowTreeRec DosSleep to 0
40 14 Aug 07 SHL Optimze ShowTreeRec collapse - was really slow
41 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
42 22 Aug 07 SHL Disable DbgMsgs shipped with 3.0.8beta1
43 26 Aug 07 SHL Revert to DosSleep(0)
44 22 Nov 07 GKY Use CopyPresParams to fix presparam inconsistencies in menus
45 10 Jan 08 SHL Sync with CfgDlgProc mods
46 15 Feb 08 SHL Sync with settings menu rework
47 15 Feb 08 SHL Avoid death if tree container 0 width
48 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory
49 02 Aug 08 GKY Always pass temp variable point to UM_SHOWME to avoid freeing pci->pszFileName early
50 19 Oct 08 GKY Fixed logic for greying menu items (Format etc) on remote and virtual drives (it was reversed)
51 19 Oct 08 GKY Fixed context menu to be "drives" menu on unformatted drives
52 28 Nov 08 GKY Remove unneeded DosEnterCriSec calls
53 10 Dec 08 SHL Integrate exception handler support
54 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
55 26 Dec 08 GKY Implemented DROPHELP for the tree container
56 27 Dec 08 GKY Add refresh removable media to tree container menus
57 28 Dec 08 GKY Rework partition submenu to gray out unavailable items (check for existence of files)
58 and have no default choice.
59 01 Jan 09 GKY Add Seek and Scan to drives & directory context menus pass drive/dir as search root
60 11 Jan 09 GKY Replace font names in the string file with global set at compile in init.c
61 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
62 07 Feb 09 GKY Add *DateFormat functions to format dates based on locale
63 07 Feb 09 GKY Eliminate Win_Error2 by moving function names to PCSZs used in Win_Error
64 08 Mar 09 GKY Renamed commafmt.h i18nutil.h
65 08 Mar 09 GKY Additional strings move to PCSZs in init.c
66 12 Mar 09 SHL Use common SearchContainer
67 14 Mar 09 GKY Prevent execution of UM_SHOWME while drive scan is occuring
68 06 Jun 09 GKY Add option to show file system type or drive label in tree
69 06 Jun 09 GKY Status line to show file sys/label not shown in tree; shortened to fit split status
70 07 Jun 09 GKY Fixed double names in tree container when collapsed tree is accessed
71 before recursive scan
72 12 Jul 09 GKY Add option to show file system type or drive label in tree
73 (get NOPRESCAN drives working)
74 22 Jul 09 GKY Code changes to use semaphores to serialize drive scanning
75 22 Jul 09 GKY Consolidated driveflag setting code in DriveFlagsOne
76 22 Jul 09 GKY Streamline scanning code for faster Tree rescans
77 14 Sep 09 SHL Drop experimental code
78 15 Sep 09 SHL Use UM_GREP when passing pathname
79 15 Nov 09 GKY Add semaphore to fix double names in tree container caused by UM_SHOWME
80 before scan completes
81 22 Nov 09 GKY Add LVM.EXE to partition submenu
82 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast
83 CHAR CONSTANT * as CHAR *.
84 11 Apr 10 GKY Fix drive tree rescan failure and program hang caused by event sem
85 never being posted
86 20 Nov 10 GKY Rework scanning code to remove redundant scans, prevent double directory
87 entries in the tree container, fix related semaphore performance using
88 combination of event and mutex semaphores
89 04 Aug 12 GKY Fix trap reported by Ben
90 30 Dec 12 GKY Changed refresh removable media to query LVM directly to call Rediscover_PRMs (Ticket 472);
91 Also added a tree rescan following volume detach.
92 22 Feb 14 GKY Fix warn readonly yes don't ask to work when recursing directories.
93 07 Sep 14 GKY Fix tree container mis-draws (stacked icons with RWS) The problem was magnified
94 by RWS but I think the occasional extra blank directory or duplicating
95 directories is related.
96 16 Mar 15 GKY Add semaphore hmtxFiltering to prevent freeing dcd while filtering. Prevents
97 a trap when FM2 is shutdown or the container is closed while tree
98 container is still populating
99 02 May 15 GKY Changes to allow a JAVA executable object to be created using "Real object"
100 menu item on a jar file.
101 12 Jul 15 GKY Fixed trap caused by pci->pszFileName being NullStr
102 07 Aug 15 SHL Rework to use AddFleshWorkRequest rather than direct calls to Stubby/Flesh/Unflesh
103 20 Aug 15 SHL Sync with SetFleshFocusPath mods
104 22 Aug 15 GKY Improve ability of maketop to get directory position in tree correct on first
105 open of states with large and/or deep tree structures
106 24 Aug 15 GKY Remove fDummy code
107 20 Sep 15 GKY Get expand and switch code to work with Flesh, UnFlesh and Stubby running on
108 a thread. Loop and idle ExpandAll; Add CollapseAll; Move tree expand to a
109 thread; Have ShowTreeRec wait for the Flesh thread.
110 26 Sep 15 GKY Adjustments to ShowTreeRec to eliminate failures and reduce retries and container
111 noise on tree switches.
112 26 Sep 15 GKY Remove fInitialDriveScan code
113 26 Sep 15 GKY Changes to speed up ExpandAll
114 26 Sep 15 GKY Put UM_TOPDIR in the object window so it can call WaitFleshWorkListEmpty
115 while avoiding thread 1
116 27 Sep 15 GKY DosSleep times in WaitFleshWorkListEmpty set by caller
117 04 Oct 15 GKY Move the eUnflesh call from UM_ENTER to the object window so WaitFleshWorkListEmpty
118 can be used (UM_ENTER is on TID 1); Prevent eUnflesh from running if no child
119 directories are present; treat floppies like invalid drives on rescan (IDM_UPDATE
120 to avoid them seen as directories and having random subdirectories attached to
121 them.
122 10 Oct 15 GKY Eliminate some unnecessary Flesh and UnFlesh calls
123 10 Oct 15 GKY Update icon and display name on CD/DVD eject in all cases.
124 10 Oct 15 GKY Don't use Flesh thread for floppy drive scans fix them getting mistakenly identified
125 as directories and add nonexistent subdirectories.
126
127***********************************************************************/
128
129#include <stdlib.h>
130#include <string.h>
131#include <ctype.h>
132
133#define INCL_DOS
134#define INCL_WIN
135#define INCL_LONGLONG
136#define INCL_DOSERRORS
137
138#include "fm3dll.h"
139#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
140#include "treecnr.h"
141#include "mainwnd2.h" // Data declaration(s)
142#include "grep.h" // Data declaration(s)
143#include "dircnrs.h" // Data declaration(s)
144#include "info.h" // Data declaration(s)
145#include "fm3dlg.h"
146#include "fm3str.h"
147#include "mle.h"
148#include "comp.h" // COMPARE
149#include "filldir.h" // RemoveCnrItems...
150#include "errutil.h" // Dos_Error...
151#include "strutil.h" // GetPString
152#include "notebook.h" // CfgDlgProc
153#include "command.h" // RunCommand
154#include "worker.h" // Action, MassAction
155#include "mainwnd.h" // BubbleHelp, FindDirCnrByName, GetNextWindowPos
156#include "misc.h" // CnrDirectEdit, EmphasizeButton, FindDirCnr
157 // FindDirCnr, FixSwitchList, OpenEdit, QuickPopup
158 // SetSortChecks, SwitchCommand, CheckMenu
159 // CurrentRecord, IsFm2Window
160#include "common.h" // CommonCnrProc, CommonDriveCmd, CommonFrameWndProc
161 // CommonTextProc
162#include "valid.h" // CheckDrive, DriveFlagsOne, IsValidDrive
163#include "chklist.h" // DropListProc
164#include "select.h" // ExpandAll
165#include "findrec.h" // FindCnrRecord, FindParentRecord, ShowCnrRecord
166#include "flesh.h" // AddFleshWorkRequest
167#include "notify.h" // HideNote
168#include "objwin.h" // MakeObjWin
169#include "notify.h" // NotifyError
170#include "remap.h" // RemapDlgProc
171#include "saveclip.h" // SaveListDlgProc
172#include "update.h" // SelectDriveIcon, UpdateCnrList, UpdateCnrRecord
173#include "sortcnr.h" // SortTreeCnr
174#include "droplist.h" // AcceptOneDrop, CheckPmDrgLimit, DropHelp, GetOneDrop
175#include "presparm.h" // CopyPresParams
176#include "defview.h" // DefaultViewKeys
177#include "draglist.h" // DoFileDrag
178#include "filter.h" // Filter
179#include "shadow.h" // OpenObject
180#include "mkdir.h" // PMMkDir
181#include "collect.h" // StartCollector
182#include "viewer.h" // StartMLEEditor
183#include "newview.h" // StartViewer
184#include "walkem.h" // WalkAllDlgProc
185#include "i18nutil.h" // CommaFmtULL
186#include "wrappers.h" // xDosFindFirst
187#include "systemf.h" // runemf2
188#include "dirs.h" // save_dir2
189#include "fortify.h"
190#include "init.h" // NullStr etc.
191#include "excputil.h" // xbeginthread
192#include "copyf.h" // ignorereadonly
193
194// Data definitions
195
196#pragma data_seg(GLOBAL1)
197HWND LastDir;
198HWND TreeCnrMenu;
199INT driveserial[26];
200BOOL fDCOpens;
201BOOL fFollowTree;
202BOOL fTopDir;
203BOOL fLVMGui;
204BOOL fDFSee;
205BOOL fFDisk;
206BOOL fMiniLVM;
207BOOL fLVM;
208BOOL fExpandAll;
209HPOINTER hptrDunno;
210HWND hwndMainMenu;
211
212#pragma data_seg(GLOBAL2)
213ULONG FM3UL;
214INT TreesortFlags;
215
216#pragma data_seg(DATA1)
217
218static PSZ pszSrcFile = __FILE__;
219static BOOL fOkayMinimize;
220static HMQ hmqExpandTree;
221
222APIRET16 APIENTRY16 Dos16MemAvail(PULONG pulAvailMem);
223
224typedef struct APPNOTIFY
225{
226 HAPP happ;
227 CHAR device;
228 struct APPNOTIFY *next;
229 struct APPNOTIFY *prev;
230}
231APPNOTIFY;
232
233MRESULT EXPENTRY OpenButtonProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
234{
235 static BOOL emphasized = FALSE;
236
237 switch (msg) {
238 case WM_CREATE:
239 {
240 MRESULT rc;
241
242 rc = PFNWPButton(hwnd, msg, mp1, mp2);
243 //fixme to allow user to change presparams 1-10-09 GKY
244 WinSetPresParam(hwnd, PP_FONTNAMESIZE,
245 strlen(FNT_8TIMESNEWROMAN) + 1,
246 (PVOID) FNT_8TIMESNEWROMAN);
247 return rc;
248 }
249
250 case WM_MOUSEMOVE:
251 BubbleHelp(hwnd, TRUE, FALSE, TRUE, GetPString(IDS_OPENBUTTONHELP));
252 break;
253
254 case WM_CONTEXTMENU:
255 PostMsg(WinQueryWindow(hwnd, QW_PARENT),
256 WM_COMMAND, MPFROM2SHORT(IDM_OPENWALK, 0), MPVOID);
257 return 0;
258
259 case DM_DRAGOVER:
260 if (!emphasized) {
261 emphasized = TRUE;
262 EmphasizeButton(hwnd, emphasized);
263 }
264 if (AcceptOneDrop(hwnd, mp1, mp2))
265 return MRFROM2SHORT(DOR_DROP, DO_MOVE);
266 return MRFROM2SHORT(DOR_NEVERDROP, 0);
267
268 case DM_DRAGLEAVE:
269 if (emphasized) {
270 emphasized = FALSE;
271 EmphasizeButton(hwnd, emphasized);
272 }
273 break;
274
275 case DM_DROPHELP:
276 DropHelp(mp1, mp2, hwnd, GetPString(IDS_OPENDROPHELP));
277 return 0;
278
279 case DM_DROP:
280 {
281 char szFrom[CCHMAXPATH + 2];
282
283 if (emphasized) {
284 emphasized = FALSE;
285 EmphasizeButton(hwnd, emphasized);
286 }
287 if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom))) {
288 MakeValidDir(szFrom);
289 WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
290 UM_OPENWINDOWFORME, MPFROMP(szFrom), MPVOID);
291 }
292 }
293 return 0;
294
295 }
296 return PFNWPButton(hwnd, msg, mp1, mp2);
297}
298
299/**
300 * Find a record in tree view, move it so it shows in container and
301 * make it the current record
302 * @param hwndCnr is container which must be in tree view
303 * @param pszDir_ is full path name to find
304 */
305
306VOID ShowTreeRec(HWND hwndCnr,
307 PCSZ pszDir_,
308 BOOL collapsefirst,
309 BOOL maketop)
310{
311 PCNRITEM pci;
312 PCNRITEM pciToSelect;
313 PCNRITEM pciP;
314 UINT retries;
315 BOOL quickbail = FALSE;
316 PSZ p;
317 BOOL found;
318 CHAR szDir[CCHMAXPATH];
319 CHAR szDirArg[CCHMAXPATH]; // Copy of passed value
320 CHAR chSaved;
321
322 strcpy(szDirArg, pszDir_); // Cache here in case arg content changed by some other thread
323
324 // already positioned to requested record?
325 pci = WinSendMsg(hwndCnr,
326 CM_QUERYRECORDEMPHASIS,
327 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
328 if (pci && (INT)pci != -1 && !stricmp(pci->pszFileName, szDirArg)) {
329 quickbail = TRUE; // Already at requested record - bypass repositioning
330 goto MakeTop;
331 }
332 // 2015-08-13 SHL add retry logic 2015-08-22 GKY increase retries from 10 to 100 to
333 // eliminate switch failures on deep or large tree state switches
334 for (found = FALSE, retries = 0; !found && retries < 100; retries++) {
335
336 pci = FindCnrRecord(hwndCnr,
337 szDirArg,
338 NULL, // pciParent
339 TRUE, // partial
340 FALSE, // partmatch
341 TRUE); // noenv
342
343 if (pci && (INT)pci != -1) {
344 found = TRUE;
345 break; // Found it
346 }
347
348 // Walk down directory tree, expanding as needed
349 strcpy(szDir, szDirArg);
350 p = szDir + 3; // Point after root backslash
351 chSaved = *p; // Remember for restore
352 *p = 0; // Chop after backslash
353
354 for (;;) {
355 // Try to match path prefix
356 pciP = FindCnrRecord(hwndCnr,
357 szDir,
358 NULL, // pciParent
359 TRUE, // partial
360 FALSE, // partmatch
361 TRUE); // noenv
362 if (!pciP || (INT)pciP == -1) {
363 WaitFleshWorkListEmpty(szDirArg, 240); // 2015-08-23 SHL
364 break; // No match
365 }
366 if (!stricmp(szDirArg, pciP->pszFileName)) {
367 pci = pciP;
368 found = TRUE;
369 break; // Got full match
370 }
371
372 // Got partial match
373
374 if (~pciP->rc.flRecordAttr & CRA_EXPANDED) {
375 WinSendMsg(hwndCnr, CM_EXPANDTREE, MPFROMP(pciP), MPVOID);
376 }
377
378 // Add next component to path unless no more components
379 if (p) {
380 *p = chSaved; // Restore
381 if (chSaved) {
382 if (chSaved == '\\')
383 p++; // Get past last backslash
384 p = strchr(p, '\\'); // Find next backslash
385 if (p) {
386 chSaved = *p;
387 *p = 0; // Truncate at backslash
388 }
389 }
390 }
391 WaitFleshWorkListEmpty(NULL, 240); // 2015-09-26 GKY Let Flesh thread catch up
392 } // while expanding
393
394 } // for
395 if (found) {
396 // Found it
397 if (~pci->rc.flRecordAttr & CRA_CURSORED) {
398 if (collapsefirst) {
399 WaitFleshWorkListEmpty(NULL, 240);
400 pciP = WinSendMsg(hwndCnr,
401 CM_QUERYRECORD,
402 MPVOID, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
403 while (pciP && (INT) pciP != -1) {
404 if (pciP->rc.flRecordAttr & CRA_EXPANDED) {
405 // collapse top level of all branches
406 WinSendMsg(hwndCnr, CM_COLLAPSETREE, MPFROMP(pciP), MPVOID);
407 }
408 pciP = WinSendMsg(hwndCnr,
409 CM_QUERYRECORD,
410 MPFROMP(pciP),
411 MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
412 } // while
413 } // if collapse
414
415 // Expand parent branches
416 // 2015-08-06 SHL FIXME to bypass if we did not collapse since search already expanded - maybe?
417 pciToSelect = pci;
418 for (;;) {
419 pciP = WinSendMsg(hwndCnr,
420 CM_QUERYRECORD,
421 MPFROMP(pciToSelect),
422 MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER));
423 if (!pciP || (INT)pciP == -1)
424 break; // Done
425 // Got parent
426 if (~pciP->rc.flRecordAttr & CRA_EXPANDED)
427 WinSendMsg(hwndCnr, CM_EXPANDTREE, MPFROMP(pciP), MPVOID);
428 pciToSelect = pciP;
429 DosSleep(0); // Let GUI update
430 } // for
431 } // if not cursored
432
433 MakeTop:
434 // make record visible
435 pciToSelect = pci;
436 if (pciToSelect && (INT) pciToSelect != -1) {
437 if (fSwitchTreeExpand && ~pciToSelect->rc.flRecordAttr & CRA_EXPANDED) {
438 WinSendMsg(hwndCnr, CM_EXPANDTREE, MPFROMP(pciToSelect), MPVOID);
439 }
440 if (maketop || fTopDir) {
441 if (fCollapseFirst && !quickbail) {
442 WaitFleshWorkListEmpty(NULL, 240); //Let the root expand first otherwise it makes top
443 }
444 ShowCnrRecord(hwndCnr, (PMINIRECORDCORE)pciToSelect);
445 }
446
447 if (!quickbail) {
448 WaitFleshWorkListEmpty(szDirArg, 240); // 2015-08-19 SHL try to ensure contents stable
449 WinSendMsg(hwndCnr,
450 CM_SETRECORDEMPHASIS,
451 MPFROMP(pciToSelect),
452 MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED));
453 }
454 }
455 }
456}
457
458MRESULT EXPENTRY TreeTitleWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
459 MPARAM mp2)
460{
461 PFNWP oldproc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
462
463 switch (msg) {
464 case WM_CONTEXTMENU:
465 return WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
466 UM_CONTEXTMENU, mp1, mp2);
467 }
468 return oldproc(hwnd, msg, mp1, mp2);
469}
470
471MRESULT EXPENTRY TreeStatProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
472{
473 switch (msg) {
474 case WM_CREATE:
475 return CommonTextProc(hwnd, msg, mp1, mp2);
476
477 case WM_CONTEXTMENU:
478 PostMsg(WinQueryWindow(hwnd, QW_PARENT), msg, mp1, mp2);
479 return 0;
480
481 case WM_PAINT:
482 {
483 MRESULT mr = PFNWPStatic(hwnd, msg, mp1, mp2);
484
485 PaintRecessedWindow(hwnd, (HPS) 0, FALSE, FALSE);
486 return mr;
487 }
488
489 case WM_SETFOCUS:
490 if (mp2)
491 PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
492 break;
493
494 case UM_FOCUSME:
495 WinSetFocus(HWND_DESKTOP, WinQueryWindow(hwnd, QW_PARENT));
496 return 0;
497 }
498 return PFNWPStatic(hwnd, msg, mp1, mp2);
499}
500
501MRESULT EXPENTRY TreeFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
502 MPARAM mp2)
503{
504 switch (msg) {
505 case UM_RESCAN:
506 PostMsg(WinQueryWindow(hwnd, QW_PARENT), msg, mp1, mp2);
507 return 0;
508
509 case WM_ADJUSTWINDOWPOS:
510 {
511 SWP *pswp;
512
513 pswp = (SWP *) mp1;
514 if (ParentIsDesktop(hwnd, (HWND) 0)) {
515 if (pswp->fl & (SWP_HIDE | SWP_MINIMIZE))
516 HideNote();
517 }
518 }
519 break;
520
521 case WM_TRACKFRAME:
522 if (!fFreeTree && !ParentIsDesktop(hwnd, (HWND) 0)) {
523 switch (SHORT1FROMMP(mp1) & TF_MOVE) {
524 case TF_MOVE:
525 case TF_LEFT:
526 case TF_TOP:
527 case (TF_LEFT | TF_BOTTOM):
528 case (TF_LEFT | TF_TOP):
529 {
530 SWP swp;
531
532 WinQueryWindowPos(hwnd, &swp);
533 if (!(swp.fl & SWP_ACTIVATE))
534 WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
535 SWP_ZORDER | SWP_ACTIVATE);
536 }
537 return 0;
538 }
539 }
540 break;
541
542 case WM_CALCFRAMERECT:
543 if (*(ULONG *) realappname != FM3UL) {
544
545 MRESULT mr;
546 PRECTL prectl;
547
548 mr = CommonFrameWndProc(TREE_CNR, hwnd, msg, mp1, mp2);
549
550 /**
551 * Calculate the position of the client rectangle.
552 * Otherwise, we'll see a lot of redraw when we move the
553 * client during WM_FORMATFRAME.
554 */
555
556 if (mr && mp2) {
557 prectl = (PRECTL) mp1;
558 prectl->yTop -= 22;
559 }
560 return mr;
561 }
562 break;
563
564 case WM_FORMATFRAME:
565 {
566 SHORT sCount;
567 PSWP pswp, pswpClient, pswpNew;
568
569 sCount = (SHORT) CommonFrameWndProc(TREE_CNR, hwnd, msg, mp1, mp2);
570
571 // Reformat the frame to "squeeze" the client
572
573 pswp = (PSWP) mp1;
574 {
575 SHORT x;
576
577 for (x = 0; x < sCount; x++) {
578 if (WinQueryWindowUShort(pswp->hwnd, QWS_ID) == FID_CLIENT) {
579 pswpClient = pswp;
580 break;
581 }
582 pswp++;
583 }
584 }
585 pswpNew = (PSWP) mp1 + sCount;
586 *pswpNew = *pswpClient;
587 pswpNew->hwnd = WinWindowFromID(hwnd, MAIN_STATUS);
588 if (*(ULONG *) realappname == FM3UL) {
589
590 PSWP pswpTitlebar = (PSWP) 0, pswpMinbutton = (PSWP) 0;
591 SHORT x;
592
593 pswpNew->hwnd = WinWindowFromID(hwnd, IDM_OPENWINDOW);
594 pswp = (PSWP) mp1;
595 for (x = 0; x < sCount; x++) {
596 if (WinQueryWindowUShort(pswp->hwnd, QWS_ID) == FID_TITLEBAR)
597 pswpTitlebar = pswp;
598 else if (WinQueryWindowUShort(pswp->hwnd, QWS_ID) == FID_MINMAX)
599 pswpMinbutton = pswp;
600 if (pswpTitlebar && pswpMinbutton)
601 break;
602 pswp++;
603 }
604 pswpNew->cy = pswpMinbutton->cy + 3;
605 pswpNew->cx = min(pswpNew->cy, (pswpMinbutton->cx / 2) + 3);
606 pswpTitlebar->cx -= (pswpNew->cx + 1);
607 pswpNew->x = pswpTitlebar->x + pswpTitlebar->cx;
608 pswpNew->y = pswpMinbutton->y - 1;
609 }
610 else {
611 pswpNew->x = pswpClient->x + 3;
612 pswpNew->y = (pswpClient->y + pswpClient->cy) - 20;
613 pswpNew->cx = pswpClient->cx - 6;
614 pswpNew->cy = 18;
615 pswpClient->cy -= 22;
616 }
617 sCount++;
618 return MRFROMSHORT(sCount);
619 }
620
621 case WM_QUERYFRAMECTLCOUNT:
622 {
623 SHORT sCount;
624
625 sCount = (SHORT) CommonFrameWndProc(TREE_CNR, hwnd, msg, mp1, mp2);
626 sCount++;
627 return MRFROMSHORT(sCount);
628 }
629 }
630 return CommonFrameWndProc(TREE_CNR, hwnd, msg, mp1, mp2);
631}
632
633MRESULT EXPENTRY TreeClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
634 MPARAM mp2)
635{
636 switch (msg) {
637 case UM_CONTAINERHWND:
638 return MRFROMLONG(WinWindowFromID(hwnd, TREE_CNR));
639
640 case UM_VIEWSMENU:
641 return MRFROMLONG(CheckMenu(hwndMainMenu, &TreeCnrMenu, TREECNR_POPUP));
642
643 case UM_TIMER:
644 case UM_ACTION:
645 case UM_SHOWME:
646 case UM_OPENWINDOWFORME:
647 case UM_MINIMIZE:
648 case UM_MAXIMIZE:
649 case WM_INITMENU:
650 case UM_INITMENU:
651 case UM_FILTER:
652 case UM_FILESMENU:
653 case UM_UPDATERECORD:
654 case UM_UPDATERECORDLIST:
655 case MM_PORTHOLEINIT:
656 case UM_DRIVECMD:
657 case WM_CLOSE:
658 case WM_CONTROL:
659 case UM_COMMAND:
660 case WM_COMMAND:
661 return WinSendMsg(WinWindowFromID(hwnd, TREE_CNR), msg, mp1, mp2);
662
663 case WM_PSETFOCUS:
664 case WM_SETFOCUS:
665 if (mp2)
666 PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
667 break;
668
669 case UM_FOCUSME:
670 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, TREE_CNR));
671 break;
672
673 case WM_ERASEBACKGROUND:
674 WinFillRect((HPS) mp1, (PRECTL) mp2, 0x00d0d0d0);
675 return 0;
676
677 case WM_PAINT:
678 {
679 HPS hps;
680 RECTL rcl;
681
682 hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
683 if (hps) {
684 WinQueryWindowRect(hwnd, &rcl);
685 WinFillRect(hps, &rcl, CLR_PALEGRAY);
686 PaintRecessedWindow(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
687 MAIN_STATUS), hps, FALSE, FALSE);
688 WinEndPaint(hps);
689 }
690 }
691 break;
692
693 case WM_SIZE:
694 WinSetWindowPos(WinWindowFromID(hwnd, TREE_CNR),
695 HWND_TOP,
696 0,
697 0,
698 SHORT1FROMMP(mp2),
699 SHORT2FROMMP(mp2), SWP_SHOW | SWP_MOVE | SWP_SIZE);
700 if (hwndMain)
701 PostMsg(hwndMain, UM_SIZE, MPVOID, MPVOID);
702 break;
703
704 case WM_CONTEXTMENU:
705 case UM_CONTEXTMENU:
706 PostMsg(WinWindowFromID(hwnd, TREE_CNR),
707 WM_CONTROL, MPFROM2SHORT(TREE_CNR, CN_CONTEXTMENU), MPVOID);
708 return 0;
709 }
710 return WinDefWindowProc(hwnd, msg, mp1, mp2);
711}
712
713ULONG ulScanPostCnt;
714
715MRESULT EXPENTRY TreeObjWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
716{
717 DIRCNRDATA *dcd;
718
719 switch (msg) {
720 case UM_SHOWME:
721 if (mp1) {
722# ifdef FORTIFY
723 Fortify_BecomeOwner(mp1);
724# endif
725 dcd = INSTDATA(hwnd);
726 if (dcd) {
727
728 /* Hold off if switching on focus change and
729 RestoreDirCnrState has restored one or directory directory containers
730 See RestoreDirCnrState()
731 */
732 if (cDirectoriesRestored > 0)
733 cDirectoriesRestored--;
734
735 if (!cDirectoriesRestored) {
736 BOOL tempsusp = dcd->suspendview;
737 BOOL tempfollow = fFollowTree;
738 dcd->suspendview = TRUE;
739 fFollowTree = FALSE;
740 priority_idle(); // 2015-09-26 GKY Majority of work done by Flesh and UI threads
741 ShowTreeRec(dcd->hwndCnr, (CHAR *)mp1, fCollapseFirst, TRUE);
742 priority_normal();
743 PostMsg(hwndTree, WM_COMMAND, MPFROM2SHORT(IDM_UPDATE, 0), MPVOID);
744
745 dcd->suspendview = (USHORT)tempsusp; // Restore
746 fFollowTree = tempfollow; // Restore
747 }
748 }
749 free((CHAR *)mp1);
750 }
751 return 0;
752
753 case UM_TOPDIR:
754 if (mp1) {
755 dcd = INSTDATA(hwnd);
756 if (dcd) {
757 PCNRITEM pci = (PCNRITEM) mp1;
758 WaitFleshWorkListEmpty(pci->pszFileName, 240);
759 ShowCnrRecord(dcd->hwndCnr, (PMINIRECORDCORE) pci);
760 }
761 }
762 return 0;
763
764 case DM_PRINTOBJECT:
765 return MRFROMLONG(DRR_TARGET);
766
767 case DM_DISCARDOBJECT:
768 dcd = INSTDATA(hwnd);
769 if (fFM2Deletes && dcd) {
770
771 LISTINFO *li;
772 CNRDRAGINFO cni;
773
774 cni.pRecord = NULL;
775 cni.pDragInfo = (PDRAGINFO) mp1;
776 li = DoFileDrop(dcd->hwndCnr,
777 dcd->directory, FALSE, MPVOID, MPFROMP(&cni));
778 CheckPmDrgLimit(cni.pDragInfo);
779 if (li) {
780 li->type = ((fDefaultDeletePerm) ? IDM_PERMDELETE : IDM_DELETE);
781 if (!PostMsg(hwnd, UM_MASSACTION, MPFROMP(li), MPVOID))
782 FreeListInfo(li);
783 else
784 return MRFROMLONG(DRR_SOURCE);
785 }
786 }
787 return MRFROMLONG(DRR_TARGET);
788
789 case UM_EXPAND:
790 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
791 if (!dcd)
792 Runtime_Error(pszSrcFile, __LINE__, NULL);
793 else {
794 BOOL tempsusp = dcd->suspendview;
795 INT x = 0;
796 BOOL fExpanding = TRUE;
797 PCNRITEM pci = (PCNRITEM) mp2;
798
799 if (!pci) {
800 Runtime_Error(pszSrcFile, __LINE__, NULL);
801 return 0;
802 }
803 dcd->suspendview = TRUE;
804 priority_idle();
805 if (SHORT1FROMMP(mp1) == IDM_EXPAND) {
806 if (!(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE))
807 fExpandAll = TRUE;
808 while (fExpanding) { // Not serialized not practical to wait on very large directories
809 x++;
810 if (!IsFleshWorkListEmpty()) {
811 WaitFleshWorkListEmpty(NULL, fExpandAll ? 1 : 50); // Let it expand
812 }
813 fExpanding = ExpandAll(dcd->hwndCnr, x, pci);
814 DosSleep(240);
815 }
816 fExpandAll = FALSE;
817 }
818 else
819 CollapseAll(dcd->hwndCnr, pci);
820 priority_normal();
821 DosSleep(1); // Fixes tree epansion (dir text and icons all placed on
822 // the same line as the drive) failure on startup using RWS
823 dcd->suspendview = (USHORT) tempsusp;
824 PostMsg(dcd->hwndCnr, UM_FILTER, MPVOID, MPVOID);
825 }
826 return 0;
827
828 case UM_UPDATERECORDLIST:
829 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
830 if (!dcd || !mp1)
831 Runtime_Error(pszSrcFile, __LINE__, NULL);
832 else {
833 INT numentries = 0;
834 CHAR **list = (CHAR **) mp1;
835
836 while (list[numentries])
837 numentries++;
838 if (numentries)
839 UpdateCnrList(dcd->hwndCnr, list, numentries, TRUE, dcd);
840 }
841 return 0;
842
843 case UM_SETUP2:
844 {
845 PCNRITEM pci = (PCNRITEM) mp1;
846
847 if (pci) {
848 if ((INT) mp2 == 21 && pci->rc.hptrIcon == hptrCDROM) {
849 if (fEjectCDScan)
850 PostMsg(hwndTree, WM_COMMAND, MPFROM2SHORT(IDM_RESCAN, 0), MPVOID);
851 else {
852 driveflags[toupper(*pci->pszFileName) - 'A'] |= DRIVE_INVALID;
853 PostMsg(hwndTree, WM_COMMAND, MPFROM2SHORT(IDM_UPDATE, 0), MPVOID);
854 }
855 }
856 NotifyError(pci->pszFileName, (ULONG) mp2);
857 }
858 }
859 return 0;
860
861 case UM_SETUP:
862# ifdef FORTIFY
863 Fortify_EnterScope();
864# endif
865 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
866 if (!dcd)
867 Runtime_Error(pszSrcFile, __LINE__, NULL);
868 else {
869# ifdef FORTIFY
870 Fortify_BecomeOwner(dcd);
871# endif
872 dcd->hwndObject = hwnd;
873 if (ParentIsDesktop(hwnd, dcd->hwndParent))
874 DosSleep(100);
875 }
876 return 0;
877
878 case UM_RESCAN2:
879 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
880 if (!dcd)
881 Runtime_Error(pszSrcFile, __LINE__, NULL);
882 // Bypass if not running integrated (i.e if vtree)
883 else if (hwndStatus &&
884 dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
885 CHAR s[CCHMAXPATH * 2];
886 PCNRITEM pci = (PCNRITEM) mp1;
887 FSALLOCATE fsa;
888 struct
889 {
890 ULONG serial;
891 CHAR volumelength;
892 CHAR volumelabel[CCHMAXPATH];
893 }
894 volser;
895 CHAR tb[64];
896 CHAR szFree[64];
897 CNRINFO cnri;
898 CHAR FileSystem[CCHMAXPATH * 2];
899 CHAR szTmpLabel[CCHMAXPATH];
900 ULONG type;
901
902 strcpy(s, GetPString(IDS_TREETEXT));
903 memset(&cnri, 0, sizeof(CNRINFO));
904 cnri.cb = sizeof(CNRINFO);
905 WinSendMsg(dcd->hwndCnr,
906 CM_QUERYCNRINFO,
907 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
908 if (cnri.cRecords) {
909 sprintf(s, GetPString(IDS_NUMDRIVESTEXT), cnri.cRecords);
910 if (pci && (INT) pci != -1) {
911 if (!(driveflags[toupper(*pci->pszFileName) - 'A'] &
912 DRIVE_REMOVABLE) ||
913 driveserial[toupper(*pci->pszFileName) - 'A'] != -1) {
914 memset(&volser, 0, sizeof(volser));
915 DosError(FERR_DISABLEHARDERR);
916 if (!DosQueryFSInfo(toupper(*pci->pszFileName) - '@',
917 FSIL_VOLSER,
918 &volser,
919 (ULONG) sizeof(volser)) &&
920 dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
921 DosError(FERR_DISABLEHARDERR);
922 if (!DosQueryFSInfo(toupper(*pci->pszFileName) - '@',
923 FSIL_ALLOC, &fsa, sizeof(FSALLOCATE))) {
924 CommaFmtULL(tb, sizeof(tb),
925 (ULONGLONG) fsa.cUnitAvail * (fsa.cSectorUnit *
926 fsa.cbSector), 'M');
927 sprintf(szFree, " %s %s", tb, GetPString(IDS_FREETEXT));
928 }
929 else
930 *szFree = 0;
931 //Show information on status line not shown in the tree container
932 driveserial[toupper(*pci->pszFileName) - 'A'] = volser.serial;
933 if (CheckDrive(toupper(*pci->pszFileName), FileSystem, &type) == -1 ||
934 fShowFSTypeInTree)
935 strcpy(FileSystem, NullStr);
936 if (fShowDriveLabelInTree)
937 strcpy(szTmpLabel, NullStr);
938 else
939 strcpy(szTmpLabel, volser.volumelabel);
940 if (fSplitStatus) {
941 CHAR temp[CCHMAXPATH] = " [";
942
943 strcat(temp, s);
944 strcat(temp, "]");
945 sprintf(s,
946 GetPString(fShowFSTypeInTree ? IDS_TREESTATUSSTART1TEXT :
947 fShowDriveLabelInTree ? IDS_TREESTATUSSTART2TEXT :
948 IDS_TREESTATUSSTARTTEXT), toupper(*pci->pszFileName),
949 FileSystem, szTmpLabel, volser.serial, szFree);
950 strcat(s, temp);
951 }
952 else {
953 strcat(s, " [");
954 sprintf(&s[strlen(s)],
955 GetPString(fShowFSTypeInTree ? IDS_TREESTATUSSTART1TEXT :
956 fShowDriveLabelInTree ? IDS_TREESTATUSSTART2TEXT :
957 IDS_TREESTATUSSTARTTEXT), toupper(*pci->pszFileName),
958 FileSystem, szTmpLabel, volser.serial, szFree);
959 strcat(s, "]");
960 }
961 if (!fMoreButtons) {
962 if (*dcd->mask.szMask ||
963 (dcd->mask.attrFile != ALLATTRS ||
964 ((fFilesInTree ||
965 (driveflags[toupper(*pci->pszFileName)] &
966 DRIVE_INCLUDEFILES)) ?
967 dcd->mask.antiattr :
968 (dcd->mask.antiattr &&
969 dcd->mask.antiattr != FILE_DIRECTORY)))) {
970 sprintf(&s[strlen(s)],
971 " (%s)",
972 (*dcd->mask.szMask) ?
973 dcd->mask.szMask : GetPString(IDS_ATTRTEXT));
974 }
975 }
976 }
977 }
978 else {
979 // find root record and strip it if needed
980 pci = FindParentRecord(dcd->hwndCnr, pci);
981 driveserial[toupper(*pci->pszFileName) - 'A'] = -1;
982 if (pci->fleshed) {
983 WaitFleshWorkListEmpty(pci->pszFileName, 240); // 2015-08-19 SHL in case pci still in work list
984 if ((toupper(*pci->pszFileName) - 'A') > 1) {
985 AddFleshWorkRequest(hwnd, pci, eUnFlesh);
986 }
987 else
988 UnFlesh(hwnd, pci);
989 }
990 }
991 }
992 }
993 // 21 Sep 09 SHL FIXME to know why checking again - focus change?
994 if (dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent))
995 WinSetWindowText(hwndStatus, s);
996 }
997 return 0;
998
999 case UM_RESCAN:
1000 // Populate container
1001 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1002 if (!dcd)
1003 Runtime_Error(pszSrcFile, __LINE__, NULL);
1004 else {
1005 RemoveCnrItems(dcd->hwndCnr, NULL, 0, CMA_FREE | CMA_INVALIDATE | CMA_ERASE);
1006 WinSendMsg(dcd->hwndCnr,
1007 CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(-1));
1008 WinSendMsg(dcd->hwndCnr,
1009 CM_SCROLLWINDOW,
1010 MPFROMSHORT(CMA_HORIZONTAL), MPFROMLONG(-1));
1011 FillTreeCnr(dcd->hwndCnr, dcd->hwndParent);
1012 if (fOkayMinimize) {
1013 PostMsg(dcd->hwndCnr, UM_MINIMIZE, MPVOID, MPVOID);
1014 fOkayMinimize = FALSE;
1015 }
1016 WinSendMsg(dcd->hwndCnr,
1017 CM_INVALIDATERECORD,
1018 MPVOID, MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
1019 PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
1020 }
1021 return 0;
1022
1023 case UM_COMMAND:
1024 if (mp1) {
1025
1026 LISTINFO *li = (LISTINFO *) mp1;
1027
1028 switch (li->type) {
1029 case IDM_DOITYOURSELF:
1030 case IDM_APPENDTOCLIP:
1031 case IDM_SAVETOCLIP:
1032 case IDM_ARCHIVE:
1033 case IDM_VIEW:
1034 case IDM_EDIT:
1035 case IDM_OBJECT:
1036 case IDM_SHADOW:
1037 case IDM_SHADOW2:
1038 case IDM_JAVAEXE:
1039 case IDM_PRINT:
1040 case IDM_ATTRS:
1041 case IDM_DELETE:
1042 case IDM_PERMDELETE:
1043 if (li->type == IDM_DELETE)
1044 ignorereadonly = FALSE;
1045 if (PostMsg(hwnd, UM_MASSACTION, mp1, mp2))
1046 return (MRESULT) TRUE;
1047 default:
1048 if (PostMsg(hwnd, UM_ACTION, mp1, mp2))
1049 return (MRESULT) TRUE;
1050 }
1051 }
1052 return 0;
1053
1054 case UM_MASSACTION:
1055 if (mp1) {
1056
1057 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1058 if (!dcd)
1059 Runtime_Error(pszSrcFile, __LINE__, NULL);
1060 else {
1061 WORKER *wk;
1062# ifdef FORTIFY
1063 Fortify_EnterScope();
1064# endif
1065 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
1066 if (!wk)
1067 FreeListInfo((LISTINFO *) mp1);
1068 else {
1069 wk->size = sizeof(WORKER);
1070 wk->hwndCnr = dcd->hwndCnr;
1071 wk->hwndParent = dcd->hwndParent;
1072 wk->hwndFrame = dcd->hwndFrame;
1073 wk->hwndClient = dcd->hwndClient;
1074 wk->li = (LISTINFO *) mp1;
1075 strcpy(wk->directory, dcd->directory);
1076 if (xbeginthread(MassAction,
1077 122880,
1078 wk,
1079 pszSrcFile,
1080 __LINE__) == -1)
1081 {
1082 free(wk);
1083 FreeListInfo((LISTINFO *) mp1);
1084 }
1085 }
1086# ifdef FORTIFY
1087 Fortify_LeaveScope();
1088# endif
1089 }
1090 }
1091 return 0;
1092
1093 case UM_ACTION:
1094# ifdef FORTIFY
1095 Fortify_EnterScope();
1096# endif
1097 if (mp1) {
1098# ifdef FORTIFY
1099 Fortify_BecomeOwner(mp1);
1100# endif
1101 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1102 if (!dcd)
1103 Runtime_Error(pszSrcFile, __LINE__, NULL);
1104 else {
1105 WORKER *wk;
1106 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
1107 if (!wk)
1108 FreeListInfo((LISTINFO *) mp1);
1109 else {
1110 wk->size = sizeof(WORKER);
1111 wk->hwndCnr = dcd->hwndCnr;
1112 wk->hwndParent = dcd->hwndParent;
1113 wk->hwndFrame = dcd->hwndFrame;
1114 wk->hwndClient = dcd->hwndClient;
1115 wk->li = (LISTINFO *) mp1;
1116 strcpy(wk->directory, dcd->directory);
1117 if (xbeginthread(Action,
1118 122880,
1119 wk,
1120 pszSrcFile,
1121 __LINE__) == -1)
1122 {
1123 free(wk);
1124 FreeListInfo((LISTINFO *) mp1);
1125 }
1126 }
1127 }
1128 }
1129# ifdef FORTIFY
1130 Fortify_LeaveScope();
1131# endif
1132 return 0;
1133
1134 case WM_CLOSE:
1135 WinDestroyWindow(hwnd);
1136 break;
1137
1138 case WM_DESTROY:
1139 hwndTree = (HWND) 0;
1140 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1141 if (dcd) {
1142 WinSendMsg(dcd->hwndCnr,
1143 UM_CLOSE, MPFROMLONG(dcd->dontclose != FALSE), MPVOID);
1144 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, NULL); // 13 Apr 10 SHL Set NULL before freeing dcd
1145 free(dcd);
1146# ifdef FORTIFY
1147 Fortify_LeaveScope();
1148# endif
1149 }
1150 xDosPostEventSem(CompactSem);
1151 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
1152 WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
1153 break;
1154 }
1155 return WinDefWindowProc(hwnd, msg, mp1, mp2);
1156}
1157
1158MRESULT EXPENTRY TreeCnrWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1159{
1160 static APPNOTIFY *apphead = NULL, *apptail = NULL;
1161 DIRCNRDATA *dcd = INSTDATA(hwnd);
1162 PCNRITEM pci;
1163 APIRET rc;
1164
1165 switch (msg) {
1166 case DM_PRINTOBJECT:
1167 return MRFROMLONG(DRR_TARGET);
1168
1169 case DM_DISCARDOBJECT:
1170 if (dcd)
1171 return WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
1172 else
1173 return MRFROMLONG(DRR_TARGET);
1174
1175 case WM_CHAR:
1176 shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
1177 if (SHORT1FROMMP(mp1) & KC_KEYUP)
1178 return (MRESULT) TRUE;
1179 if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
1180 switch (SHORT2FROMMP(mp2)) {
1181 case VK_INSERT:
1182 if ((shiftstate & KC_CTRL) == KC_CTRL)
1183 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_MKDIR, 0), MPVOID);
1184 break;
1185 case VK_DELETE:
1186 if ((shiftstate & KC_CTRL) == KC_CTRL)
1187 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PERMDELETE, 0), MPVOID);
1188 else if ((shiftstate & KC_SHIFT) == KC_SHIFT)
1189 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_SAVETOCLIP, 0), MPVOID);
1190 else
1191 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DELETE, 0), MPVOID);
1192 break;
1193 } // switch
1194 }
1195
1196 if (SearchContainer(hwnd, msg, mp1, mp2))
1197 return (MRESULT)TRUE; // Avoid default handler
1198
1199 break; // Let default handler see key
1200
1201 case WM_MOUSEMOVE:
1202 case WM_BUTTON1UP:
1203 case WM_BUTTON2UP:
1204 case WM_BUTTON3UP:
1205 shiftstate = (SHORT2FROMMP(mp2) & (KC_SHIFT | KC_ALT | KC_CTRL));
1206 break;
1207
1208 case UM_TIMER:
1209 if (dcd && dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent) &&
1210 hwndStatus2) {
1211 FILEFINDBUF3L ffb;
1212 ULONG nm = 1;
1213 HDIR hdir = HDIR_CREATE;
1214
1215 if (*SwapperDat) {
1216 if (!xDosFindFirst(SwapperDat,
1217 &hdir,
1218 FILE_NORMAL | FILE_HIDDEN |
1219 FILE_SYSTEM | FILE_ARCHIVED | FILE_READONLY,
1220 &ffb, sizeof(ffb), &nm, FIL_STANDARDL)) {
1221 CHAR tb[39], tm[39], tpm[39], s[163];
1222 ULONG amem;
1223
1224 priority_bumped();
1225 DosFindClose(hdir);
1226 if (!DosQuerySysInfo(QSV_TOTAVAILMEM,
1227 QSV_TOTAVAILMEM,
1228 (PVOID) & amem, sizeof(amem))) {
1229 CommaFmtULL(tpm, sizeof(tpm), amem, 'M');
1230 }
1231 else
1232 *tpm = 0;
1233 if (!Dos16MemAvail(&amem))
1234 CommaFmtULL(tm, sizeof(tm), amem, 'M');
1235 else
1236 *tm = 0;
1237 CommaFmtULL(tb, sizeof(tb), ffb.cbFile, 'M');
1238 sprintf(s, " %s %s%s%s%s%s",
1239 GetPString(IDS_SWAPFILETEXT),
1240 tb,
1241 *tm ? GetPString(IDS_TREEMEMTEXT) : NullStr,
1242 tm, *tpm ? "/" : NullStr, tpm);
1243 WinSetWindowText(hwndStatus2, s);
1244 }
1245 else
1246 WinSetWindowText(hwndStatus2, NullStr);
1247 }
1248 else
1249 WinSetWindowText(hwndStatus2, NullStr);
1250 }
1251 // 13 Jul 09 SHL FIXME to make sense
1252 if (msg == UM_TIMER)
1253 return 0;
1254 break;
1255
1256 case WM_PRESPARAMCHANGED:
1257 PresParamChanged(hwnd, PCSZ_TREECNR, mp1, mp2);
1258 break;
1259
1260 case UM_FILESMENU:
1261 {
1262 HWND menuHwnd = (HWND) 0;
1263 FSALLOCATE fsa;
1264
1265 pci = (PCNRITEM)CurrentRecord(hwnd);
1266 if (pci && (INT)pci != -1) {
1267 if (IsRoot(pci->pszFileName) || !DosQueryFSInfo(toupper(*pci->pszFileName) - '@',
1268 FSIL_ALLOC, &fsa,
1269 sizeof(FSALLOCATE)))
1270 menuHwnd = CheckMenu(hwndMainMenu, &TreeMenu, TREE_POPUP);
1271 else {
1272 menuHwnd = CheckMenu(hwndMainMenu, &DirMenu, DIR_POPUP);
1273 }
1274 if (!(pci->attrFile & FILE_DIRECTORY))
1275 menuHwnd = CheckMenu(hwndMainMenu, &FileMenu, FILE_POPUP);
1276 }
1277 return MRFROMLONG(menuHwnd);
1278 }
1279
1280 case UM_COMPARE:
1281 if (dcd && mp1 && mp2) {
1282
1283 COMPARE *cmp;
1284 CHAR *leftdir = (CHAR *)mp1, *rightdir = (CHAR *)mp2;
1285
1286 if (!IsFile(leftdir) && !IsFile(rightdir)) {
1287 cmp = xmallocz(sizeof(COMPARE), pszSrcFile, __LINE__);
1288 if (cmp) {
1289 cmp->size = sizeof(COMPARE);
1290 strcpy(cmp->leftdir, leftdir);
1291 strcpy(cmp->rightdir, rightdir);
1292 cmp->hwndParent = dcd->hwndParent;
1293 cmp->dcd.hwndParent = dcd->hwndParent;
1294 WinDlgBox(HWND_DESKTOP,
1295 HWND_DESKTOP,
1296 CompareDlgProc, FM3ModHandle, COMP_FRAME, MPFROMP(cmp));
1297 }
1298 }
1299 }
1300 return 0;
1301
1302 case UM_UPDATERECORDLIST:
1303 if (dcd && mp1)
1304 WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
1305 return 0;
1306
1307 case UM_UPDATERECORD:
1308 if (dcd && mp1) {
1309 CHAR *filename;
1310 filename = mp1;
1311 if (filename) {
1312 UpdateCnrRecord(hwnd, filename, TRUE, dcd);
1313 }
1314 }
1315 return 0;
1316
1317 case WM_SETFOCUS:
1318 if (dcd && hwndStatus && mp2) {
1319 WinSendMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1320 if (hwndMain)
1321 PostMsg(hwndMain, UM_ADVISEFOCUS, MPFROMLONG(dcd->hwndFrame), MPVOID);
1322 }
1323 break;
1324
1325 case UM_RESCAN:
1326
1327 if (dcd && dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
1328 // put name of our window on status line
1329
1330 PCNRITEM pci = NULL;
1331 CHAR str[CCHMAXPATH + 6];
1332
1333 if (fAutoView && hwndMain) {
1334 pci = WinSendMsg(hwnd,
1335 CM_QUERYRECORDEMPHASIS,
1336 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1337 if (pci && (INT) pci != -1 && fComments &&
1338 !(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_SLOW))
1339 WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
1340 else
1341 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1342 }
1343 if (!fAutoView || !hwndMain)
1344 pci = (PCNRITEM) WinSendMsg(hwnd,
1345 CM_QUERYRECORDEMPHASIS,
1346 MPFROMLONG(CMA_FIRST),
1347 MPFROMSHORT(CRA_CURSORED));
1348 if ((INT) pci == -1)
1349 pci = NULL;
1350 if (pci) {
1351 if (*(ULONG *) realappname == FM3UL) {
1352 sprintf(str, "%s %s", GetPString(IDS_DTTEXT), pci->pszFileName);
1353 WinSetWindowText(dcd->hwndFrame, str);
1354 WinSetWindowText(WinWindowFromID(dcd->hwndFrame, FID_TITLEBAR),
1355 str);
1356 }
1357 else
1358 WinSetWindowText(WinWindowFromID(dcd->hwndFrame,
1359 MAIN_STATUS), pci->pszFileName);
1360 if (fMoreButtons && hwndName) {
1361 CHAR szDate[DATE_BUF_BYTES];
1362
1363 DateFormat(szDate, pci->date);
1364 WinSetWindowText(hwndName, pci->pszFileName);
1365 sprintf(str, "%s %02u%s%02u%s%02u", szDate,
1366 pci->time.hours, TimeSeparator,
1367 pci->time.minutes, TimeSeparator, pci->time.seconds);
1368 WinSetWindowText(hwndDate, str);
1369 WinSetWindowText(hwndAttr, pci->pszDispAttr);
1370 }
1371 }
1372 PostMsg(dcd->hwndObject, UM_RESCAN2, MPFROMP(pci), MPVOID);
1373 if (hwndStatus2)
1374 PostMsg(hwnd, UM_TIMER, MPVOID, MPVOID);
1375 }
1376 return 0;
1377
1378 case UM_SETUP:
1379# ifdef FORTIFY
1380 // Balance WM_DESTROY
1381 Fortify_EnterScope();
1382# endif
1383
1384 if (!dcd) {
1385 Runtime_Error(pszSrcFile, __LINE__, NULL);
1386 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1387 return 0;
1388 }
1389 else {
1390 if (!dcd->hwndObject) {
1391 // first time through -- set things up
1392 CNRINFO cnri;
1393
1394# ifdef FORTIFY
1395 Fortify_EnterScope();
1396# endif
1397
1398 RestorePresParams(hwnd, PCSZ_TREECNR);
1399 memset(&cnri, 0, sizeof(CNRINFO));
1400 cnri.cb = sizeof(CNRINFO);
1401 WinSendMsg(hwnd,
1402 CM_QUERYCNRINFO,
1403 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1404 cnri.cyLineSpacing = 0;
1405 cnri.cxTreeIndent = 12;
1406 cnri.pSortRecord = (PVOID) SortTreeCnr;
1407 cnri.flWindowAttr &= (~(CV_NAME | CV_DETAIL | CV_TEXT));
1408 cnri.flWindowAttr |= (CV_TREE | CA_TREELINE | CV_ICON | CV_MINI);
1409 {
1410 ULONG size = sizeof(ULONG);
1411
1412 PrfQueryProfileData(fmprof,
1413 appname,
1414 "TreeflWindowAttr",
1415 (PVOID) & cnri.flWindowAttr, &size);
1416 size = sizeof(MASK);
1417 *dcd->mask.prompt = 0;
1418 if (!*dcd->mask.szMask && !dcd->mask.attrFile) {
1419 if (PrfQueryProfileSize(fmprof,
1420 appname, "TreeFilter", &size) && size) {
1421 PrfQueryProfileData(fmprof,
1422 appname, "TreeFilter", &dcd->mask, &size);
1423 SetMask(NULL, &dcd->mask);
1424 }
1425 else
1426 dcd->mask.attrFile = (FILE_READONLY | FILE_NORMAL |
1427 FILE_ARCHIVED | FILE_DIRECTORY |
1428 FILE_HIDDEN | FILE_SYSTEM);
1429 }
1430 dcd->mask.attrFile |= FILE_DIRECTORY;
1431 }
1432 cnri.flWindowAttr &= (~(CA_MIXEDTARGETEMPH | CA_ORDEREDTARGETEMPH));
1433 cnri.flWindowAttr |= CV_FLOW;
1434 dcd->flWindowAttr = cnri.flWindowAttr;
1435 WinSendMsg(hwnd,
1436 CM_SETCNRINFO,
1437 MPFROMP(&cnri),
1438 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
1439 CMA_CXTREEINDENT | CMA_PSORTRECORD));
1440 if (xbeginthread(MakeObjWin,
1441 327680,
1442 dcd,
1443 pszSrcFile,
1444 __LINE__) == -1)
1445 {
1446 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1447 }
1448 else
1449 DosSleep(1);
1450# ifdef FORTIFY
1451 Fortify_LeaveScope();
1452# endif
1453 }
1454 }
1455 return 0;
1456
1457 case WM_BUTTON3CLICK:
1458 case WM_CHORD:
1459 {
1460 PCNRITEM pci = NULL;
1461 QUERYRECFROMRECT pqr;
1462 NOTIFYRECORDENTER nr;
1463 BOOL tbool = fDCOpens;
1464 RECTL rectl;
1465 POINTL ptl;
1466
1467 shiftstate = (SHORT2FROMMP(mp2) & (KC_SHIFT | KC_ALT | KC_CTRL));
1468 if (msg == WM_CHORD) {
1469 if (!WinQueryPointerPos(HWND_DESKTOP, &ptl))
1470 break;
1471 WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
1472 }
1473 else {
1474 ptl.x = SHORT1FROMMP(mp1);
1475 ptl.y = SHORT2FROMMP(mp1);
1476 }
1477 memset(&rectl, 0, sizeof(rectl));
1478 memset(&pqr, 0, sizeof(pqr));
1479 pqr.cb = sizeof(pqr);
1480 pqr.rect.xLeft = ptl.x - 1;
1481 pqr.rect.xRight = ptl.x + 1;
1482 pqr.rect.yTop = ptl.y + 1;
1483 pqr.rect.yBottom = ptl.y - 1;
1484 pqr.fsSearch = CMA_PARTIAL;
1485 pci = (PCNRITEM) WinSendMsg(hwnd,
1486 CM_QUERYRECORDFROMRECT,
1487 MPFROMLONG(CMA_FIRST), MPFROMP(&pqr));
1488 if (!pci || (INT) pci == -1)
1489 break; //Probable B3 click on white space
1490 else {
1491 memset(&nr, 0, sizeof(nr));
1492 nr.hwndCnr = hwnd;
1493 nr.pRecord = (PRECORDCORE) pci;
1494 fDCOpens = TRUE;
1495 WinSendMsg(hwnd,
1496 WM_CONTROL,
1497 MPFROM2SHORT(WinQueryWindowUShort(hwnd,
1498 QWS_ID),
1499 CN_ENTER), MPFROMP(&nr));
1500 PostMsg(hwnd, UM_RESTOREDC, MPFROMLONG(tbool), MPVOID);
1501 }
1502 }
1503 break;
1504
1505 case UM_RESTOREDC:
1506 fDCOpens = (BOOL) mp1;
1507 return 0;
1508
1509 case WM_CONTROL:
1510 DosError(FERR_DISABLEHARDERR);
1511 if (dcd) {
1512 switch (SHORT2FROMMP(mp1)) {
1513 case CN_BEGINEDIT:
1514 case CN_REALLOCPSZ:
1515 case CN_ENDEDIT:
1516 {
1517 MRESULT mre;
1518
1519 mre = CnrDirectEdit(hwnd, msg, mp1, mp2);
1520 if (mre != (MRESULT) - 1)
1521 return mre;
1522 }
1523 break;
1524
1525 case CN_DRAGLEAVE:
1526 if (mp2) {
1527
1528 PDRAGINFO pDInfo;
1529
1530 // fixme to know why - seems superfluous
1531 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
1532 DrgAccessDraginfo(pDInfo);
1533 DrgFreeDraginfo(pDInfo);
1534 }
1535 return 0;
1536
1537 case CN_DROPHELP:
1538 if (mp2) {
1539
1540 PDRAGINFO pDInfo;
1541 PCNRITEM pci;
1542 ULONG numitems;
1543 USHORT usOperation;
1544
1545 pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
1546 pDInfo = (PDRAGINFO) ((PCNRDRAGINFO) mp2)->pDragInfo;
1547 if (!DrgAccessDraginfo(pDInfo)) {
1548 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
1549 GetPString(IDS_DROPERRORTEXT));
1550 }
1551 else {
1552 numitems = DrgQueryDragitemCount(pDInfo);
1553 usOperation = pDInfo->usOperation;
1554 if (usOperation == DO_DEFAULT)
1555 usOperation = fCopyDefault ? DO_COPY : DO_MOVE;
1556 FreeDragInfoData(hwnd, pDInfo);
1557 saymsg(MB_ENTER | MB_ICONASTERISK,
1558 hwnd,
1559 GetPString(IDS_DROPHELPHDRTEXT),
1560 GetPString(IDS_DROPHELPTEXT),
1561 numitems,
1562 &"s"[numitems == 1L],
1563 pci ? NullStr : GetPString(IDS_NOTEXT),
1564 pci ? NullStr : " ",
1565 pci ? pci->pszFileName : NullStr,
1566 pci ? " " : NullStr,
1567 GetPString((usOperation == DO_MOVE) ?
1568 IDS_MOVETEXT :
1569 (usOperation == DO_LINK) ?
1570 IDS_LINKTEXT : IDS_COPYTEXT));
1571 }
1572 }
1573 return 0;
1574
1575 case CN_DRAGAFTER:
1576 case CN_DRAGOVER:
1577 if (mp2) {
1578
1579 PDRAGITEM pDItem;
1580 PDRAGINFO pDInfo;
1581 PCNRITEM pci;
1582 USHORT uso;
1583
1584 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
1585 if (!DrgAccessDraginfo(pDInfo)) {
1586 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
1587 PCSZ_DRGACCESSDRAGINFO);
1588 return (MRFROM2SHORT(DOR_NODROP, 0)); // Drop not valid
1589 }
1590 pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
1591 if ((INT) pci == -1)
1592 pci = NULL;
1593 if (pci && (pci->flags & (RECFLAGS_ENV | RECFLAGS_NODROP))) {
1594 DrgFreeDraginfo(pDInfo);
1595 return MRFROM2SHORT(DOR_NODROP, 0);
1596 }
1597 if (!WinIsWindowEnabled(dcd->hwndFrame)) {
1598 DrgFreeDraginfo(pDInfo);
1599 return MRFROM2SHORT(DOR_NODROP, 0);
1600 }
1601 if (pci) {
1602 uso = pDInfo->usOperation;
1603 if (uso == DO_DEFAULT)
1604 uso = (fCopyDefault) ? DO_COPY : DO_MOVE;
1605 if (!(pci->attrFile & FILE_DIRECTORY)) {
1606 if (uso != DO_LINK && uso != DO_COPY && uso != DO_MOVE) {
1607 DrgFreeDraginfo(pDInfo);
1608 return (MRFROM2SHORT(DOR_NODROP, 0));
1609 }
1610 if (uso != DO_LINK &&
1611 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
1612 DRIVE_NOTWRITEABLE)) {
1613
1614 ARC_TYPE *info;
1615
1616 if (!fQuickArcFind &&
1617 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
1618 DRIVE_SLOW))
1619 info = find_type(pci->pszFileName, NULL);
1620 else
1621 info = quick_find_type(pci->pszFileName, NULL);
1622 if (!info || ((uso == DO_MOVE && !info->move) ||
1623 (uso == DO_COPY && !info->create))) {
1624 DrgFreeDraginfo(pDInfo);
1625 return (MRFROM2SHORT(DOR_NODROP, 0));
1626 }
1627 }
1628 }
1629 }
1630 pDItem = DrgQueryDragitemPtr(pDInfo, // Access DRAGITEM
1631 0); // Index to DRAGITEM
1632 if (DrgVerifyRMF(pDItem, // Check valid rendering
1633 (CHAR *) DRM_OS2FILE, // mechanisms and data
1634 NULL) || DrgVerifyRMF(pDItem,
1635 (CHAR *) DRM_FM2ARCMEMBER,
1636 (CHAR *) DRF_FM2ARCHIVE)) { // formats
1637 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
1638 if (!pci || (INT) pci == -1)
1639 return MRFROM2SHORT(DOR_DROP, DO_MOVE);
1640 if (driveflags[toupper(*pci->pszFileName) - 'A'] &
1641 DRIVE_NOTWRITEABLE)
1642 return MRFROM2SHORT(DOR_DROP, DO_LINK);
1643 if (toupper(*pci->pszFileName) < 'C')
1644 return MRFROM2SHORT(DOR_DROP, DO_COPY);
1645 return MRFROM2SHORT(DOR_DROP, // Return okay to drop
1646 ((fCopyDefault) ? DO_COPY : DO_MOVE));
1647 }
1648 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
1649 }
1650 return MRFROM2SHORT(DOR_NODROP, 0); // Drop not valid
1651
1652 case CN_INITDRAG:
1653 {
1654 PCNRDRAGINIT pcd = (PCNRDRAGINIT) mp2;
1655 PCNRITEM pci;
1656
1657 if (!pcd) {
1658 Runtime_Error(pszSrcFile, __LINE__, NULL);
1659 break;
1660 }
1661 else {
1662 pci = (PCNRITEM) pcd->pRecord;
1663 if (!pci || (INT) pci == -1) {
1664 Runtime_Error(pszSrcFile, __LINE__, NULL);
1665 break;
1666 }
1667 if (pci->flags & (RECFLAGS_ENV | RECFLAGS_NODRAG)) {
1668 Runtime_Error(pszSrcFile, __LINE__, "drag not allowed");
1669 break;
1670 }
1671 if (hwndStatus2) {
1672 WinSetWindowText(hwndStatus2, (IsRoot(pci->pszFileName)) ?
1673 (CHAR *) GetPString(IDS_DRAGROOTTEXT) :
1674 (pci->attrFile & FILE_DIRECTORY) ?
1675 (CHAR *) GetPString(IDS_DRAGDIRTEXT) :
1676 (CHAR *) GetPString(IDS_DRAGFILETEXT));
1677 }
1678 DoFileDrag(hwnd, dcd->hwndObject, mp2, NULL, NULL, TRUE);
1679 if (hwndStatus2) {
1680 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1681 }
1682 }
1683 }
1684 return 0;
1685
1686 case CN_DROP:
1687 {
1688 LISTINFO *li;
1689 ULONG action = UM_ACTION;
1690
1691 li = DoFileDrop(hwnd, NULL, TRUE, mp1, mp2);
1692 CheckPmDrgLimit(((PCNRDRAGINFO)mp2)->pDragInfo);
1693 if (li) {
1694 if (!*li->targetpath) {
1695 if (li->list[0])
1696 PMMkDir(dcd->hwndParent, li->list[0], FALSE);
1697 FreeListInfo(li);
1698 return 0;
1699 }
1700 if (li->list && li->list[0] && IsRoot(li->list[0]))
1701 li->type = DO_LINK;
1702 else if (fDragndropDlg && (!*li->arcname || !li->info)) {
1703
1704 CHECKLIST cl;
1705
1706 memset(&cl, 0, sizeof(cl));
1707 cl.size = sizeof(cl);
1708 cl.flags = li->type;
1709 cl.list = li->list;
1710 cl.cmd = li->type;
1711 cl.prompt = li->targetpath;
1712 li->type = WinDlgBox(HWND_DESKTOP,
1713 dcd->hwndParent,
1714 DropListProc,
1715 FM3ModHandle, DND_FRAME, MPFROMP(&cl));
1716 if (li->type == DID_ERROR)
1717 Win_Error(hwnd, HWND_DESKTOP, pszSrcFile, __LINE__,
1718 GetPString(IDS_DRAGDROPDIALOGTEXT));
1719 if (!li->type) {
1720 FreeListInfo(li);
1721 return 0;
1722 }
1723 li->list = cl.list;
1724 if (!li->list || !li->list[0]) {
1725 FreeListInfo(li);
1726 return 0;
1727 }
1728 }
1729 switch (li->type) {
1730 case DO_LINK:
1731 if (fLinkSetsIcon) {
1732 li->type = IDM_SETICON;
1733 action = UM_MASSACTION;
1734 }
1735 else
1736 li->type = IDM_COMPARE;
1737 break;
1738 case DND_EXTRACT:
1739 if (*li->targetpath && !IsFile(li->targetpath))
1740 li->type = IDM_EXTRACT;
1741 break;
1742 case DND_MOVE:
1743 li->type = IDM_MOVE;
1744 if (*li->targetpath && IsFile(li->targetpath) == 1) {
1745 action = UM_MASSACTION;
1746 li->type = IDM_ARCHIVEM;
1747 }
1748 break;
1749 case DND_WILDMOVE:
1750 li->type = IDM_WILDMOVE;
1751 if (*li->targetpath && IsFile(li->targetpath) == 1) {
1752 action = UM_MASSACTION;
1753 li->type = IDM_ARCHIVEM;
1754 }
1755 break;
1756 case DND_OBJECT:
1757 li->type = IDM_OBJECT;
1758 action = UM_MASSACTION;
1759 break;
1760 case DND_SHADOW:
1761 li->type = IDM_SHADOW;
1762 action = UM_MASSACTION;
1763 break;
1764 case DND_COMPARE:
1765 li->type = IDM_COMPARE;
1766 break;
1767 case DND_SETICON:
1768 action = UM_MASSACTION;
1769 li->type = IDM_SETICON;
1770 break;
1771 case DND_COPY:
1772 li->type = IDM_COPY;
1773 if (*li->targetpath && IsFile(li->targetpath) == 1) {
1774 action = UM_MASSACTION;
1775 li->type = IDM_ARCHIVE;
1776 }
1777 break;
1778 case DND_WILDCOPY:
1779 li->type = IDM_WILDCOPY;
1780 if (*li->targetpath && IsFile(li->targetpath) == 1) {
1781 action = UM_MASSACTION;
1782 li->type = IDM_ARCHIVE;
1783 }
1784 break;
1785 default:
1786 if (*li->arcname && li->info) {
1787 action = UM_MASSACTION;
1788 li->type = (li->type == DO_MOVE) ?
1789 IDM_FAKEEXTRACTM : IDM_FAKEEXTRACT;
1790 }
1791 else if (*li->targetpath && IsFile(li->targetpath) == 1) {
1792 action = UM_MASSACTION;
1793 li->type = (li->type == DO_MOVE) ? IDM_ARCHIVEM : IDM_ARCHIVE;
1794 }
1795 else
1796 li->type = (li->type == DO_MOVE) ? IDM_MOVE : IDM_COPY;
1797 break;
1798 }
1799 if (!li->list || !li->list[0])
1800 FreeListInfo(li);
1801 else if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID))
1802 FreeListInfo(li);
1803 else {
1804
1805 USHORT usop = 0;
1806
1807 switch (li->type) {
1808 case IDM_COPY:
1809 case IDM_WILDCOPY:
1810 usop = DO_COPY;
1811 break;
1812 case IDM_MOVE:
1813 case IDM_WILDMOVE:
1814 case IDM_ARCHIVEM:
1815 usop = DO_MOVE;
1816 break;
1817 }
1818 if (usop)
1819 return MRFROM2SHORT(DOR_DROP, usop);
1820 }
1821 }
1822 }
1823 return 0;
1824
1825 case CN_EMPHASIS:
1826 {
1827 PNOTIFYRECORDEMPHASIS pre = mp2;
1828
1829 if (pre->fEmphasisMask & CRA_SELECTED) {
1830 if (pre->pRecord->flRecordAttr & CRA_SELECTED) {
1831 if (((PCNRITEM) (pre->pRecord))->attrFile & FILE_DIRECTORY) {
1832 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1833 if (fFollowTree &&
1834 !(driveflags
1835 [toupper(*((PCNRITEM) pre->pRecord)->pszFileName) -
1836 'A'] & DRIVE_INVALID)) {
1837 if (!LastDir && !ParentIsDesktop(hwnd, dcd->hwndParent))
1838 LastDir = FindDirCnr(dcd->hwndParent);
1839 if (LastDir) {
1840
1841 NOTIFYRECORDENTER pri;
1842 BOOL tbool = fDCOpens;
1843
1844 fDCOpens = FALSE;
1845 memset(&pri, 0, sizeof(pri));
1846 pri.hwndCnr = hwnd;
1847 pri.fKey = FALSE;
1848 pri.pRecord = pre->pRecord;
1849 WinSendMsg(hwnd,
1850 WM_CONTROL,
1851 MPFROM2SHORT(SHORT1FROMMP(mp1),
1852 CN_ENTER), MPFROMP(&pri));
1853 fDCOpens = tbool;
1854 }
1855 }
1856 if (*(ULONG *) realappname != FM3UL)
1857 WinSetWindowText(WinWindowFromID(dcd->hwndFrame,
1858 MAIN_STATUS),
1859 ((PCNRITEM) (pre->pRecord))->pszFileName);
1860 }
1861 }
1862 }
1863 }
1864 break;
1865
1866 case CN_CONTEXTMENU:
1867 {
1868 PCNRITEM pci = (PCNRITEM)mp2;
1869 BOOL wasFollowing;
1870
1871 wasFollowing = fFollowTree;
1872 fFollowTree = FALSE;
1873 if (pci && (INT)pci != -1 && !(pci->flags & RECFLAGS_ENV)) {
1874 // 2015-08-09 SHL try to ensure contents stable
1875 if (!IsFleshWorkListEmpty())
1876 WinPostMsg(hwnd, msg, mp1, mp2); // Try again later
1877 else {
1878 WinSendMsg(hwnd,
1879 CM_SETRECORDEMPHASIS,
1880 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
1881 MarkAll(hwnd, FALSE, FALSE, TRUE);
1882 if (!(pci->attrFile & FILE_DIRECTORY))
1883 dcd->hwndLastMenu = CheckMenu(hwndMainMenu, &FileMenu, FILE_POPUP);
1884 else if (!IsRoot(pci->pszFileName))
1885 dcd->hwndLastMenu = CheckMenu(hwndMainMenu, &DirMenu, DIR_POPUP);
1886 else
1887 dcd->hwndLastMenu = CheckMenu(hwndMainMenu, &TreeMenu, TREE_POPUP);
1888 }
1889 }
1890 else {
1891 dcd->hwndLastMenu = CheckMenu(hwndMainMenu, &TreeCnrMenu, TREECNR_POPUP);
1892 if (dcd->hwndLastMenu && !dcd->cnremphasized) {
1893 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1894 MPFROM2SHORT(TRUE, CRA_SOURCE));
1895 dcd->cnremphasized = TRUE;
1896 }
1897 }
1898 if (dcd->hwndLastMenu) {
1899 if (dcd->hwndLastMenu == DirMenu)
1900 WinEnableMenuItem(DirMenu, IDM_TREE, FALSE);
1901 if (dcd->hwndLastMenu == TreeCnrMenu) {
1902 if (dcd->flWindowAttr & CV_MINI)
1903 WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
1904 }
1905 if (!PopupMenu(hwnd, hwnd, dcd->hwndLastMenu)) {
1906 if (dcd->cnremphasized) {
1907 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1908 MPFROM2SHORT(FALSE, CRA_SOURCE));
1909 dcd->cnremphasized = FALSE;
1910 }
1911 if (dcd->hwndLastMenu != TreeCnrMenu)
1912 MarkAll(hwnd, TRUE, FALSE, TRUE);
1913 }
1914 }
1915 fFollowTree = wasFollowing;
1916 }
1917 break;
1918
1919 case CN_ENTER:
1920 if (mp2) {
1921 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
1922
1923 PostMsg(hwnd, UM_ENTER, MPFROMP(pci), MPVOID);
1924 }
1925 break;
1926
1927 case CN_COLLAPSETREE:
1928 case CN_EXPANDTREE:
1929 WinPostQueueMsg(hmqExpandTree, CN_EXPANDTREE ? UM_EXPANDTREE :UM_COLLAPSETREE,
1930 mp2, MPFROMP(dcd));
1931 break;
1932 } // switch WM_CONTROL
1933 }
1934 return 0;
1935
1936 case UM_ACTION:
1937 if (mp1) {
1938
1939 LISTINFO *li = mp1;
1940 ULONG action = (ULONG) mp2;
1941
1942 if (!li->list || !li->list[0] ||
1943 !PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID))
1944 FreeListInfo(li);
1945 }
1946 return 0;
1947
1948 case UM_SHOWME:
1949 if (mp1 && dcd) {
1950 CHAR *dir = xstrdup((CHAR *)mp1, pszSrcFile, __LINE__);
1951
1952 if (dir) {
1953 if (!PostMsg(dcd->hwndObject, UM_SHOWME, MPFROMP(dir), MPVOID))
1954 free(dir);
1955 else
1956 SetFleshFocusPath(dir);
1957 }
1958 }
1959 return 0;
1960
1961 case UM_TOPDIR:
1962 if (mp1) {
1963 PostMsg(dcd->hwndObject, UM_TOPDIR, mp1, MPVOID);
1964 }
1965 return 0;
1966
1967 case UM_ENTER:
1968 {
1969 FILEFINDBUF3 ffb;
1970 HDIR hDir = HDIR_CREATE;
1971 ULONG nm = 1;
1972 BOOL IsOk = FALSE;
1973 ULONG ulDriveNum, ulDriveMap;
1974 PCNRITEM pciP, pciL, pci;
1975 ULONG fl = SWP_ACTIVATE;
1976 INT x;
1977
1978 if (fFollowTree)
1979 fl = 0;
1980 SetShiftState();
1981 pci = (PCNRITEM) mp1;
1982 if (pci &&
1983 (INT) pci != -1 &&
1984 !(pci->rc.flRecordAttr & CRA_INUSE) &&
1985 !(pci->flags & RECFLAGS_ENV) && IsFullName(pci->pszFileName)) {
1986 x = (INT) (toupper(*pci->pszFileName) - 'A');
1987 if (driveflags[x] & DRIVE_INVALID) {
1988 if (!fAlertBeepOff)
1989 DosBeep(50, 100);
1990 if (hwndStatus)
1991 WinSetWindowText(hwndStatus, (CHAR *) GetPString(IDS_RESCANSUGTEXT));
1992 return 0;
1993 }
1994 DosError(FERR_DISABLEHARDERR);
1995 if (!DosQCurDisk(&ulDriveNum, &ulDriveMap)) {
1996 if (!(ulDriveMap & 1 << x)) {
1997 pciL = pciP = pci;
1998 for (;;) {
1999 pciP = WinSendMsg(hwnd,
2000 CM_QUERYRECORD,
2001 MPFROMP(pciL),
2002 MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER));
2003 if (pciP && (INT) pciP != -1)
2004 pciL = pciP;
2005 else {
2006 pciP = pciL;
2007 break;
2008 }
2009 } // for
2010 RemoveCnrItems(hwnd, pciP, 1, CMA_FREE | CMA_INVALIDATE);
2011 return 0;
2012 }
2013 }
2014 if (driveflags[x] & (DRIVE_REMOVABLE | DRIVE_NOPRESCAN)) {
2015
2016 struct
2017 {
2018 ULONG serial;
2019 CHAR volumelength;
2020 CHAR volumelabel[CCHMAXPATH];
2021 }
2022 volser;
2023 CHAR FileSystem[CCHMAXPATH];
2024 CHAR szBuf[CCHMAXPATH];
2025
2026 pciL = pciP = pci;
2027 for (;;) {
2028 pciP = WinSendMsg(hwnd,
2029 CM_QUERYRECORD,
2030 MPFROMP(pciL),
2031 MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER));
2032 if (pciP && (INT) pciP != -1)
2033 pciL = pciP;
2034 else {
2035 pciP = pciL;
2036 break;
2037 }
2038 }
2039 if ((driveflags[x] & DRIVE_NOPRESCAN) || (toupper(*pci->pszFileName) > 'B' &&
2040 !(driveflags[x] & DRIVE_CDROM))) {
2041 DriveFlagsOne(x, FileSystem, &volser);
2042 SelectDriveIcon(pciP);
2043 if (hwndMain)
2044 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
2045 }
2046 memset(&volser, 0, sizeof(volser));
2047 DosError(FERR_DISABLEHARDERR);
2048 rc = DosQueryFSInfo(toupper(*pci->pszFileName) - '@',
2049 FSIL_VOLSER, &volser,
2050 (ULONG) sizeof(volser));
2051 if (!rc) {
2052 if (!volser.serial || driveserial[x] != volser.serial) {
2053 AddFleshWorkRequest(hwnd, pciP, eFlesh); // forceFlesh
2054 driveserial[x] = volser.serial;
2055 }
2056 if (!pciP->fleshed) {
2057 AddFleshWorkRequest(hwnd, pciP, eFlesh); // forceFlesh
2058 }
2059 if ((fShowFSTypeInTree || fShowDriveLabelInTree) &&
2060 strlen(pciP->pszFileName) < 4) {
2061 strcpy(szBuf, pciP->pszFileName);
2062 strcat(szBuf, " [");
2063 strcat(szBuf, fShowFSTypeInTree ? FileSystem : volser.volumelabel);
2064 strcat(szBuf, "]");
2065 pciP->pszDisplayName = xstrdup(szBuf, pszSrcFile, __LINE__);
2066 pciP->rc.pszIcon = pciP->pszDisplayName;
2067 }
2068 WinSendMsg(hwnd,
2069 CM_INVALIDATERECORD,
2070 MPFROMP(&pciP),
2071 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
2072 }
2073 else {
2074 driveserial[x] = -1;
2075 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2076 if (dcd)
2077 PostMsg(dcd->hwndObject, UM_SETUP2, MPFROMP(pci), MPFROMLONG(rc));
2078 return 0;
2079 }
2080 }
2081 rc = 0;
2082 IsOk = (IsRoot(pci->pszFileName) &&
2083 IsValidDrive(toupper(*pci->pszFileName)));
2084 if (!IsOk) {
2085 DosError(FERR_DISABLEHARDERR);
2086 rc = DosFindFirst(pci->pszFileName, &hDir,
2087 FILE_NORMAL | FILE_DIRECTORY |
2088 FILE_ARCHIVED | FILE_READONLY |
2089 FILE_HIDDEN | FILE_SYSTEM,
2090 &ffb, sizeof(ffb), &nm, FIL_STANDARD);
2091 priority_bumped();
2092 }
2093 if (!rc) {
2094 if (!IsOk)
2095 DosFindClose(hDir);
2096 if (IsOk || (ffb.attrFile & FILE_DIRECTORY)) {
2097 if ((shiftstate & (KC_CTRL | KC_ALT)) == (KC_CTRL | KC_ALT)) {
2098 PostMsg(hwnd,
2099 WM_COMMAND, MPFROM2SHORT(IDM_SHOWALLFILES, 0), MPVOID);
2100 return 0;
2101 }
2102 if ((shiftstate & (KC_CTRL | KC_SHIFT)) == (KC_CTRL | KC_SHIFT)) {
2103 OpenObject(pci->pszFileName, Settings, dcd->hwndFrame);
2104 return 0;
2105 }
2106 if (!(shiftstate & (KC_CTRL | KC_SHIFT))) {
2107 if (!ParentIsDesktop(hwnd, dcd->hwndParent)) {
2108 if (FindDirCnrByName(pci->pszFileName, TRUE)) {
2109 return 0;
2110 }
2111 }
2112 }
2113 if ((shiftstate & KC_CTRL) ||
2114 (!(shiftstate & KC_SHIFT) &&
2115 ParentIsDesktop(hwnd, dcd->hwndParent) && fVTreeOpensWPS)) {
2116
2117 ULONG size = sizeof(ULONG), flWindowAttr = CV_ICON;
2118 CHAR s[33];
2119
2120 strcpy(s, PCSZ_ICON);
2121 PrfQueryProfileData(fmprof,
2122 appname,
2123 "DirflWindowAttr",
2124 (PVOID) & flWindowAttr, &size);
2125 if (flWindowAttr & CV_DETAIL) {
2126 if (IsRoot(pci->pszFileName))
2127 strcpy(s, PCSZ_TREE);
2128 else
2129 strcpy(s, Details);
2130 }
2131 OpenObject(pci->pszFileName, s, dcd->hwndFrame);
2132 return 0;
2133 }
2134 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2135 !fDCOpens && !LastDir && !(shiftstate & KC_SHIFT))
2136 LastDir = FindDirCnr(dcd->hwndParent);
2137 if (LastDir && !fDCOpens && !(shiftstate & KC_SHIFT)) {
2138 WinSendMsg(LastDir,
2139 UM_SETDIR, MPFROMP(pci->pszFileName), MPVOID);
2140 WinSetWindowPos(WinQueryWindow(WinQueryWindow(LastDir,
2141 QW_PARENT),
2142 QW_PARENT),
2143 HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | fl);
2144 }
2145 else
2146 OpenDirCnr(hwnd,
2147 dcd->hwndParent,
2148 dcd->hwndFrame, FALSE, pci->pszFileName);
2149 }
2150 else {
2151 if (!(driveflags[x] & DRIVE_INCLUDEFILES))
2152 RemoveCnrItems(hwnd, pci, 1, CMA_FREE | CMA_INVALIDATE);
2153 else {
2154
2155 SWP swp;
2156
2157 WinQueryWindowPos(dcd->hwndFrame, &swp);
2158 DefaultViewKeys(hwnd,
2159 dcd->hwndFrame,
2160 dcd->hwndParent, &swp, pci->pszFileName);
2161 }
2162 }
2163 }
2164 else {
2165 if (!IsRoot(pci->pszFileName)) {
2166 NotifyError(pci->pszFileName, rc);
2167 RemoveCnrItems(hwnd, pci, 1, CMA_FREE | CMA_INVALIDATE);
2168 }
2169 }
2170 }
2171 else if (!pci)
2172 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_MKDIR, 0), MPVOID);
2173 if (fFollowTree)
2174 WinSetFocus(HWND_DESKTOP, hwnd);
2175 }
2176 return 0;
2177
2178 case WM_MENUEND:
2179 if (dcd) {
2180
2181 HWND hwndMenu = (HWND) mp2;
2182
2183 if (hwndMenu == TreeCnrMenu || hwndMenu == TreeMenu ||
2184 hwndMenu == DirMenu) {
2185 MarkAll(hwnd, TRUE, FALSE, TRUE);
2186 if (dcd->cnremphasized) {
2187 WinSendMsg(hwnd,
2188 CM_SETRECORDEMPHASIS,
2189 MPVOID, MPFROM2SHORT(FALSE, CRA_SOURCE));
2190 dcd->cnremphasized = FALSE;
2191 }
2192 }
2193 }
2194 break;
2195
2196 case UM_OPENWINDOWFORME:
2197 if (dcd) {
2198 if (mp1 && !IsFile((CHAR *)mp1))
2199 OpenDirCnr(hwnd, dcd->hwndParent, dcd->hwndFrame, FALSE, (char *)mp1);
2200 }
2201 return 0;
2202
2203 case MM_PORTHOLEINIT:
2204 if (dcd) {
2205 switch (SHORT1FROMMP(mp1)) {
2206 case 0:
2207 case 1:
2208 {
2209 ULONG wmsg;
2210
2211 wmsg = ((SHORT1FROMMP(mp1) == 0) ? UM_FILESMENU : UM_VIEWSMENU);
2212 PortholeInit((HWND) WinSendMsg(dcd->hwndClient,
2213 wmsg, MPVOID, MPVOID), mp1, mp2);
2214 }
2215 break;
2216 }
2217 }
2218 break;
2219
2220 case UM_INITMENU:
2221 case WM_INITMENU:
2222 if (dcd) {
2223
2224 switch (SHORT1FROMMP(mp1)) {
2225 case IDM_FILESMENU:
2226 {
2227 PCNRITEM pci;
2228
2229 pci = (PCNRITEM) CurrentRecord(hwnd);
2230 if (pci && (INT) pci != -1) {
2231 BOOL rdy;
2232 BOOL writeable;
2233 BOOL removable;
2234 BOOL local;
2235 BOOL underenv;
2236 CHAR chDrvU;
2237 CHAR szDrv[CCHMAXPATH];
2238
2239 strcpy(szDrv, pci->pszFileName);
2240 chDrvU = *pci->pszFileName;
2241 chDrvU = toupper(chDrvU);
2242 MakeValidDir(szDrv);
2243 rdy = *szDrv == chDrvU; // Drive not ready if MakeValidDir changes drive letter
2244 removable = rdy
2245 && (driveflags[chDrvU - 'A'] & DRIVE_REMOVABLE) != 0;
2246 writeable = rdy
2247 && !(driveflags[chDrvU - 'A'] & DRIVE_NOTWRITEABLE);
2248 local = rdy && (!(driveflags[chDrvU - 'A'] & (DRIVE_REMOTE | DRIVE_VIRTUAL)));
2249 underenv = (pci->flags & RECFLAGS_UNDERENV) != 0;
2250 CopyPresParams((HWND) mp2, hwndMainMenu);
2251 WinEnableMenuItem((HWND) mp2, IDM_INFO, rdy);
2252
2253 WinEnableMenuItem((HWND) mp2, IDM_ATTRS, writeable);
2254 WinEnableMenuItem((HWND) mp2, IDM_EAS, writeable);
2255 WinEnableMenuItem((HWND) mp2, IDM_SUBJECT, writeable);
2256 WinEnableMenuItem((HWND) mp2, IDM_DRVFLAGS, 1); // fixme to allow if not ready
2257
2258 WinEnableMenuItem((HWND) mp2, IDM_ARCHIVE, rdy);
2259
2260 WinEnableMenuItem((HWND) mp2, IDM_UPDATE, !underenv);
2261 WinEnableMenuItem((HWND) mp2, IDM_EXPANDSUBMENU, !underenv);
2262 WinEnableMenuItem((HWND) mp2, IDM_EXPAND, !underenv);
2263 WinEnableMenuItem((HWND) mp2, IDM_COLLAPSE, !underenv);
2264
2265 WinEnableMenuItem((HWND) mp2, IDM_SIZES, rdy);
2266 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, writeable);
2267 WinEnableMenuItem((HWND) mp2, IDM_SHOWALLFILES, rdy);
2268 WinEnableMenuItem((HWND) mp2, IDM_UNDELETE, writeable);
2269
2270 WinEnableMenuItem((HWND) mp2, IDM_CHKDSK, writeable && local);
2271 WinEnableMenuItem((HWND) mp2, IDM_FORMAT, writeable && local);
2272 WinEnableMenuItem((HWND) mp2, IDM_OPTIMIZE, writeable && local);
2273 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONSMENU, local);
2274 WinEnableMenuItem((HWND) mp2, IDM_PARTITION, fMiniLVM);
2275 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONDF, fDFSee);
2276 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONLVMG, fLVMGui);
2277 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONLVM, fLVM);
2278 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONFD, fFDisk);
2279
2280 WinEnableMenuItem((HWND) mp2, IDM_DETACH, !local);
2281
2282 WinEnableMenuItem((HWND) mp2, IDM_EJECT, removable);
2283
2284 WinEnableMenuItem((HWND) mp2, IDM_LOCK, removable);
2285 WinEnableMenuItem((HWND) mp2, IDM_UNLOCK, removable);
2286
2287 WinEnableMenuItem((HWND) mp2, IDM_DELETE, !underenv && writeable);
2288 WinEnableMenuItem((HWND) mp2, IDM_PERMDELETE, !underenv
2289 && writeable);
2290 WinEnableMenuItem((HWND) mp2, IDM_DELETESUBMENU, !underenv
2291 && writeable);
2292 WinEnableMenuItem((HWND) mp2, IDM_MOVEMENU, !underenv
2293 && writeable);
2294 WinEnableMenuItem((HWND) mp2, IDM_RENAME, !underenv && writeable);
2295
2296 }
2297 }
2298 break;
2299
2300 case IDM_VIEWSMENU:
2301 WinCheckMenuItem((HWND) mp2,
2302 IDM_MINIICONS, ((dcd->flWindowAttr & CV_MINI) != 0));
2303 CopyPresParams((HWND) mp2, hwndMainMenu);
2304 WinEnableMenuItem((HWND) mp2, IDM_RESELECT, FALSE);
2305 WinEnableMenuItem((HWND) mp2, IDM_PARTITION, fMiniLVM);
2306 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONDF, fDFSee);
2307 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONLVMG, fLVMGui);
2308 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONLVM, fLVM);
2309 WinEnableMenuItem((HWND) mp2, IDM_PARTITIONFD, fFDisk);
2310 break;
2311
2312 case IDM_COMMANDSMENU:
2313 SetupCommandMenu((HWND) mp2, hwnd);
2314 CopyPresParams((HWND) mp2, hwndMainMenu);
2315 break;
2316
2317 case IDM_SORTSUBMENU:
2318 SetSortChecks((HWND) mp2, TreesortFlags);
2319 CopyPresParams((HWND) mp2, hwndMainMenu);
2320 break;
2321
2322 case IDM_WINDOWSMENU:
2323 SetupWinList((HWND) mp2,
2324 (hwndMain) ? hwndMain : (HWND) 0, dcd->hwndFrame);
2325 CopyPresParams((HWND) mp2, hwndMainMenu);
2326 break;
2327 }
2328 dcd->hwndLastMenu = (HWND) mp2;
2329 }
2330 if (msg == WM_INITMENU)
2331 break;
2332 return 0;
2333
2334 case UM_COMMAND:
2335 if (!mp1)
2336 Runtime_Error(pszSrcFile, __LINE__, NULL);
2337 else {
2338 if (!dcd) {
2339 Runtime_Error(pszSrcFile, __LINE__, NULL);
2340 FreeListInfo((LISTINFO *) mp1);
2341 }
2342 else {
2343 if (!PostMsg(dcd->hwndObject, UM_COMMAND, mp1, mp2)) {
2344 Runtime_Error(pszSrcFile, __LINE__, PCSZ_POSTMSG);
2345 FreeListInfo((LISTINFO *) mp1);
2346 }
2347 else
2348 return (MRESULT) TRUE;
2349 }
2350 }
2351 return 0;
2352
2353 case UM_LOADFILE:
2354 if (dcd && mp2) {
2355
2356 HWND hwnd;
2357
2358 if ((INT)mp1 == 5 || (INT)mp1 == 13 || (INT)mp1 == 21)
2359 hwnd = StartViewer(HWND_DESKTOP, (INT)mp1,
2360 (CHAR *)mp2, dcd->hwndFrame);
2361 else
2362 hwnd = StartMLEEditor(dcd->hwndParent,
2363 (INT)mp1, (CHAR *)mp2, dcd->hwndFrame);
2364 free((CHAR *)mp2);
2365 return MRFROMLONG(hwnd);
2366 }
2367 return 0;
2368
2369 case UM_FIXCNRMLE:
2370 case UM_FIXEDITNAME:
2371 return CommonCnrProc(hwnd, msg, mp1, mp2);
2372
2373 case UM_NOTIFY:
2374 if (mp2)
2375 Notify((CHAR *)mp2);
2376 return 0;
2377
2378 case UM_FILTER:
2379 if (dcd) {
2380
2381 BOOL tempsusp = dcd->suspendview;
2382
2383 if (mp1)
2384 SetMask((CHAR *)mp1, &dcd->mask);
2385
2386 dcd->suspendview = TRUE;
2387 dcd->mask.attrFile |= FILE_DIRECTORY;
2388 WinSendMsg(hwnd, CM_FILTER, MPFROMP(Filter), MPFROMP(&dcd->mask));
2389 dcd->suspendview = (USHORT) tempsusp;
2390 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2391 }
2392 return 0;
2393
2394 case UM_DRIVECMD:
2395 if (mp1) {
2396 ShowTreeRec(hwnd, (CHAR *)mp1, FALSE, TRUE);
2397 PostMsg(hwndTree, WM_COMMAND, MPFROM2SHORT(IDM_UPDATE, 0), MPVOID);
2398 }
2399 return 0;
2400
2401 case WM_APPTERMINATENOTIFY:
2402 {
2403 APPNOTIFY *info;
2404 PCNRITEM pci;
2405 CHAR s[] = " :\\";
2406
2407 if (!mp2) {
2408 if (hwndMain)
2409 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
2410 }
2411 info = apphead;
2412 while (info) {
2413 if (info->happ == (HAPP) mp1) {
2414 *s = info->device;
2415 pci = FindCnrRecord(hwnd, s, NULL, FALSE, FALSE, TRUE);
2416 if (pci && (INT) pci != -1) {
2417 INT x = info->device - 'A';
2418 CHAR FileSystem[CCHMAXPATH];
2419
2420 driveserial[x] = -1;
2421 DriveFlagsOne(x, FileSystem, NULL);
2422 if (driveflags[x] &
2423 (DRIVE_INVALID | DRIVE_IGNORE))
2424 RemoveCnrItems(hwnd, pci, 1, CMA_FREE);
2425 else
2426 AddFleshWorkRequest(hwnd, pci, eFlesh);
2427 }
2428 if (info->prev)
2429 info->prev->next = info->next;
2430 if (info->next)
2431 info->next->prev = info->prev;
2432 if (apphead == info)
2433 apphead = info->next;
2434 if (apptail == info)
2435 apptail = info->prev;
2436 free(info);
2437 break;
2438 }
2439 info = info->next;
2440 }
2441 }
2442 break;
2443
2444 case WM_COMMAND:
2445 DosError(FERR_DISABLEHARDERR);
2446 if (dcd) {
2447 if (SwitchCommand(dcd->hwndLastMenu, SHORT1FROMMP(mp1)))
2448 return 0;
2449 switch (SHORT1FROMMP(mp1)) {
2450 case IDM_SETTARGET:
2451 SetTargetDir(hwnd, FALSE, NULL);
2452 break;
2453
2454 case IDM_DETACH:
2455 {
2456 CHAR d[3] = " :";
2457 PCNRITEM pci;
2458 PROGDETAILS pgd;
2459 CHAR params[368], *p;
2460 HAPP happ;
2461
2462 pci = (PCNRITEM) CurrentRecord(hwnd);
2463 if (pci && (INT) pci != -1 && isalpha(*pci->pszFileName)) {
2464 *d = toupper(*pci->pszFileName);
2465 p = GetCmdSpec(FALSE);
2466 memset(&pgd, 0, sizeof(pgd));
2467 pgd.Length = sizeof(pgd);
2468 pgd.progt.progc = PROG_WINDOWABLEVIO;
2469 pgd.progt.fbVisible = SHE_VISIBLE;
2470 pgd.pszTitle = (PSZ)GetPString(IDS_DETACHREQUESTTEXT);
2471 pgd.pszExecutable = p;
2472 pgd.pszParameters = params;
2473 pgd.pszStartupDir = NULL;
2474 pgd.pszIcon = NULL;
2475 pgd.pszEnvironment = NULL;
2476 pgd.swpInitial.hwndInsertBehind = HWND_TOP;
2477 pgd.swpInitial.hwnd = hwnd;
2478 pgd.swpInitial.fl = SWP_SHOW | SWP_ACTIVATE;
2479 sprintf(params, "/C NET USE %s /D", d);
2480 happ = WinStartApp(hwnd, &pgd, pgd.pszParameters,
2481 NULL, SAF_MAXIMIZED);
2482 if (!happ) {
2483 saymsg(MB_CANCEL | MB_ICONEXCLAMATION, hwnd,
2484 GetPString(IDS_ERRORTEXT),
2485 GetPString(IDS_CANTSTARTTEXT), p, params);
2486 }
2487 else {
2488 APPNOTIFY *info;
2489
2490 info = xmallocz(sizeof(APPNOTIFY), pszSrcFile, __LINE__);
2491 if (info) {
2492 info->happ = happ;
2493 info->device = *d;
2494 if (!apphead)
2495 apphead = info;
2496 else {
2497 apptail->next = info;
2498 info->prev = apptail;
2499 }
2500 apptail = info;
2501 }
2502 PostMsg(hwndTree, WM_COMMAND, MPFROM2SHORT(IDM_RESCAN, 0), MPVOID);
2503 }
2504 }
2505 }
2506 break;
2507
2508 case IDM_REMAP:
2509 WinDlgBox(HWND_DESKTOP, hwnd, RemapDlgProc,
2510 FM3ModHandle, MAP_FRAME, NULL);
2511 break;
2512
2513 case IDM_CONTEXTMENU:
2514 {
2515 PCNRITEM pci;
2516
2517 pci = (PCNRITEM) CurrentRecord(hwnd);
2518 PostMsg(hwnd, WM_CONTROL, MPFROM2SHORT(DIR_CNR, CN_CONTEXTMENU),
2519 MPFROMP(pci));
2520 }
2521 break;
2522
2523 case IDM_FINDINTREE:
2524 {
2525 PSZ pszTempDir;
2526 PCNRITEM pci;
2527
2528 pci = (PCNRITEM) CurrentRecord(hwnd);
2529 if (pci && (INT) pci != -1) {
2530 pszTempDir = xstrdup(pci->pszFileName, pszSrcFile, __LINE__);
2531 if (pszTempDir)
2532 MakeValidDir(pszTempDir);
2533 }
2534 else
2535 pszTempDir = xstrdup(pFM2SaveDirectory, pszSrcFile, __LINE__);
2536 if (pszTempDir) {
2537 if (WinDlgBox(HWND_DESKTOP, dcd->hwndParent,
2538 WalkAllDlgProc,
2539 FM3ModHandle, WALK_FRAME, MPFROMP(pszTempDir))) {
2540 if (!WinSendMsg(hwnd, UM_SHOWME, MPFROMP(pszTempDir), MPFROMLONG(1)))
2541 free(pszTempDir);
2542 }
2543 else
2544 free(pszTempDir);
2545 }
2546 }
2547 break;
2548
2549 case IDM_BEGINEDIT:
2550 OpenEdit(hwnd);
2551 break;
2552
2553 case IDM_ENDEDIT:
2554 WinSendMsg(hwnd, CM_CLOSEEDIT, MPVOID, MPVOID);
2555 break;
2556
2557 case IDM_FILTER:
2558 {
2559 BOOL empty = FALSE;
2560 PCNRITEM pci;
2561
2562 pci = (PCNRITEM) CurrentRecord(hwnd);
2563 if (!*dcd->mask.szMask)
2564 empty = TRUE;
2565 dcd->mask.fIsTree = TRUE;
2566 *dcd->mask.prompt = 0;
2567 if (pci && (INT) pci != -1)
2568 dcd->mask.fFilesIncluded =
2569 ((driveflags[toupper(*pci->pszFileName) - 'A'] &
2570 DRIVE_INCLUDEFILES) != 0);
2571 else
2572 dcd->mask.fFilesIncluded = FALSE;
2573 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
2574 FM3ModHandle, MSK_FRAME, MPFROMP(&dcd->mask)))
2575 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2576 else if (empty)
2577 *dcd->mask.szMask = 0;
2578 PrfWriteProfileData(fmprof, appname, "TreeFilter", &dcd->mask,
2579 sizeof(MASK));
2580 }
2581 break;
2582
2583 case IDM_SHOWSORT:
2584 QuickPopup(hwnd, dcd, CheckMenu(hwndMainMenu, &TreeCnrMenu, TREECNR_POPUP),
2585 IDM_SORTSUBMENU);
2586 break;
2587
2588 case IDM_SHOWSELECT:
2589 QuickPopup(hwnd, dcd, CheckMenu(hwndMainMenu, &TreeCnrMenu, TREECNR_POPUP),
2590 IDM_SELECTSUBMENU);
2591 break;
2592
2593 case IDM_TREECNRVIEWSETTINGS:
2594 if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndParent))
2595 PostMsg(dcd->hwndParent, msg, MPFROMLONG(IDM_TREECNRVIEWSETTINGS), mp2);
2596 else {
2597 WinDlgBox(HWND_DESKTOP,
2598 hwnd,
2599 CfgDlgProc,
2600 FM3ModHandle,
2601 CFG_FRAME,
2602 MPFROMLONG(IDM_TREECNRVIEWSETTINGS));
2603 }
2604 break;
2605
2606 case IDM_WALKDIR:
2607 case IDM_OPENWALK:
2608 {
2609 CHAR newpath[CCHMAXPATH];
2610 PCNRITEM pci;
2611
2612 pci = (PCNRITEM) CurrentRecord(hwnd);
2613 if (pci && (INT) pci != -1) {
2614 strcpy(newpath, pci->pszFileName);
2615 MakeValidDir(newpath);
2616 }
2617 else
2618 strcpy(newpath, pFM2SaveDirectory);
2619 if (!WinDlgBox(HWND_DESKTOP, dcd->hwndParent, WalkAllDlgProc,
2620 FM3ModHandle, WALK_FRAME,
2621 MPFROMP(newpath)) || !*newpath)
2622 break;
2623 WinSendMsg(hwnd, UM_OPENWINDOWFORME, MPFROMP(newpath), MPVOID);
2624 }
2625 break;
2626
2627 case IDM_HELP:
2628 if (hwndHelp) {
2629 if (!ParentIsDesktop(dcd->hwndFrame, dcd->hwndParent))
2630 PostMsg(dcd->hwndParent, UM_COMMAND, mp1, mp2);
2631 else
2632 WinSendMsg(hwndHelp, HM_HELP_CONTENTS, MPVOID, MPVOID);
2633 }
2634 break;
2635
2636 case IDM_PARTITION:
2637 runemf2(SEPARATE | WINDOWED, HWND_DESKTOP, pszSrcFile, __LINE__,
2638 NULL, NULL,
2639 "%s", PCSZ_MINILVMEXE);
2640 break;
2641
2642 case IDM_PARTITIONDF:
2643 runemf2(SEPARATE | WINDOWED, HWND_DESKTOP, pszSrcFile, __LINE__,
2644 NULL, NULL,
2645 "%s", PCSZ_DFSOS2EXE);
2646 break;
2647
2648 case IDM_PARTITIONLVMG:
2649 runemf2(SEPARATE | WINDOWED, HWND_DESKTOP, pszSrcFile, __LINE__,
2650 NULL, NULL,
2651 "%s", PCSZ_LVMGUICMD);
2652 break;
2653
2654 case IDM_PARTITIONLVM:
2655 runemf2(SEPARATE | WINDOWED, HWND_DESKTOP, pszSrcFile, __LINE__,
2656 NULL, NULL,
2657 "%s", PCSZ_LVMEXE);
2658 break;
2659
2660 case IDM_PARTITIONFD:
2661 runemf2(SEPARATE | WINDOWED, HWND_DESKTOP, pszSrcFile, __LINE__,
2662 NULL, NULL,
2663 "%s", PCSZ_FDISKPMEXE);
2664 break;
2665
2666 case IDM_REFRESHREMOVABLES:
2667 {
2668 PFN Rediscover_PRMs;
2669 HMODULE hmod = 0;
2670 CHAR objerr[CCHMAXPATH];
2671
2672 rc = DosLoadModule(objerr, sizeof(objerr), "LVM", &hmod);
2673 if (!rc) {
2674 rc = DosQueryProcAddr(hmod, 70, NULL, &Rediscover_PRMs);
2675 if (!rc)
2676 Rediscover_PRMs(&rc);
2677 DosFreeModule(hmod);
2678 }
2679 if (!rc)
2680 PostMsg(hwndTree, WM_COMMAND, MPFROM2SHORT(IDM_RESCAN, 0), MPVOID);
2681 break;
2682 }
2683
2684 case IDM_SORTNAME:
2685 case IDM_SORTFILENAME:
2686 case IDM_SORTSIZE:
2687 case IDM_SORTEASIZE:
2688 case IDM_SORTFIRST:
2689 case IDM_SORTLAST:
2690 case IDM_SORTLWDATE:
2691 case IDM_SORTLADATE:
2692 case IDM_SORTCRDATE:
2693 TreesortFlags &= (SORT_REVERSE | SORT_DIRSFIRST | SORT_DIRSLAST);
2694 case IDM_SORTDIRSFIRST:
2695 case IDM_SORTDIRSLAST:
2696 case IDM_SORTREVERSE:
2697 switch (SHORT1FROMMP(mp1)) {
2698 case IDM_SORTFILENAME:
2699 TreesortFlags |= SORT_FILENAME;
2700 break;
2701 case IDM_SORTSIZE:
2702 TreesortFlags |= SORT_SIZE;
2703 break;
2704 case IDM_SORTEASIZE:
2705 TreesortFlags |= SORT_EASIZE;
2706 break;
2707 case IDM_SORTFIRST:
2708 TreesortFlags |= SORT_FIRSTEXTENSION;
2709 break;
2710 case IDM_SORTLAST:
2711 TreesortFlags |= SORT_LASTEXTENSION;
2712 break;
2713 case IDM_SORTLWDATE:
2714 TreesortFlags |= SORT_LWDATE;
2715 break;
2716 case IDM_SORTLADATE:
2717 TreesortFlags |= SORT_LADATE;
2718 break;
2719 case IDM_SORTCRDATE:
2720 TreesortFlags |= SORT_CRDATE;
2721 break;
2722 case IDM_SORTDIRSFIRST:
2723 if (TreesortFlags & SORT_DIRSFIRST)
2724 TreesortFlags &= (~SORT_DIRSFIRST);
2725 else {
2726 TreesortFlags |= SORT_DIRSFIRST;
2727 TreesortFlags &= (~SORT_DIRSLAST);
2728 }
2729 break;
2730 case IDM_SORTDIRSLAST:
2731 if (TreesortFlags & SORT_DIRSLAST)
2732 TreesortFlags &= (~SORT_DIRSLAST);
2733 else {
2734 TreesortFlags |= SORT_DIRSLAST;
2735 TreesortFlags &= (~SORT_DIRSFIRST);
2736 }
2737 break;
2738 case IDM_SORTREVERSE:
2739 if (TreesortFlags & SORT_REVERSE)
2740 TreesortFlags &= (~SORT_REVERSE);
2741 else
2742 TreesortFlags |= SORT_REVERSE;
2743 break;
2744 }
2745 PrfWriteProfileData(fmprof, appname, "TreeSort", &TreesortFlags,
2746 sizeof(INT));
2747 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(SortTreeCnr), MPVOID);
2748 break;
2749
2750 case IDM_COLLECT:
2751 case IDM_GREP:
2752 if (!Collector) {
2753
2754 HWND hwndC;
2755 SWP swp;
2756
2757 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2758 !fAutoTile &&
2759 (!fExternalCollector && *(ULONG *) realappname == FM3UL))
2760 GetNextWindowPos(dcd->hwndParent, &swp, NULL, NULL);
2761 hwndC = StartCollector((fExternalCollector ||
2762 *(ULONG *) realappname != FM3UL) ?
2763 HWND_DESKTOP : dcd->hwndParent, 4);
2764 if (hwndC) {
2765 if (!ParentIsDesktop(hwnd,
2766 dcd->hwndParent) &&
2767 !fAutoTile &&
2768 (!fExternalCollector && *(ULONG *) realappname == FM3UL))
2769 WinSetWindowPos(hwndC,
2770 HWND_TOP,
2771 swp.x,
2772 swp.y,
2773 swp.cx,
2774 swp.cy,
2775 SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER);
2776 else if (!ParentIsDesktop(hwnd,
2777 dcd->hwndParent) &&
2778 fAutoTile && *(ULONG *) realappname == FM3UL)
2779 TileChildren(dcd->hwndParent, TRUE);
2780 }
2781 WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
2782 DosSleep(100);
2783 }
2784 else
2785 StartCollector(dcd->hwndParent, 4);
2786 if (SHORT1FROMMP(mp1) == IDM_GREP) {
2787 PCNRITEM pci = NULL;
2788
2789 pci = WinSendMsg(hwnd,
2790 CM_QUERYRECORDEMPHASIS,
2791 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
2792 if (pci && (INT) pci != -1)
2793 PostMsg(Collector, WM_COMMAND,
2794 MPFROM2SHORT(UM_GREP, 0), MPFROMP(pci->pszFileName));
2795 else
2796 PostMsg(Collector, WM_COMMAND,
2797 MPFROM2SHORT(IDM_GREP, 0), MPVOID);
2798 }
2799 else
2800 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_COLLECTOR, 0), MPVOID);
2801 break;
2802
2803 case IDM_COLLECTOR:
2804 DosSleep(32);
2805 {
2806 CHAR **list;
2807
2808 list = BuildList(hwnd);
2809 if (list) {
2810 if (Collector) {
2811 if (!PostMsg(Collector, WM_COMMAND,
2812 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(list)))
2813 FreeList(list);
2814 }
2815 else
2816 FreeList(list);
2817 }
2818 }
2819 break;
2820
2821 case IDM_COLLAPSEALL:
2822 WinSendMsg(hwnd, CM_COLLAPSETREE, MPVOID, MPVOID);
2823 break;
2824
2825 case IDM_COLLAPSE:
2826 case IDM_EXPAND:
2827 {
2828 PCNRITEM pci = NULL;
2829
2830 pci = (PCNRITEM) CurrentRecord(hwnd);
2831 if (pci && (INT) pci != -1) {
2832 if (pci->flags & RECFLAGS_UNDERENV)
2833 break;
2834 PostMsg(dcd->hwndObject, UM_EXPAND, mp1, MPFROMP(pci));
2835 }
2836 }
2837 break;
2838
2839 case IDM_UPDATE:
2840 {
2841 // 2015-08-07 SHL FIXME select
2842 PCNRITEM pci;
2843 if (!IsFleshWorkListEmpty())
2844 break; // 2015-08-07 SHL hold off until stable
2845 pci = (PCNRITEM)CurrentRecord(hwnd);
2846 if (pci && (INT)pci != -1) {
2847 struct
2848 {
2849 ULONG serial;
2850 CHAR volumelength;
2851 CHAR volumelabel[CCHMAXPATH];
2852 }
2853 volser;
2854 INT x = toupper(*pci->pszFileName) - 'A';
2855 CHAR FileSystem[CCHMAXPATH], szBuf[CCHMAXPATH];
2856
2857 UINT driveflag = driveflags[x];
2858 if (pci->attrFile & FILE_DIRECTORY) {
2859 if (pci->flags & RECFLAGS_UNDERENV)
2860 break;
2861 if (pci->fleshed) {
2862 if (x > 1) {
2863 AddFleshWorkRequest(hwnd, pci, eUnFlesh);
2864 }
2865 else
2866 UnFlesh(hwnd, pci);
2867 }
2868
2869 // Check if drive type might need update
2870 if ((driveflag & (DRIVE_INVALID | DRIVE_NOPRESCAN)) ||
2871 (~driveflag & DRIVE_NOPRESCAN && pci->rc.hptrIcon == hptrDunno)) {
2872 DriveFlagsOne(x, FileSystem, &volser);
2873 driveflag = driveflags[x];
2874 if (driveflag & DRIVE_INVALID)
2875 if (driveflag & DRIVE_REMOVABLE) {
2876 pci->rc.hptrIcon = hptrRemovable;
2877 if (fShowFSTypeInTree || fShowDriveLabelInTree) {
2878 strcpy(szBuf, pci->pszFileName);
2879 strcat(szBuf, " [");
2880 strcat(szBuf, "]");
2881 pci->pszDisplayName = xstrdup(szBuf, pszSrcFile, __LINE__);
2882 pci->rc.pszIcon = pci->pszDisplayName;
2883 }
2884 }
2885 else
2886 pci->rc.hptrIcon = hptrDunno;
2887 else if (strlen(pci->pszFileName) < 4) {
2888 SelectDriveIcon(pci);
2889 if (fShowFSTypeInTree || fShowDriveLabelInTree) {
2890 strcpy(szBuf, pci->pszFileName);
2891 strcat(szBuf, " [");
2892 strcat(szBuf, fShowFSTypeInTree ? FileSystem : volser.volumelabel);
2893 strcat(szBuf, "]");
2894 pci->pszDisplayName = xstrdup(szBuf, pszSrcFile, __LINE__);
2895 pci->rc.pszIcon = pci->pszDisplayName;
2896 }
2897 }
2898 WinSendMsg(hwnd,
2899 CM_INVALIDATERECORD,
2900 MPFROMP(&pci),
2901 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
2902 if (hwndMain)
2903 PostMsg(hwndMain, UM_BUILDDRIVEBAR, MPVOID, MPVOID);
2904 }
2905 if (~driveflag & DRIVE_INVALID) {
2906 if (x > 1) {
2907 // Note the UnFlesh above may not have completed when this is called
2908 // We need to keep it behind the UnFlesh in line
2909 AddFleshWorkRequest(hwnd, pci, eFlesh);
2910 }
2911 else
2912 Flesh(hwnd, pci);
2913 }
2914 }
2915 }
2916 }
2917 break;
2918
2919 case IDM_RESCAN:
2920 PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPVOID);
2921 break;
2922
2923 case IDM_RESORT:
2924 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(SortTreeCnr), MPVOID);
2925 break;
2926
2927 case IDM_TEXT:
2928 case IDM_MINIICONS:
2929 {
2930 CNRINFO cnri;
2931
2932 memset(&cnri, 0, sizeof(CNRINFO));
2933 cnri.cb = sizeof(CNRINFO);
2934 WinSendMsg(hwnd,
2935 CM_QUERYCNRINFO,
2936 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
2937 if (SHORT1FROMMP(mp1) == IDM_MINIICONS) {
2938 if (cnri.flWindowAttr & CV_MINI)
2939 cnri.flWindowAttr &= (~CV_MINI);
2940 else
2941 cnri.flWindowAttr |= CV_MINI;
2942 }
2943 else {
2944 if (cnri.flWindowAttr & CV_TEXT) {
2945 cnri.flWindowAttr &= (~CV_TEXT);
2946 cnri.flWindowAttr |= CV_ICON;
2947 }
2948 else {
2949 cnri.flWindowAttr &= (~CV_ICON);
2950 cnri.flWindowAttr |= CV_TEXT;
2951 }
2952 }
2953 dcd->flWindowAttr = cnri.flWindowAttr;
2954 PrfWriteProfileData(fmprof,
2955 appname,
2956 "TreeflWindowAttr",
2957 &cnri.flWindowAttr, sizeof(ULONG));
2958 WinSendMsg(hwnd,
2959 CM_SETCNRINFO,
2960 MPFROMP(&cnri),
2961 MPFROMLONG(CMA_FLWINDOWATTR | CMA_TREEICON |
2962 CMA_SLTREEBITMAPORICON));
2963 }
2964 break;
2965
2966 case IDM_SIZES:
2967 case IDM_DRVFLAGS:
2968 case IDM_SHOWALLFILES:
2969 case IDM_UNDELETE:
2970 case IDM_OPTIMIZE:
2971 case IDM_CHKDSK:
2972 case IDM_FORMAT:
2973 case IDM_MKDIR:
2974 case IDM_LOCK:
2975 case IDM_UNLOCK:
2976 case IDM_EJECT:
2977 case IDM_CLOSETRAY:
2978 {
2979 PCNRITEM pci;
2980
2981 pci = (PCNRITEM) CurrentRecord(hwnd);
2982 if (pci && (INT) pci != -1)
2983 CommonDriveCmd(hwnd, pci->pszFileName, SHORT1FROMMP(mp1));
2984 }
2985 break;
2986
2987 case IDM_SAVETOLIST:
2988 WinDlgBox(HWND_DESKTOP,
2989 hwnd,
2990 SaveListDlgProc, FM3ModHandle, SAV_FRAME, MPFROMP(&hwnd));
2991 break;
2992
2993 case IDM_DELETE:
2994 case IDM_PERMDELETE:
2995 case IDM_MOVE:
2996 case IDM_WPSMOVE:
2997 case IDM_WILDMOVE:
2998 case IDM_RENAME:
2999 {
3000 PCNRITEM pci;
3001
3002 pci = (PCNRITEM) CurrentRecord(hwnd);
3003 if (pci && (INT) pci != -1) {
3004 if (pci->flags & RECFLAGS_UNDERENV)
3005 break;
3006 }
3007 }
3008 // else intentional fallthru
3009 case IDM_ATTRS:
3010 case IDM_INFO:
3011 case IDM_COPY:
3012 case IDM_WPSCOPY:
3013 case IDM_WILDCOPY:
3014 case IDM_DOITYOURSELF:
3015 case IDM_OPENWINDOW:
3016 case IDM_OPENSETTINGS:
3017 case IDM_OPENDEFAULT:
3018 case IDM_OPENICON:
3019 case IDM_OPENDETAILS:
3020 case IDM_OPENTREE:
3021 case IDM_SHADOW:
3022 case IDM_SHADOW2:
3023 case IDM_COMPARE:
3024 case IDM_VIEW:
3025 case IDM_VIEWTEXT:
3026 case IDM_VIEWBINARY:
3027 case IDM_EDIT:
3028 case IDM_EDITTEXT:
3029 case IDM_EDITBINARY:
3030 case IDM_EAS:
3031 case IDM_SUBJECT:
3032 case IDM_APPENDTOCLIP:
3033 case IDM_SAVETOCLIP:
3034 case IDM_ARCHIVE:
3035 case IDM_MCIPLAY:
3036 case IDM_UUDECODE:
3037 {
3038 LISTINFO *li;
3039 ULONG action = UM_ACTION;
3040# ifdef FORTIFY
3041 Fortify_EnterScope();
3042# endif
3043 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
3044 if (li) {
3045 li->type = SHORT1FROMMP(mp1);
3046 li->hwnd = hwnd;
3047 li->list = BuildList(hwnd);
3048 if (!li->list || !li->list[0]) {
3049 free(li);
3050 break;
3051 }
3052 if (IsRoot(li->list[0])) {
3053 switch (SHORT1FROMMP(mp1)) {
3054 case IDM_MOVE:
3055 case IDM_COPY:
3056 case IDM_WILDCOPY:
3057 case IDM_WILDMOVE:
3058 case IDM_WPSMOVE:
3059 case IDM_WPSCOPY:
3060 case IDM_RENAME:
3061 case IDM_DELETE:
3062 case IDM_PERMDELETE:
3063 mp1 = MPFROM2SHORT(IDM_INFO, SHORT2FROMMP(mp1));
3064 li->type = IDM_INFO;
3065 }
3066 }
3067 switch (SHORT1FROMMP(mp1)) {
3068 case IDM_APPENDTOCLIP:
3069 case IDM_SAVETOCLIP:
3070 case IDM_ARCHIVE:
3071 case IDM_DELETE:
3072 case IDM_PERMDELETE:
3073 case IDM_ATTRS:
3074 case IDM_SHADOW:
3075 case IDM_SHADOW2:
3076 case IDM_DOITYOURSELF:
3077 case IDM_EAS:
3078 case IDM_VIEW:
3079 case IDM_VIEWTEXT:
3080 case IDM_VIEWBINARY:
3081 case IDM_EDIT:
3082 case IDM_EDITTEXT:
3083 case IDM_EDITBINARY:
3084 case IDM_MCIPLAY:
3085 action = UM_MASSACTION;
3086 }
3087 if (li->type == IDM_DELETE)
3088 ignorereadonly = FALSE;
3089 if (SHORT1FROMMP(mp1) == IDM_SHADOW ||
3090 SHORT1FROMMP(mp1) == IDM_SHADOW2)
3091 *li->targetpath = 0;
3092 if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID)) {
3093 Runtime_Error(pszSrcFile, __LINE__, PCSZ_POSTMSG);
3094 FreeListInfo(li);
3095 }
3096 }
3097# ifdef FORTIFY
3098 Fortify_LeaveScope();
3099# endif
3100 }
3101 break;
3102
3103 default:
3104 if (SHORT1FROMMP(mp1) >= IDM_COMMANDSTART &&
3105 SHORT1FROMMP(mp1) < IDM_QUICKTOOLSTART) {
3106
3107 INT x;
3108
3109 if (!cmdloaded)
3110 load_commands();
3111 x = SHORT1FROMMP(mp1);
3112 if (x >= 0) {
3113 RunCommand(hwnd, x);
3114 if (fUnHilite)
3115 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
3116 }
3117 }
3118 break;
3119 }
3120 }
3121 return 0;
3122
3123 case WM_SAVEAPPLICATION:
3124 if (dcd && !ParentIsDesktop(hwnd, dcd->hwndParent)) {
3125
3126 SWP swp, swpP;
3127 INT ratio;
3128
3129 WinQueryWindowPos(dcd->hwndFrame, &swp);
3130 if (!(swp.fl & (SWP_MINIMIZE | SWP_MAXIMIZE | SWP_HIDE))) {
3131 WinQueryWindowPos(dcd->hwndParent, &swpP);
3132 if (swp.cx) {
3133 ratio = (swpP.cx * 100) / swp.cx;
3134 if (ratio > 0)
3135 PrfWriteProfileData(fmprof, appname, "TreeWindowRatio",
3136 &ratio, sizeof(INT));
3137 }
3138 }
3139 }
3140 else if (dcd && ParentIsDesktop(hwnd, dcd->hwndParent)) {
3141
3142 SWP swp;
3143
3144 WinQueryWindowPos(dcd->hwndFrame, &swp);
3145 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE | SWP_MAXIMIZE)))
3146 WinStoreWindowPos((CHAR *) FM2Str, "VTreeWindowPos", dcd->hwndFrame);
3147 }
3148 break;
3149
3150 case UM_MINIMIZE:
3151 if (dcd && hwndMain) {
3152 fOkayMinimize = TRUE;
3153 if (dcd->hwndObject) {
3154 DosSleep(50);
3155 fOkayMinimize = FALSE;
3156 WinSetWindowPos(((hwndMain) ? WinQueryWindow(hwndMain, QW_PARENT) :
3157 dcd->hwndFrame), HWND_TOP, 0, 0, 0, 0,
3158 SWP_MINIMIZE | SWP_DEACTIVATE);
3159 }
3160 }
3161 return 0;
3162
3163 case UM_MAXIMIZE:
3164 if (dcd || hwndMain)
3165 WinSetWindowPos(((hwndMain) ? WinQueryWindow(hwndMain, QW_PARENT) :
3166 dcd->hwndFrame), HWND_TOP, 0, 0, 0, 0, SWP_MAXIMIZE |
3167 SWP_SHOW);
3168 return 0;
3169
3170 case UM_CLOSE:
3171 {
3172 HWND hwndParent = WinQueryWindow(WinQueryWindow(WinQueryWindow(hwnd,
3173 QW_PARENT),
3174 QW_PARENT), QW_PARENT);
3175
3176 if (!mp1) {
3177 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
3178 WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
3179 if (hwndParent && !ParentIsDesktop(hwnd, hwndParent))
3180 WinDestroyWindow(hwndParent);
3181 }
3182 else
3183 WinDestroyWindow(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
3184 QW_PARENT));
3185 }
3186 return 0;
3187
3188 case WM_CLOSE:
3189 WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
3190 if (dcd)
3191 dcd->stopflag++;
3192 if (dcd && dcd->hwndObject) {
3193 // kill object window
3194 if (WinIsWindow((HAB) 0, dcd->hwndObject)) {
3195 if (!PostMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID))
3196 WinSendMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID);
3197 }
3198 }
3199 else
3200 WinSendMsg(hwnd, UM_CLOSE, MPFROMLONG(1), MPVOID);
3201 return 0;
3202
3203 case WM_DESTROY:
3204# ifdef FORTIFY
3205 DbgMsg(pszSrcFile, __LINE__, "WM_DESTROY hwnd %x TID %u", hwnd, GetTidForThread()); // 18 Jul 08 SHL FIXME
3206# endif
3207 if (TreeCnrMenu)
3208 WinDestroyWindow(TreeCnrMenu);
3209 if (DirMenu)
3210 WinDestroyWindow(DirMenu);
3211 if (FileMenu)
3212 WinDestroyWindow(FileMenu);
3213 TreeCnrMenu = FileMenu = DirMenu = (HWND) 0;
3214 EmptyCnr(hwnd);
3215 if (apphead) {
3216 APPNOTIFY *info, *next;
3217
3218 info = apphead;
3219 while (info) {
3220 next = info->next;
3221 free(info);
3222 info = next;
3223 }
3224 apphead = apptail = NULL;
3225 }
3226# ifdef FORTIFY
3227 Fortify_LeaveScope();
3228# endif
3229 break; // WM_DESTROY
3230 } // switch
3231 if (dcd && dcd->oldproc){
3232 return dcd->oldproc(hwnd, msg, mp1, mp2);
3233 }
3234 else
3235 return PFNWPCnr(hwnd, msg, mp1, mp2);
3236}
3237
3238/**
3239 * Start drive tree container
3240 * @returns tree handle or NULLHANDLE
3241 */
3242
3243HWND StartTreeCnr(HWND hwndParent, ULONG flags)
3244{
3245 /**
3246 * bitmapped flags:
3247 * 0x00000001 = don't close app when window closes
3248 * 0x00000002 = no frame controls
3249 * 0x00000004 = no close or move button
3250 */
3251
3252 HWND hwndFrame = NULLHANDLE;
3253 HWND hwndSysMenu = NULLHANDLE;
3254 HWND hwndClient;
3255 ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
3256 FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE;
3257 DIRCNRDATA *dcd;
3258
3259 if (!hwndParent)
3260 hwndParent = HWND_DESKTOP;
3261 if (ParentIsDesktop(hwndParent, hwndParent))
3262 FrameFlags |= (FCF_TASKLIST | FCF_MENU);
3263 if (flags & 2)
3264 FrameFlags &= (~(FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER |
3265 FCF_MINMAX | FCF_ICON));
3266 hwndFrame = WinCreateStdWindow(hwndParent,
3267 WS_VISIBLE,
3268 &FrameFlags,
3269 (CHAR *) WC_TREECONTAINER,
3270 NULL,
3271 WS_VISIBLE | fwsAnimate,
3272 FM3ModHandle, TREE_FRAME, &hwndClient);
3273 if (hwndParent != HWND_DESKTOP) {
3274 hwndSysMenu = WinWindowFromID(hwndFrame, FID_SYSMENU);
3275 if (hwndSysMenu != NULLHANDLE)
3276 WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
3277 MPFROM2SHORT(SC_CLOSE, TRUE),
3278 MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
3279 if (!fFreeTree)
3280 WinSendMsg(hwndSysMenu, MM_SETITEMATTR,
3281 MPFROM2SHORT(SC_MOVE, TRUE),
3282 MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
3283 }
3284 if (hwndFrame && hwndClient) {
3285# ifdef FORTIFY
3286 Fortify_EnterScope();
3287# endif
3288 dcd = xmallocz(sizeof(DIRCNRDATA), pszSrcFile, __LINE__);
3289 if (!dcd) {
3290 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
3291 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3292 hwndFrame = (HWND) 0;
3293 }
3294 else {
3295 SWP swp;
3296 WinQueryWindowPos(hwndFrame, &swp);
3297 if (*(ULONG *) realappname == FM3UL) {
3298 if (!WinCreateWindow(hwndFrame,
3299 (CHAR *) WC_TREEOPENBUTTON,
3300 "#303",
3301 WS_VISIBLE | BS_PUSHBUTTON | BS_NOPOINTERFOCUS | BS_BITMAP,
3302 ((swp.cx -
3303 WinQuerySysValue(HWND_DESKTOP,
3304 SV_CXMINMAXBUTTON)) -
3305 WinQuerySysValue(HWND_DESKTOP,
3306 SV_CXMINMAXBUTTON) / 2) -
3307 WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER),
3308 (swp.cy -
3309 WinQuerySysValue(HWND_DESKTOP,
3310 SV_CYMINMAXBUTTON)) -
3311 WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER),
3312 WinQuerySysValue(HWND_DESKTOP,
3313 SV_CXMINMAXBUTTON) / 2,
3314 WinQuerySysValue(HWND_DESKTOP,
3315 SV_CYMINMAXBUTTON), hwndFrame,
3316 HWND_TOP, IDM_OPENWINDOW, NULL, NULL)) {
3317 Win_Error(hwndFrame, hwndParent, pszSrcFile, __LINE__,
3318 PCSZ_WINCREATEWINDOW);
3319 }
3320 }
3321 else {
3322 if (!WinCreateWindow(hwndFrame,
3323 (CHAR *) WC_TREESTATUS,
3324 (CHAR *) GetPString(IDS_YOUAREHERETEXT),
3325 WS_VISIBLE | SS_TEXT | DT_LEFT | DT_VCENTER,
3326 swp.x + 4 + WinQuerySysValue(HWND_DESKTOP,
3327 SV_CXSIZEBORDER),
3328 swp.cy - (22 + WinQuerySysValue(HWND_DESKTOP,
3329 SV_CYSIZEBORDER)),
3330 (swp.cx - 8) - (WinQuerySysValue(HWND_DESKTOP,
3331 SV_CXSIZEBORDER)
3332 * 2), 22, hwndFrame, HWND_TOP,
3333 MAIN_STATUS, NULL, NULL)) {
3334 Win_Error(hwndFrame, hwndParent, pszSrcFile, __LINE__,
3335 PCSZ_WINCREATEWINDOW);
3336 }
3337 }
3338 memset(dcd, 0, sizeof(DIRCNRDATA));
3339 dcd->size = sizeof(DIRCNRDATA);
3340 dcd->type = TREE_FRAME;
3341 dcd->dontclose = (flags & 1) != 0;
3342 dcd->hwndParent = hwndParent ? hwndParent : HWND_DESKTOP;
3343 dcd->hwndClient = hwndClient;
3344 dcd->hwndFrame = hwndFrame;
3345 {
3346 PFNWP oldproc;
3347
3348 oldproc = WinSubclassWindow(hwndFrame, TreeFrameWndProc);
3349 WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
3350 oldproc = WinSubclassWindow(WinWindowFromID(hwndFrame, FID_TITLEBAR),
3351 (PFNWP) TreeTitleWndProc);
3352 WinSetWindowPtr(WinWindowFromID(hwndFrame, FID_TITLEBAR),
3353 QWL_USER, (PVOID) oldproc);
3354 }
3355 dcd->hwndCnr = WinCreateWindow(hwndClient,
3356 WC_CONTAINER,
3357 NULL,
3358 CCS_AUTOPOSITION | CCS_MINIICONS |
3359 CCS_MINIRECORDCORE,
3360 0,
3361 0,
3362 0,
3363 0,
3364 hwndClient,
3365 HWND_TOP, (ULONG) TREE_CNR, NULL, NULL);
3366 if (!dcd->hwndCnr) {
3367 Win_Error(hwndClient, hwndClient, pszSrcFile, __LINE__,
3368 PCSZ_WINCREATEWINDOW);
3369 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3370 free(dcd);
3371 dcd = NULL;
3372 hwndFrame = (HWND) 0;
3373 }
3374 else {
3375 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, (PVOID) dcd);
3376 if (ParentIsDesktop(hwndFrame, hwndParent)) {
3377 WinSetWindowText(WinWindowFromID(hwndFrame, FID_TITLEBAR), "VTree");
3378 FixSwitchList(hwndFrame, "VTree");
3379 }
3380 else {
3381 WinSetWindowText(hwndFrame, (CHAR *) GetPString(IDS_TREETEXT));
3382 WinSetWindowText(WinWindowFromID(hwndFrame, FID_TITLEBAR),
3383 (CHAR *) GetPString(IDS_TREETEXT));
3384 }
3385 dcd->oldproc = WinSubclassWindow(dcd->hwndCnr, TreeCnrWndProc);
3386 // fixme to document 01 test?
3387 if (dcd->oldproc == 0)
3388 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
3389 "WinSubclassWindow");
3390 if (!PostMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID))
3391 WinSendMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID);
3392 }
3393 }
3394# ifdef FORTIFY
3395 if (dcd)
3396 Fortify_ChangeScope(dcd, -1);
3397 Fortify_LeaveScope();
3398 if (dcd)
3399 Fortify_ChangeScope(dcd, +1);
3400# endif
3401 }
3402 WinShowWindow(hwndFrame, FALSE);
3403 return hwndFrame;
3404}
3405
3406static VOID ExpandTreeThread(VOID *args)
3407{
3408 QMSG qmsg;
3409 DIRCNRDATA *dcd;
3410 HAB hab = WinInitialize(0);
3411# ifdef FORTIFY
3412 Fortify_EnterScope();
3413# endif
3414 if (hab) {
3415 hmqExpandTree = WinCreateMsgQueue(hab, 0);
3416 if (hmqExpandTree) {
3417 while (WinGetMsg(hab, &qmsg, (HWND) 0, UM_COLLAPSETREE, UM_EXPANDTREE)) {
3418 dcd = (DIRCNRDATA *) qmsg.mp2;
3419 if (!dcd)
3420 Runtime_Error(pszSrcFile, __LINE__, NULL);
3421 else {
3422 PCNRITEM pci = (PCNRITEM) qmsg.mp1;
3423
3424 if (pci && (INT) pci != -1 && !(pci->flags & RECFLAGS_ENV)) {
3425 if (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE) {
3426
3427 struct
3428 {
3429 ULONG serial;
3430 CHAR volumelength;
3431 CHAR volumelabel[CCHMAXPATH];
3432 }
3433 volser;
3434
3435 memset(&volser, 0, sizeof(volser));
3436 DosError(FERR_DISABLEHARDERR);
3437 if (!DosQueryFSInfo(toupper(*pci->pszFileName) - '@',
3438 FSIL_VOLSER, &volser,
3439 (ULONG) sizeof(volser))) {
3440 if (qmsg.msg == UM_COLLAPSETREE &&
3441 !volser.serial ||
3442 driveserial[toupper(*pci->pszFileName) - 'A'] !=
3443 volser.serial)
3444 {
3445 if (pci->fleshed) {
3446 WaitFleshWorkListEmpty(pci->pszFileName, 10); // 2015-08-19 SHL in case pci still in work list
3447 AddFleshWorkRequest(dcd->hwndCnr, pci, eUnFlesh);
3448 }
3449 }
3450 if (qmsg.msg != UM_COLLAPSETREE ||
3451 (!volser.serial ||
3452 driveserial[toupper(*pci->pszFileName) - 'A'] !=
3453 volser.serial)) {
3454 WaitFleshWorkListEmpty(pci->pszFileName, 10); // 2015-08-19 SHL in case pci still in work list
3455 if (qmsg.msg == UM_EXPANDTREE && AddFleshWorkRequest(dcd->hwndCnr, pci, eFlesh)
3456 && !dcd->suspendview && fTopDir) {
3457 PostMsg(dcd->hwndCnr, UM_TOPDIR, MPFROMP(pci), MPVOID);
3458 }
3459 }
3460 driveserial[toupper(*pci->pszFileName) - 'A'] = volser.serial;
3461 }
3462 else {
3463 driveserial[toupper(*pci->pszFileName) - 'A'] = -1;
3464 if (pci->fleshed) {
3465 WaitFleshWorkListEmpty(pci->pszFileName, 10); // 2015-08-19 SHL in case pci still in work list
3466 AddFleshWorkRequest(dcd->hwndCnr, pci, eUnFlesh);
3467 }
3468 PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
3469 if (!fAlertBeepOff)
3470 DosBeep(250, 100);
3471 }
3472 }
3473 else if (qmsg.msg == UM_EXPANDTREE) {
3474 if (fExpandAll)
3475 DosSleep(1);
3476 else {
3477 WaitFleshWorkListEmpty(pci->pszFileName, 10); // 2015-08-19 SHL in case pci still in work list
3478 }
3479 AddFleshWorkRequest(dcd->hwndCnr, pci, eFlesh); // forceFlesh
3480 if (!dcd->suspendview && fTopDir) {
3481 PostMsg(dcd->hwndCnr, UM_TOPDIR, MPFROMP(pci), MPVOID);
3482 }
3483 }
3484 if (qmsg.msg == UM_EXPANDTREE && !dcd->suspendview) {
3485 WinSendMsg(dcd->hwndCnr, UM_FILTER, MPVOID, MPVOID);
3486 }
3487 }
3488 }
3489 }
3490 }
3491 WinDestroyMsgQueue(hmqExpandTree);
3492 }
3493 WinTerminate(hab);
3494# ifdef FORTIFY
3495 Fortify_LeaveScope();
3496# endif
3497}
3498
3499BOOL StartExpandTreeThread(VOID)
3500{
3501 TID tid;
3502 tid = xbeginthread(ExpandTreeThread,
3503 65536,
3504 NULL,
3505 pszSrcFile, __LINE__);
3506 return tid != -1;
3507
3508}
3509
3510#pragma alloc_text(TREECNR,TreeCnrWndProc,TreeObjWndProc,TreeClientWndProc)
3511#pragma alloc_text(TREECNR,TreeFrameWndProc,TreeTitleWndProc,ShowTreeRec)
3512#pragma alloc_text(TREECNR,TreeStatProc,OpenButtonProc)
3513#pragma alloc_text(STARTUP,StartTreeCnr)
Note: See TracBrowser for help on using the repository browser.