source: trunk/dll/treecnr.c

Last change on this file was 1912, checked in by Gregg Young, 10 months ago

One more attempt to fix the tree container corruption on scan/rescan

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