source: trunk/dll/treecnr.c@ 1874

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

DosSleep times in WaitFleshWorkListEmpty set by caller; TOPDIR code calls WaitFleshWorkListEmpty before ShowCnrRecord and now actually exists for directory containers in tree view. These calls are made from the object windows.

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