source: trunk/dll/treecnr.c@ 1883

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

Comments for CS [1882]

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