source: trunk/dll/treecnr.c@ 1880

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

Remove dead code and comments from remaining c files. #if 0 and #if NEVER were not addressed

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