source: trunk/dll/treecnr.c@ 1876

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

Eliminate some unnecessary Flesh and UnFlesh calls.Update icon and display name on CD/DVD eject in all cases.
Don't use Flesh thread for floppy drive scans fix them getting mistakenly identified as directories and add nonexistent subdirectories.

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