source: trunk/dll/treecnr.c@ 1896

Last change on this file since 1896 was 1896, checked in by Gregg Young, 3 years ago

Attempt to fix tree container corruption and rare trap when both switch on focaus change and switch on directory change are enabled.

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