source: trunk/dll/treecnr.c@ 1875

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

Move the eUnflesh call from UM_ENTER to the object window so WaitFleshWorkListEmpty can be used (UM_ENTER is on TID 1); Prevent eUnflesh from running if no child directories are present; treat floppies like invalid drives on rescan (IDM_UPDATE to avoid them seen as directories and having random subdirectories attached to them.

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