source: trunk/dll/treecnr.c@ 1873

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

Adjustments to ShowTreeRec to eliminate failures and reduce retries and container noise on tree switches. Remove fInitialDriveScan code. Changes to speed up ExpandAll. WaitFleshWorkListEmpty now gives error message and returns if semaphore request fails more than 5 consecutive times.

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