source: trunk/dll/dircnrs.c@ 1890

Last change on this file since 1890 was 1890, checked in by Steven Levine, 6 years ago

Add PMPRINTF enable support to makefiles.
Correct PMPRINTF debug macro enables in sources.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 106.9 KB
Line 
1
2/***********************************************************************
3
4 $Id: dircnrs.c 1890 2020-01-30 06:39:42Z stevenhl $
5
6 Directory containers
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2015 Steven H. Levine
10
11 16 Oct 02 SHL Handle large partitions
12 01 Aug 04 SHL Rework lstrip/rstrip usage
13 23 May 05 SHL Use QWL_USER
14 24 May 05 SHL Rework Win_Error usage
15 25 May 05 SHL Use ULONGLONG and CommaFmtULL
16 26 May 05 SHL More large file formatting updates
17 05 Jun 05 SHL Use QWL_USER
18 10 Nov 05 SHL Comments
19 13 Jul 06 SHL Use Runtime_Error
20 26 Jul 06 SHL Use chop_at_crnl
21 15 Aug 06 SHL Rework warning message text
22 07 Jan 07 GKY Move error strings etc. to string file
23 30 Mar 07 GKY Remove GetPString for window class names
24 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
25 06 Apr 07 GKY Add some error checking in drag/drop
26 19 Apr 07 SHL Use FreeDragInfoData. Add more drag/drop error checking.
27 12 May 07 SHL Use dcd->ulItemsToUnHilite; sync with UnHilite arg mods
28 10 Jun 07 GKY Add CheckPmDrgLimit including IsFm2Window as part of work around PM drag limit
29 02 Aug 07 SHL Sync with CNRITEM mods
30 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
31 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
32 26 Aug 07 GKY DosSleep(1) in loops changed to (0)
33 22 Nov 07 GKY Use CopyPresParams to fix presparam inconsistencies in menus
34 10 Jan 08 SHL Sync with CfgDlgProc mods
35 19 Jan 08 JBS Ticket 150: fix/improve save and restore of dir cnr state at FM/2 close/reopen
36 15 Feb 08 SHL Sync with settings menu rework
37 22 Feb 08 JBS Ticket 230: Fix/improve various code related to state or presparam values in the INI file.
38 11 May 08 GKY Avoid using stale dcd after free
39 11 May 08 SHL Add stale dcd sanity checks
40 21 Jun 08 GKY Fix columns to honor preferences on new container open.
41 22 Jun 08 GKY Included free_... functions for fortify checking
42 06 Jul 08 GKY Update delete/undelete to include move to and open XWP trashcan
43 11 Jul 08 JBS Ticket 230: Simplified code and eliminated some local variables by incorporating
44 all the details view settings (both the global variables and those in the
45 DIRCNRDATA struct) into a new struct: DETAILS_SETTINGS.
46 20 Jul 08 GKY Add save/append filename to clipboard.
47 Change menu wording to make these easier to find
48 02 Aug 08 GKY Always pass temp variable point to treecnr UM_SHOWME to avoid
49 freeing dcd->directory early
50 25 Aug 08 GKY Check TMP directory space warn if lee than 5 MiB prevent archiver from opening if
51 less than 10 KiB (It hangs and can't be closed)
52 29 Nov 08 GKY Remove or replace with a mutex semaphore DosEnterCriSec where appropriate.
53 10 Dec 08 SHL Integrate exception handler support
54 26 Dec 08 GKY Fixed DROPHELP to check for copy as default is action is DO_DEFAULT
55 01 Jan 09 GKY Add Seek and Scan to drives & directory context menus pass drive/dir as search root
56 07 Feb 09 GKY Eliminate Win_Error2 by moving function names to PCSZs used in Win_Error
57 07 Feb 09 GKY Move repeated strings to PCSZs.
58 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
59 07 Feb 09 GKY Add *DateFormat functions to format dates based on locale
60 08 Mar 09 GKY Renamed commafmt.h i18nutil.h
61 08 Mar 09 GKY Additional strings move to PCSZs in init.c
62 12 Mar 09 SHL Use common SearchContainer
63 14 Mar 09 GKY Prevent execution of UM_SHOWME while drive scan is occuring
64 29 Mar 09 SHL Keep more keys away from PM if extended search in progress
65 29 Mar 09 SHL Increase extended search timeout to 3 seconds
66 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
67 22 Jul 09 GKY Code changes to use semaphores to serialize drive scanning
68 22 Jul 09 SHL Cleanup of SETFOCUS code
69 14 Sep 09 SHL Drop experimental code
70 15 Sep 09 SHL Show rescan progress while filling container
71 13 Dec 09 GKY Fixed separate paramenters. Please note that appname should be used in
72 profile calls for user settings that work and are setable in more than one
73 miniapp; FM3Str should be used for setting only relavent to FM/2 or that
74 aren't user settable; realappname should be used for setting applicable to
75 one or more miniapp but not to FM/2
76 17 Jan 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10).
77 Mostly cast CHAR CONSTANT * as CHAR *.
78 28 May 10 GKY Yet another attempt to prevent duplicate directory names in the tree by
79 suppressing SHOW_ME during initial drive scan.
80 20 Nov 10 GKY Rework scanning code to remove redundant scans, prevent double directory
81 entries in the tree container, fix related semaphore performance using
82 combination of event and mutex semaphores
83 04 Aug 12 GKY Changes to use Unlock to unlock files if Unlock.exe is in path both from menu/toolbar and as part of
84 copy, move and delete operations
85 22 Feb 14 GKY Fix warn readonly yes don't ask to work when recursing directories.
86 02 Mar 14 GKY Speed up intial drive scans Ticket 528
87 26 Jun 14 SHL Rework DirObjWndProc UM_RESCAN to avoid hanging FM/2 Lite when tree hidden
88 30 Aug 14 GKY Add semaphore hmtxFiltering to prevent freeing dcd while filtering. Prevents
89 a trap when FM2 is shutdown while directory containers are still populating
90 02 May 15 GKY Changes to allow a JAVA executable object to be created using "Real object"
91 menu item on a jar file.
92 02 Aug 15 GKY Remove unneed SubbyScan code and improve suppression of blank lines and
93 duplicate subdirectory name caused by running Stubby in worker threads.
94 07 Aug 15 SHL Rework to use AddFleshWorkRequest rather than direct calls to Stubby/Flesh/Unflesh
95 26 Sep 15 GKY Add code so case UM_TOPDIR actually exists put it in the object window so it
96 can call WaitFleshWorkListEmpty while avoiding thread 1
97 27 Sep 15 GKY DosSleep times in WaitFleshWorkListEmpty set by caller
98
99***********************************************************************/
100
101#include <stdlib.h>
102#include <string.h>
103#include <ctype.h>
104#include <limits.h>
105
106#define INCL_DOS
107#define INCL_WIN
108#define INCL_DOSERRORS
109#define INCL_LONGLONG
110#define INCL_WINWORKPLACE
111
112#include "fm3dll.h"
113#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
114#include "mainwnd2.h" // Data declaration(s)
115#include "grep.h" // Data declaration(s)
116#include "info.h" // Data declaration(s)
117#include "treecnr.h" // Data declaration(s)
118#include "dircnrs.h" // Data declaration(s)
119#include "init.h" // Data declaration(s)
120#include "fm3dlg.h"
121#include "fm3str.h"
122#include "mle.h"
123#include "arccnrs.h" // StartArcCnr
124#include "comp.h" // COMPARE
125#include "filldir.h" // EmptyCnr...
126#include "errutil.h" // Dos_Error...
127#include "strutil.h" // GetPString
128#include "notebook.h" // CfgDlgProc
129#include "command.h" // RunCommand
130#include "worker.h" // Action, MassAction
131#include "misc.h" // GetTidForThread, AdjustCnrColsForFSType, AdjustCnrColsForPref
132 // AdjustDetailsSwitches, CnrDirectEdit, OpenEdit, QuickPopup
133 // SayFilter, SaySort, SayView, SetCnrCols, SetDetailsSwitches
134 // SetSortChecks, SetViewMenu, SwitchCommand, CheckMenu
135 // CurrentRecord, DrawTargetEmphasis, IsFm2Window
136#include "chklist.h" // CenterOverWindow, DropListProc
137#include "common.h" // CommonCnrProc, CommonCreateTextChildren, CommonFrameWndProc
138 // CommonTextPaint, CommonTextButton, CommonTextProc
139#include "mainwnd.h" // CountDirCnrs, GetNextWindowPos, MakeBubble, TopWindow
140#include "select.h" // DeselectAll, HideAll, InvertAll, SelectAll, SelectList
141 // SpecialSelect2
142#include "dirsize.h" // DirSizeProc
143#include "flesh.h" // AddFleshWorkRequest
144#include "valid.h" // IsValidDir
145#include "objwin.h" // MakeObjWin
146#include "notify.h" // NotifyError
147#include "objcnr.h" // ObjCnrDlgProc
148#include "draglist.h" // DoFileDrag, FreeDragInfoData, PickUp
149#include "saveclip.h" // SaveListDlgProc
150#include "findrec.h" // ShowCnrRecord
151#include "sortcnr.h" // SortDirCnr
152#include "seeall.h" // StartSeeAll
153#include "update.h" // UpdateCnrList, UpdateCnrRecord
154#include "walkem.h" // add_udir
155#include "strips.h" // chop_at_crnl
156#include "droplist.h" // AcceptOneDrop, CheckPmDrgLimit, DropHelp, GetOneDrop
157#include "presparm.h" // CopyPresParams
158#include "defview.h" // DefaultViewKeys
159#include "systemf.h" // ExecOnList
160#include "filter.h" // Filter
161#include "findrec.h" // FindCnrRecord
162#include "input.h" // InputDlgProc
163#include "shadow.h" // OpenObject
164#include "mkdir.h" // PMMkDir
165#include "collect.h" // StartCollector
166#include "viewer.h" // StartMLEEditor
167#include "newview.h" // StartViewer
168#include "undel.h" // UndeleteDlgProc
169#include "i18nutil.h" // commafmt
170#include "getnames.h" // insert_filename
171#include "wrappers.h" // xfree
172#include "fortify.h"
173#include "excputil.h" // 06 May 08 SHL added
174#include "pathutil.h" // AddBackslashToPath
175#include "copyf.h" // ignorereadonly
176
177#ifdef PMPRINTF
178#define _PMPRINTF_ // Enable debug macros
179#include "PMPRINTF.H"
180#endif
181
182// Data definitions
183#pragma data_seg(GLOBAL1)
184HWND DirCnrMenu;
185HWND hwndAttr;
186HWND hwndDate;
187
188#pragma data_seg(GLOBAL2)
189INT sortFlags;
190
191#pragma data_seg(DATA1)
192
193static PSZ pszSrcFile = __FILE__;
194
195MRESULT EXPENTRY DirFrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
196{
197 return CommonFrameWndProc(DIR_CNR, hwnd, msg, mp1, mp2);
198}
199
200MRESULT EXPENTRY DirTextProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
201{
202 static BOOL emphasized = FALSE;
203 static HWND hwndButtonPopup = (HWND) 0;
204 static USHORT lastid = 0;
205 static ULONG timestamp = ULONG_MAX;
206
207 switch (msg) {
208 case WM_CREATE:
209 return CommonTextProc(hwnd, msg, mp1, mp2);
210
211 case WM_COMMAND:
212 {
213 DIRCNRDATA *dcd;
214 MRESULT mr;
215
216 mr = WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd,
217 QW_PARENT),
218 DIR_CNR), msg, mp1, mp2);
219 if (hwndButtonPopup &&
220 SHORT1FROMMP(mp1) > IDM_DETAILSTITLES &&
221 SHORT1FROMMP(mp1) < IDM_DETAILSSETUP) {
222 dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
223 QW_PARENT),
224 DIR_CNR), QWL_USER);
225 if (dcd)
226 SetDetailsSwitches(hwndButtonPopup, &dcd->ds);
227 }
228 return mr;
229 }
230
231 case UM_CONTEXTMENU:
232 case WM_CONTEXTMENU:
233 {
234 USHORT id;
235
236 id = WinQueryWindowUShort(hwnd, QWS_ID);
237 switch (id) {
238 case DIR_FOLDERICON:
239 if (fNoFoldMenu) {
240 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
241 DIR_CNR),
242 WM_COMMAND, MPFROM2SHORT(IDM_PREVIOUS, 0), mp2);
243 break;
244 }
245 // else intentional fallthru
246 case DIR_SELECTED:
247 case DIR_VIEW:
248 case DIR_SORT:
249 {
250 POINTL ptl = { 0, 0 };
251 SWP swp;
252 DIRCNRDATA *dcd;
253
254 if (hwndButtonPopup)
255 WinDestroyWindow(hwndButtonPopup);
256 if (id == DIR_SELECTED && msg == WM_CONTEXTMENU)
257 id = DIR_MAX;
258 if (id == lastid) {
259
260 ULONG check;
261
262 DosQuerySysInfo(QSV_MS_COUNT,
263 QSV_MS_COUNT, &check, sizeof(check));
264 if (check < timestamp + 500) {
265 lastid = 0;
266 goto MenuAbort;
267 }
268 }
269 hwndButtonPopup = WinLoadMenu(HWND_DESKTOP, FM3ModHandle, id);
270 CopyPresParams(hwndButtonPopup, hwnd);
271 if (hwndButtonPopup) {
272 WinSetWindowUShort(hwndButtonPopup, QWS_ID, id);
273 dcd = WinQueryWindowPtr(WinWindowFromID(WinQueryWindow(hwnd,
274 QW_PARENT),
275 DIR_CNR), QWL_USER);
276 if (id == DIR_SORT) { // don't have sort pathname in dirs
277 WinSendMsg(hwndButtonPopup,
278 MM_DELETEITEM,
279 MPFROM2SHORT(IDM_SORTNAME, FALSE), MPVOID);
280 WinSendMsg(hwndButtonPopup,
281 MM_DELETEITEM,
282 MPFROM2SHORT(IDM_SORTNONE, FALSE), MPVOID);
283 if (dcd)
284 SetSortChecks(hwndButtonPopup, dcd->sortFlags);
285 }
286 else if (id == DIR_VIEW) {
287 if (dcd) {
288 SetViewMenu(hwndButtonPopup, dcd->flWindowAttr);
289 SetDetailsSwitches(hwndButtonPopup, &dcd->ds);
290 }
291 }
292 else if (id == DIR_MAX) {
293
294 int x;
295 BOOL enable;
296 USHORT ids[] = { IDM_SELECTBOTH,
297 IDM_SELECTMORE,
298 IDM_SELECTONE,
299 IDM_SELECTNEWER,
300 IDM_SELECTOLDER,
301 IDM_SELECTBIGGER,
302 IDM_SELECTSMALLER,
303 IDM_DESELECTBOTH,
304 IDM_DESELECTMORE,
305 IDM_DESELECTONE,
306 IDM_DESELECTNEWER,
307 IDM_DESELECTOLDER,
308 IDM_DESELECTBIGGER,
309 IDM_DESELECTSMALLER,
310 0
311 };
312
313 enable = (CountDirCnrs(dcd->hwndParent) > 1);
314 for (x = 0; ids[x]; x++)
315 WinEnableMenuItem(hwndButtonPopup, ids[x], enable);
316 }
317 else if (id == DIR_SELECTED) {
318 if (dcd)
319 WinEnableMenuItem(hwndButtonPopup,
320 IDM_RESELECT, (dcd->lastselection != NULL));
321 }
322 ptl.x = 0;
323 if (WinPopupMenu(HWND_OBJECT,
324 HWND_OBJECT,
325 hwndButtonPopup, -32767, -32767, 0, 0)) {
326 WinQueryWindowPos(hwndButtonPopup, &swp);
327 ptl.y = -(swp.cy + 2);
328 }
329 else {
330 WinQueryWindowPos(hwnd, &swp);
331 ptl.y = swp.cy + 2;
332 }
333 if (WinPopupMenu(hwnd,
334 hwnd,
335 hwndButtonPopup,
336 ptl.x,
337 ptl.y,
338 0,
339 PU_HCONSTRAIN | PU_VCONSTRAIN |
340 PU_KEYBOARD | PU_MOUSEBUTTON1)) {
341 CenterOverWindow(hwndButtonPopup);
342 PaintRecessedWindow(hwnd, (HPS) 0, FALSE, FALSE);
343 }
344 }
345 }
346 break;
347 default:
348 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), DIR_CNR),
349 WM_CONTROL, MPFROM2SHORT(DIR_CNR, CN_CONTEXTMENU), MPVOID);
350 break;
351 }
352 } // case WM_CONTENT_MENU
353
354 MenuAbort:
355
356 if (msg == UM_CONTEXTMENU)
357 return 0;
358 break;
359
360 case WM_MENUEND:
361 if (hwndButtonPopup == (HWND) mp2) {
362 lastid = WinQueryWindowUShort((HWND) mp2, QWS_ID);
363 WinDestroyWindow(hwndButtonPopup);
364 hwndButtonPopup = (HWND) 0;
365 DosQuerySysInfo(QSV_MS_COUNT,
366 QSV_MS_COUNT, &timestamp, sizeof(timestamp));
367 switch (lastid) {
368 case DIR_VIEW:
369 case DIR_SORT:
370 case DIR_FOLDERICON:
371 case DIR_SELECTED:
372 case DIR_MAX:
373 PaintRecessedWindow(hwnd, (HPS) 0, TRUE, FALSE);
374 break;
375 }
376 }
377 break;
378
379 case WM_BUTTON3DOWN:
380 case WM_BUTTON1DOWN:
381 case WM_BUTTON3UP:
382 case WM_BUTTON1UP:
383 {
384 USHORT id;
385
386 id = WinQueryWindowUShort(hwnd, QWS_ID);
387 switch (id) {
388 case DIR_FILTER:
389 case DIR_VIEW:
390 case DIR_SORT:
391 case DIR_SELECTED:
392 case DIR_FOLDERICON:
393 case DIR_MAX:
394 return CommonTextButton(hwnd, msg, mp1, mp2);
395 }
396 }
397 break;
398
399 case WM_BUTTON1DBLCLK:
400 {
401 NOTIFYRECORDENTER nr;
402
403 if (WinQueryWindowUShort(hwnd, QWS_ID) != DIR_FOLDERICON) {
404 memset(&nr, 0, sizeof(NOTIFYRECORDENTER));
405 nr.hwndCnr = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), DIR_CNR);
406 WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
407 WM_CONTROL, MPFROM2SHORT(DIR_CNR, CN_ENTER), MPFROMP(&nr));
408 }
409 }
410 break;
411
412 case WM_MOUSEMOVE:
413 {
414 USHORT id = WinQueryWindowUShort(hwnd, QWS_ID);
415 PCSZ s = NULL;
416
417 if (fOtherHelp) {
418 if ((!hwndBubble ||
419 WinQueryWindowULong(hwndBubble, QWL_USER) != hwnd) &&
420 !WinQueryCapture(HWND_DESKTOP)) {
421 switch (id) {
422 case DIR_TOTALS:
423 s = GetPString(IDS_DIRCNRTOTALHELP);
424 break;
425 case DIR_SELECTED:
426 s = GetPString(IDS_DIRCNRSELECTEDHELP);
427 break;
428 case DIR_VIEW:
429 s = GetPString(IDS_DIRCNRVIEWHELP);
430 break;
431 case DIR_SORT:
432 s = GetPString(IDS_DIRCNRSORTHELP);
433 break;
434 case DIR_FILTER:
435 s = GetPString(IDS_DIRCNRFILTERHELP);
436 break;
437 case DIR_MAX:
438 s = GetPString(IDS_DIRCNRMAXHELP);
439 break;
440 case DIR_FOLDERICON:
441 s = GetPString(IDS_DIRCNRFOLDERHELP);
442 break;
443 default:
444 break;
445 }
446 if (s)
447 MakeBubble(hwnd, TRUE, s);
448 else if (hwndBubble)
449 WinDestroyWindow(hwndBubble);
450 }
451 }
452 switch (id) {
453 case DIR_MAX:
454 case DIR_FOLDERICON:
455 case DIR_FILTER:
456 case DIR_SORT:
457 case DIR_VIEW:
458 case DIR_SELECTED:
459 return CommonTextButton(hwnd, msg, mp1, mp2);
460 }
461 }
462 break;
463
464 case WM_CHORD:
465 case WM_BUTTON3CLICK:
466 case WM_BUTTON1CLICK:
467 case UM_CLICKED:
468 case UM_CLICKED3:
469 {
470 USHORT id, cmd = 0;
471
472 id = WinQueryWindowUShort(hwnd, QWS_ID);
473 if (msg == UM_CLICKED || msg == UM_CLICKED3) {
474 switch (id) {
475 case DIR_MAX:
476 cmd = IDM_MAXIMIZE;
477 break;
478 case DIR_VIEW:
479 case DIR_SELECTED:
480 case DIR_SORT:
481 PostMsg(hwnd, UM_CONTEXTMENU, MPVOID, MPVOID);
482 break;
483 case DIR_FILTER:
484 cmd = IDM_FILTER;
485 break;
486 default:
487 break;
488 }
489 }
490 else if (id == DIR_FOLDERICON) {
491 if ((msg == WM_BUTTON1CLICK && (SHORT2FROMMP(mp2) & KC_CTRL)))
492 cmd = IDM_PREVIOUS;
493 else if (msg == WM_BUTTON3CLICK || msg == WM_CHORD)
494 cmd = IDM_RESCAN;
495 else if (msg == WM_BUTTON1CLICK && (SHORT2FROMMP(mp2) & KC_SHIFT))
496 cmd = IDM_WALKDIR;
497 else if (msg == WM_BUTTON1CLICK && (SHORT2FROMMP(mp2) & KC_ALT))
498 cmd = IDM_WINDOWDLG;
499 else
500 cmd = IDM_PARENT;
501 }
502 if (cmd)
503 PostMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
504 DIR_CNR),
505 WM_COMMAND, MPFROM2SHORT(cmd, 0), MPVOID);
506 }
507 if (msg == UM_CLICKED || msg == UM_CLICKED3)
508 return 0;
509 break;
510
511 case DM_DROP:
512 case DM_DRAGOVER:
513 case DM_DRAGLEAVE:
514 case DM_DROPHELP:
515 case WM_BEGINDRAG:
516 if (msg == DM_DRAGOVER) {
517 if (!emphasized) {
518 emphasized = TRUE;
519 DrawTargetEmphasis(hwnd, emphasized);
520 }
521 }
522 else if (msg != WM_BEGINDRAG) {
523 if (emphasized) {
524 emphasized = FALSE;
525 DrawTargetEmphasis(hwnd, emphasized);
526 }
527 }
528 switch (WinQueryWindowUShort(hwnd, QWS_ID)) {
529 case DIR_FOLDERICON:
530 switch (msg) {
531 case DM_DRAGOVER:
532 if (AcceptOneDrop(hwnd, mp1, mp2))
533 return MRFROM2SHORT(DOR_DROP, DO_MOVE);
534 return (MRFROM2SHORT(DOR_NODROP, 0)); // Drop not valid
535 case DM_DROPHELP:
536 DropHelp(mp1, mp2, hwnd, GetPString(IDS_DIRCNRFOLDERDROPHELP));
537 return 0;
538 case DM_DROP:
539 {
540 char szFrom[CCHMAXPATH + 2];
541
542 if (emphasized) {
543 emphasized = FALSE;
544 DrawTargetEmphasis(hwnd, emphasized);
545 }
546 if (GetOneDrop(hwnd, mp1, mp2, szFrom, sizeof(szFrom)))
547 WinSendMsg(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
548 DIR_CNR),
549 WM_COMMAND, MPFROM2SHORT(IDM_SWITCH, 0),
550 MPFROMP(szFrom));
551 }
552 return 0;
553 default:
554 return PFNWPStatic(hwnd, msg, mp1, mp2);
555 }
556 case DIR_MAX:
557 if (msg == WM_BEGINDRAG)
558 return PFNWPStatic(hwnd, msg, mp1, mp2);
559 default:
560 {
561 CNRDRAGINFO cnd;
562 USHORT dcmd;
563
564 switch (msg) {
565 case DM_DROP:
566 dcmd = CN_DROP;
567 break;
568 case DM_DRAGOVER:
569 dcmd = CN_DRAGOVER;
570 break;
571 case DM_DRAGLEAVE:
572 dcmd = CN_DRAGLEAVE;
573 break;
574 case DM_DROPHELP:
575 dcmd = CN_DROPHELP;
576 break;
577 case WM_BEGINDRAG:
578 dcmd = CN_INITDRAG;
579 break;
580 }
581 memset(&cnd, 0, sizeof(cnd));
582 cnd.pDragInfo = (PDRAGINFO) mp1;
583 cnd.pRecord = NULL;
584 return WinSendMsg(WinQueryWindow(hwnd, QW_PARENT),
585 WM_CONTROL,
586 MPFROM2SHORT(DIR_CNR, dcmd), MPFROMP(&cnd));
587 }
588 }
589 }
590 return PFNWPStatic(hwnd, msg, mp1, mp2);
591}
592
593MRESULT EXPENTRY DirClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1,
594 MPARAM mp2)
595{
596 switch (msg) {
597 case UM_CONTAINERDIR:
598 if (mp1) {
599
600 DIRCNRDATA *dcd;
601
602 *(CHAR *)mp1 = 0;
603 dcd = WinQueryWindowPtr(WinWindowFromID(hwnd, DIR_CNR), QWL_USER);
604 if (dcd)
605 strcpy((CHAR *)mp1, dcd->directory);
606 return MRFROMLONG(TRUE);
607 }
608 return 0;
609
610 case UM_CONTAINERHWND:
611 return MRFROMLONG(WinWindowFromID(hwnd, DIR_CNR));
612
613 case UM_VIEWSMENU:
614 return MRFROMLONG(CheckMenu(hwnd, &DirCnrMenu, DIRCNR_POPUP));
615
616 case UM_DRIVECMD:
617 case WM_INITMENU:
618 case UM_FILTER:
619 case UM_INITMENU:
620 case MM_PORTHOLEINIT:
621 case UM_COMMAND:
622 case UM_FILESMENU:
623 case UM_UPDATERECORD:
624 case UM_UPDATERECORDLIST:
625 return WinSendMsg(WinWindowFromID(hwnd, DIR_CNR), msg, mp1, mp2);
626
627 case WM_PSETFOCUS:
628 case WM_SETFOCUS:
629 if (mp2)
630 PostMsg(hwnd, UM_FOCUSME, MPVOID, MPVOID);
631 break;
632
633 case UM_FOCUSME:
634 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, DIR_CNR));
635 break;
636
637 case WM_PAINT:
638 {
639 HPS hps;
640 RECTL rcl;
641
642 hps = WinBeginPaint(hwnd, (HPS) 0, NULL);
643 if (hps) {
644 WinQueryWindowRect(hwnd, &rcl);
645 WinFillRect(hps, &rcl, CLR_PALEGRAY);
646 CommonTextPaint(hwnd, hps);
647 WinEndPaint(hps);
648 }
649 }
650 break;
651
652 case UM_SIZE:
653 case WM_SIZE:
654 if (msg == UM_SIZE) {
655
656 SWP swp;
657
658 WinQueryWindowPos(hwnd, &swp);
659 mp1 = MPFROM2SHORT(swp.cx, swp.cy);
660 mp2 = MPFROM2SHORT(swp.cx, swp.cy);
661 }
662 {
663 USHORT cx, cy, bx;
664
665 cx = SHORT1FROMMP(mp2);
666 cy = SHORT2FROMMP(mp2);
667 WinSetWindowPos(WinWindowFromID(hwnd, DIR_CNR), HWND_TOP,
668 0, 0, cx, cy - 24, SWP_SHOW | SWP_MOVE | SWP_SIZE);
669 if (WinWindowFromID(hwnd, DIR_MAX) != (HWND) 0) {
670 WinSetWindowPos(WinWindowFromID(hwnd, DIR_MAX), HWND_TOP,
671 cx - 22,
672 cy - 22, 20, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
673 cx -= 24;
674 }
675 WinSetWindowPos(WinWindowFromID(hwnd, DIR_FOLDERICON), HWND_TOP,
676 2, cy - 22, 24, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
677 WinSetWindowPos(WinWindowFromID(hwnd, DIR_TOTALS), HWND_TOP,
678 29,
679 cy - 22,
680 (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
681 WinSetWindowPos(WinWindowFromID(hwnd, DIR_SELECTED), HWND_TOP,
682 29 + (cx / 3) + 2,
683 cy - 22,
684 (cx / 3) - 2, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
685 bx = (cx - (29 + (((cx / 3) + 2) * 2))) / 3;
686 WinSetWindowPos(WinWindowFromID(hwnd, DIR_VIEW), HWND_TOP,
687 29 + (((cx / 3) + 2) * 2),
688 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
689 WinSetWindowPos(WinWindowFromID(hwnd, DIR_SORT), HWND_TOP,
690 29 + (((cx / 3) + 2) * 2) + bx,
691 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
692 WinSetWindowPos(WinWindowFromID(hwnd, DIR_FILTER), HWND_TOP,
693 29 + (((cx / 3) + 2) * 2) + (bx * 2),
694 cy - 22, bx - 4, 20, SWP_SHOW | SWP_MOVE | SWP_SIZE);
695 }
696 CommonTextPaint(hwnd, (HPS) 0);
697 if (msg == UM_SIZE) {
698 WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), HWND_TOP, 0, 0, 0, 0,
699 SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE);
700 return 0;
701 }
702 break;
703
704 case WM_COMMAND:
705 case WM_CONTROL:
706 case WM_CLOSE:
707 return WinSendMsg(WinWindowFromID(hwnd, DIR_CNR), msg, mp1, mp2);
708 }
709 return WinDefWindowProc(hwnd, msg, mp1, mp2);
710}
711
712MRESULT EXPENTRY DirObjWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
713{
714 DIRCNRDATA *dcd;
715 CHAR tf[64];
716 CHAR tb[64];
717 CHAR s[CCHMAXPATH * 2];
718
719 switch (msg) {
720 case WM_CREATE:
721 DbgMsg(pszSrcFile, __LINE__, "WM_CREATE mp1 %p mp2 %p", mp1, mp2); // 18 Jul 08 SHL fixme
722 break;
723
724 case DM_PRINTOBJECT:
725 return MRFROMLONG(DRR_TARGET);
726
727 case DM_DISCARDOBJECT:
728 dcd = INSTDATA(hwnd);
729 if (fFM2Deletes && dcd) {
730 LISTINFO *li;
731 CNRDRAGINFO cni;
732 cni.pRecord = NULL;
733 cni.pDragInfo = (PDRAGINFO) mp1;
734 li =
735 DoFileDrop(dcd->hwndCnr, dcd->directory, FALSE, MPVOID,
736 MPFROMP(&cni));
737 CheckPmDrgLimit(cni.pDragInfo);
738 if (li) {
739 li->type = (fDefaultDeletePerm) ? IDM_PERMDELETE : IDM_DELETE;
740 if (!PostMsg(hwnd, UM_MASSACTION, MPFROMP(li), MPVOID))
741 FreeListInfo(li);
742 else
743 return MRFROMLONG(DRR_SOURCE);
744 }
745 }
746 return MRFROMLONG(DRR_TARGET);
747
748 case UM_UPDATERECORDLIST:
749 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
750 if (dcd && mp1) {
751
752 INT numentries = 0;
753 CHAR **list = (CHAR **) mp1;
754
755 while (list[numentries])
756 numentries++;
757 if (numentries)
758 UpdateCnrList(dcd->hwndCnr, list, numentries, TRUE, dcd);
759 }
760 return 0;
761
762 case UM_SETUP:
763# ifdef FORTIFY
764 // DbgMsg(pszSrcFile, __LINE__, "UM_SETUP hwnd %p TID %u", hwnd, GetTidForThread()); // 18 Jul 08 SHL fixme
765 Fortify_EnterScope();
766# endif
767 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
768 if (dcd) {
769# ifdef FORTIFY
770 Fortify_BecomeOwner(dcd); // We free dcd
771 if (GetTidForThread())
772 Fortify_ChangeScope(dcd, -1);
773# endif
774 // set unique id
775 WinSetWindowUShort(hwnd, QWS_ID, DIROBJ_FRAME + (DIR_FRAME - dcd->id));
776 dcd->hwndObject = hwnd;
777 if (ParentIsDesktop(hwnd, dcd->hwndParent))
778 DosSleep(100);
779 }
780 else
781 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
782# ifdef FORTIFY
783 // TID 1 will free data
784 if (GetTidForThread())
785 Fortify_LeaveScope();
786# endif
787 return 0;
788
789 case UM_RESCAN2:
790 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
791 if (dcd && dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
792 FSALLOCATE fsa;
793 CHAR szFree[64];
794 DosError(FERR_DISABLEHARDERR);
795 if (!DosQueryFSInfo(toupper(*dcd->directory) - '@',
796 FSIL_ALLOC, &fsa, sizeof(FSALLOCATE))) {
797 CommaFmtULL(tb, sizeof(tb),
798 (ULONGLONG) fsa.cUnitAvail * (fsa.cSectorUnit *
799 fsa.cbSector), 'K');
800 sprintf(szFree, " {%s %s}", tb, GetPString(IDS_FREETEXT));
801 }
802 else
803 *szFree = 0;
804 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
805 commafmt(tf, sizeof(tf), dcd->totalfiles);
806 CommaFmtULL(tb, sizeof(tb), dcd->ullTotalBytes, ' ');
807 DosReleaseMutexSem(hmtxFiltering);
808 if (!fMoreButtons) {
809 sprintf(s, " [%s / %s]%s%s%s%s %s",
810 tf, tb, szFree,
811 (*dcd->mask.szMask || dcd->mask.antiattr ||
812 dcd->mask.attrFile != ALLATTRS) ? " (" : NullStr,
813 (*dcd->mask.szMask) ? dcd->mask.szMask :
814 (dcd->mask.antiattr ||
815 dcd->mask.attrFile != ALLATTRS) ?
816 GetPString(IDS_ALLTEXT) : NullStr,
817 (*dcd->mask.szMask || dcd->mask.antiattr ||
818 dcd->mask.attrFile != ALLATTRS) ? ")" : NullStr,
819 dcd->directory);
820 }
821 else {
822 sprintf(s, " [%s / %s]%s %s", tf, tb, szFree, dcd->directory);
823 }
824 if (dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent))
825 WinSetWindowText(hwndStatus, s);
826 }
827 return 0;
828
829 case UM_FLESH:
830 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
831 if (dcd) {
832
833 PCNRITEM pci, pciC;
834
835 pci = WinSendMsg(dcd->hwndCnr,
836 CM_QUERYRECORD,
837 MPVOID, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
838 while (pci && (INT) pci != -1) {
839 if (!pci->pszFileName || !strcmp(pci->pszFileName, NullStr)) {
840 Runtime_Error(pszSrcFile, __LINE__, "pci->pszFileName NULL for %p", pci);
841 return 0;
842 }
843 if (pci->attrFile & FILE_DIRECTORY) {
844 pciC = WinSendMsg(dcd->hwndCnr,
845 CM_QUERYRECORD,
846 MPFROMP(pci),
847 MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER));
848 if (!pciC) {
849 AddFleshWorkRequest(dcd->hwndCnr, pci, eStubby);
850 }
851 }
852 pci = WinSendMsg(dcd->hwndCnr,
853 CM_QUERYRECORD,
854 MPFROMP(pci), MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
855 }
856 dcd->firsttree = TRUE;
857 }
858 return 0;
859
860 case UM_TOPDIR:
861 if (mp1) {
862 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
863 if (dcd) {
864 PCNRITEM pci = (PCNRITEM) mp1;
865 WaitFleshWorkListEmpty(pci->pszFileName, 240L);
866 ShowCnrRecord(dcd->hwndCnr, (PMINIRECORDCORE) pci);
867 }
868 }
869 return 0;
870
871 case UM_RESCAN:
872 // populate container
873 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
874 if (dcd) {
875 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
876 if (dcd->stopflag)
877 dcd->stopflag--;
878 if (dcd->stopflag) {
879 DosReleaseMutexSem(hmtxFM2Globals);
880 return 0;
881 }
882 DosReleaseMutexSem(hmtxFM2Globals);
883 if (mp1) {
884 strcpy(dcd->previous, dcd->directory);
885 strcpy(dcd->directory, (CHAR *)mp1);
886 }
887 MakeValidDir(dcd->directory);
888 {
889 sprintf(s,
890 "%s%s%s",
891 (ParentIsDesktop(dcd->hwndFrame, (HWND) 0)) ?
892 "VDir" :
893 NullStr,
894 (ParentIsDesktop(dcd->hwndFrame, (HWND) 0)) ?
895 (!dcd->dontclose) ?
896 " Master: " : ": " : NullStr, dcd->directory);
897 WinSetWindowText(dcd->hwndFrame, s);
898 WinSetWindowText(WinWindowFromID(dcd->hwndFrame, FID_TITLEBAR), s);
899 }
900 RemoveCnrItems(dcd->hwndCnr, NULL, 0, CMA_FREE | CMA_INVALIDATE | CMA_ERASE);
901 AdjustCnrColsForFSType(dcd->hwndCnr, dcd->directory, &dcd->ds, FALSE);
902 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
903 dcd->ullTotalBytes = dcd->totalfiles = dcd->selectedfiles = dcd->selectedbytes = 0;
904 DosReleaseMutexSem(hmtxFiltering);
905 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, "0 / 0k");
906 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, "0 / 0k");
907 if (hwndStatus &&
908 dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
909 WinSetWindowText(hwndStatus, (CHAR *) GetPString(IDS_PLEASEWAITSCANNINGTEXT));
910 if (hwndMain)
911 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
912 }
913 // 2014-06-26 SHL FM/2 Lite may not have drive tree yet
914 if (hwndTree) {
915 // 2015-08-12 SHL Optimze to update drive tree for only last saved state
916 if (fSwitchTreeOnDirChg) {
917 // Keep drive tree in sync with directory container
918 PSZ pszTempDir;
919 pszTempDir = xstrdup(dcd->directory, pszSrcFile, __LINE__);
920 if (pszTempDir) {
921 if (hwndMain) {
922 if (TopWindow(hwndMain, (HWND)0) == dcd->hwndFrame) {
923 if (!PostMsg(hwndTree, UM_SHOWME, MPFROMP(pszTempDir), MPVOID))
924 free(pszTempDir);
925 }
926 }
927 else {
928 if (!PostMsg(hwndTree, UM_SHOWME, MPFROMP(pszTempDir), MPVOID))
929 free(pszTempDir);
930 }
931 }
932 } // fSwitchTreeOnDirChg
933 } // if hwndTree
934 dcd->firsttree = FALSE;
935 WinStartTimer(WinQueryAnchorBlock(hwnd), dcd->hwndCnr, ID_DIRCNR_TIMER, 500);
936 // fixme to check errors
937 FillDirCnr(dcd->hwndCnr, dcd->directory, dcd, &dcd->ullTotalBytes);
938 WinStopTimer(WinQueryAnchorBlock(hwnd), dcd->hwndCnr, ID_DIRCNR_TIMER);
939 PostMsg(dcd->hwndCnr, UM_RESCAN, MPVOID, MPVOID);
940 if (mp2 && !fLeaveTree && (dcd->flWindowAttr & CV_TREE)) {
941 ULONG flWindowAttr = dcd->flWindowAttr;
942 CNRINFO cnri;
943 flWindowAttr &= ~(CV_NAME | CV_TREE | CV_ICON | CV_DETAIL | CV_TEXT);
944 if (dcd->lastattr) {
945 if (dcd->lastattr & CV_TEXT)
946 flWindowAttr |= CV_TEXT;
947 else if (dcd->lastattr & CV_DETAIL)
948 flWindowAttr |= CV_DETAIL;
949 else if (dcd->lastattr & CV_ICON)
950 flWindowAttr |= CV_ICON;
951 else
952 flWindowAttr |= CV_NAME;
953 }
954 else
955 flWindowAttr |= CV_NAME;
956 flWindowAttr |= CV_FLOW;
957 memset(&cnri, 0, sizeof(CNRINFO));
958 cnri.cb = sizeof(CNRINFO);
959 if (WinSendMsg(dcd->hwndCnr, CM_QUERYCNRINFO, MPFROMP(&cnri),
960 MPFROMLONG(sizeof(CNRINFO)))) {
961 dcd->flWindowAttr = cnri.flWindowAttr = flWindowAttr;
962 WinSendMsg(dcd->hwndCnr, CM_SETCNRINFO,
963 MPFROMP(&cnri), MPFROMLONG(CMA_FLWINDOWATTR));
964 SayView(WinWindowFromID(dcd->hwndClient,
965 DIR_VIEW), dcd->flWindowAttr);
966 }
967 }
968 if (dcd->flWindowAttr & CV_TREE)
969 PostMsg(dcd->hwndObject, UM_FLESH, MPVOID, MPVOID);
970 if (*dcd->previous) {
971 if (strlen(dcd->previous) > strlen(dcd->directory) &&
972 !strnicmp(dcd->directory, dcd->previous,
973 strlen(dcd->directory)))
974 {
975 PCNRITEM pci = FindCnrRecord(dcd->hwndCnr,
976 dcd->previous,
977 NULL, TRUE, FALSE, TRUE);
978 if (pci && (INT) pci != -1) {
979 // make found item current (cursored) item
980 WinSendMsg(dcd->hwndCnr, CM_SETRECORDEMPHASIS, MPFROMP(pci),
981 MPFROM2SHORT(TRUE, CRA_CURSORED));
982 // make sure that record shows in viewport
983 ShowCnrRecord(dcd->hwndCnr, (PMINIRECORDCORE) pci);
984 }
985 }
986 }
987 }
988 return 0;
989
990 case UM_COMMAND:
991 if (mp1) {
992
993 LISTINFO *li = (LISTINFO *) mp1;
994
995 switch (li->type) {
996 case IDM_DOITYOURSELF:
997 case IDM_APPENDTOCLIP:
998 case IDM_APPENDTOCLIPFILENAME:
999 case IDM_SAVETOCLIP:
1000 case IDM_SAVETOCLIPFILENAME:
1001 case IDM_ARCHIVE:
1002 case IDM_ARCHIVEM:
1003 case IDM_VIEWTEXT:
1004 case IDM_VIEWBINARY:
1005 case IDM_VIEWARCHIVE:
1006 case IDM_VIEW:
1007 case IDM_EDITTEXT:
1008 case IDM_EDITBINARY:
1009 case IDM_EDIT:
1010 case IDM_OBJECT:
1011 case IDM_SHADOW:
1012 case IDM_SHADOW2:
1013 case IDM_JAVAEXE:
1014 case IDM_PRINT:
1015 case IDM_ATTRS:
1016 case IDM_DELETE:
1017 case IDM_PERMDELETE:
1018 case IDM_MCIPLAY:
1019 case IDM_UPDATE:
1020 if (li->type == IDM_DELETE)
1021 ignorereadonly = FALSE;
1022 if (PostMsg(hwnd, UM_MASSACTION, mp1, mp2))
1023 return (MRESULT) TRUE;
1024 break;
1025 default:
1026 if (PostMsg(hwnd, UM_ACTION, mp1, mp2))
1027 return (MRESULT) TRUE;
1028 }
1029 }
1030 return 0;
1031
1032 case UM_SELECT:
1033 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1034 if (dcd) {
1035 switch (SHORT1FROMMP(mp1)) {
1036 case IDM_SELECTBOTH:
1037 case IDM_SELECTONE:
1038 case IDM_SELECTMORE:
1039 case IDM_SELECTNEWER:
1040 case IDM_SELECTOLDER:
1041 case IDM_SELECTBIGGER:
1042 case IDM_SELECTSMALLER:
1043 case IDM_DESELECTBOTH:
1044 case IDM_DESELECTONE:
1045 case IDM_DESELECTMORE:
1046 case IDM_DESELECTNEWER:
1047 case IDM_DESELECTOLDER:
1048 case IDM_DESELECTBIGGER:
1049 case IDM_DESELECTSMALLER:
1050 SpecialSelect2(dcd->hwndParent, SHORT1FROMMP(mp1));
1051 break;
1052 case IDM_SELECTLIST:
1053 {
1054 CHAR filename[CCHMAXPATH], *p, *pp;
1055 ULONG size;
1056
1057 strcpy(filename, PCSZ_STARDOTLST);
1058 size = CCHMAXPATH;
1059 PrfQueryProfileData(fmprof, appname, "SaveToListName",
1060 filename, &size);
1061 pp = strrchr(filename, '\\');
1062 if (!pp)
1063 pp = filename;
1064 p = strrchr(pp, '.');
1065 if (p && *(p + 1) && p > pp + 1) {
1066 if (pp > filename)
1067 pp++;
1068 *pp = '*';
1069 pp++;
1070 if (p > pp)
1071 memmove(pp, p, strlen(p) + 1);
1072 }
1073 if (insert_filename(hwnd, filename, FALSE, FALSE))
1074 SelectList(dcd->hwndCnr, TRUE, FALSE, FALSE, NULL, filename,
1075 NULL);
1076 }
1077 break;
1078 case IDM_SELECTALL:
1079 SelectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, FALSE);
1080 break;
1081 case IDM_DESELECTALL:
1082 DeselectAll(dcd->hwndCnr, TRUE, TRUE, NULL, NULL, FALSE);
1083 break;
1084 case IDM_SELECTALLFILES:
1085 SelectAll(dcd->hwndCnr, TRUE, FALSE, NULL, NULL, FALSE);
1086 break;
1087 case IDM_DESELECTALLFILES:
1088 DeselectAll(dcd->hwndCnr, TRUE, FALSE, NULL, NULL, FALSE);
1089 break;
1090 case IDM_SELECTALLDIRS:
1091 SelectAll(dcd->hwndCnr, FALSE, TRUE, NULL, NULL, FALSE);
1092 break;
1093 case IDM_DESELECTALLDIRS:
1094 DeselectAll(dcd->hwndCnr, FALSE, TRUE, NULL, NULL, FALSE);
1095 break;
1096 case IDM_DESELECTMASK:
1097 case IDM_SELECTMASK:
1098 {
1099 MASK mask;
1100 PCNRITEM pci = (PCNRITEM) mp2;
1101
1102 memset(&mask, 0, sizeof(MASK));
1103 mask.fNoAttribs = TRUE;
1104 mask.fNoDirs = TRUE;
1105 mask.fText = TRUE;
1106 strcpy(mask.prompt,
1107 GetPString((SHORT1FROMMP(mp1) == IDM_SELECTMASK) ?
1108 IDS_SELECTFILTERTEXT : IDS_DESELECTFILTERTEXT));
1109 if (pci && (INT) pci != -1)
1110 strcpy(mask.szMask, pci->pszFileName);
1111 if (WinDlgBox(HWND_DESKTOP,
1112 dcd->hwndCnr,
1113 PickMaskDlgProc,
1114 FM3ModHandle, MSK_FRAME, MPFROMP(&mask))) {
1115 if (SHORT1FROMMP(mp1) == IDM_SELECTMASK)
1116 SelectAll(dcd->hwndCnr,
1117 TRUE, TRUE, mask.szMask, mask.szText, FALSE);
1118 else
1119 DeselectAll(dcd->hwndCnr,
1120 TRUE, TRUE, mask.szMask, mask.szText, FALSE);
1121 }
1122 }
1123 break;
1124
1125 case IDM_DESELECTCLIP:
1126 case IDM_SELECTCLIP:
1127 {
1128 CHAR **list;
1129
1130 list = ListFromClipboard(hwnd);
1131 if (list) {
1132 SelectList(dcd->hwndCnr, TRUE, FALSE,
1133 (SHORT1FROMMP(mp1) == IDM_DESELECTCLIP),
1134 NULL, NULL, list);
1135 FreeList(list);
1136 }
1137 }
1138 break;
1139
1140 case IDM_INVERT:
1141 InvertAll(dcd->hwndCnr);
1142 break;
1143 }
1144 }
1145 return 0;
1146
1147 case UM_MASSACTION:
1148 if (mp1) {
1149 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1150 if (dcd) {
1151 WORKER *wk;
1152# ifdef FORTIFY
1153 Fortify_EnterScope();
1154# endif
1155 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
1156 if (!wk)
1157 FreeListInfo((LISTINFO *) mp1);
1158 else {
1159 wk->size = sizeof(WORKER);
1160 wk->hwndCnr = dcd->hwndCnr;
1161 wk->hwndParent = dcd->hwndParent;
1162 wk->hwndFrame = dcd->hwndFrame;
1163 wk->hwndClient = dcd->hwndClient;
1164 wk->li = (LISTINFO *) mp1;
1165 strcpy(wk->directory, dcd->directory);
1166 if (xbeginthread(MassAction,
1167 122880,
1168 wk,
1169 pszSrcFile,
1170 __LINE__) == -1)
1171 {
1172 free(wk);
1173 FreeListInfo((LISTINFO *)mp1);
1174 }
1175 }
1176# ifdef FORTIFY
1177 DosSleep(1); // Allow MassAction to take ownership
1178 Fortify_LeaveScope();
1179# endif
1180 }
1181 }
1182 return 0;
1183
1184 case UM_ACTION:
1185 if (mp1) {
1186
1187 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1188 if (dcd) {
1189
1190 WORKER *wk;
1191# ifdef FORTIFY
1192 Fortify_EnterScope();
1193# endif
1194 wk = xmallocz(sizeof(WORKER), pszSrcFile, __LINE__);
1195 if (!wk)
1196 FreeListInfo((LISTINFO *) mp1);
1197 else {
1198 wk->size = sizeof(WORKER);
1199 wk->hwndCnr = dcd->hwndCnr;
1200 wk->hwndParent = dcd->hwndParent;
1201 wk->hwndFrame = dcd->hwndFrame;
1202 wk->hwndClient = dcd->hwndClient;
1203 wk->li = (LISTINFO *) mp1;
1204 strcpy(wk->directory, dcd->directory);
1205
1206 if (xbeginthread(Action,
1207 122880,
1208 wk,
1209 pszSrcFile,
1210 __LINE__) == -1)
1211 {
1212 Runtime_Error(pszSrcFile, __LINE__,
1213 GetPString(IDS_COULDNTSTARTTHREADTEXT));
1214 free(wk);
1215 FreeListInfo((LISTINFO *) mp1);
1216 }
1217 }
1218# ifdef FORTIFY
1219 Fortify_LeaveScope();
1220# endif
1221 }
1222 }
1223 return 0;
1224
1225 case WM_CLOSE:
1226 WinDestroyWindow(hwnd);
1227 break;
1228
1229 case WM_DESTROY:
1230# ifdef FORTIFY
1231 DbgMsg(pszSrcFile, __LINE__, "WM_DESTROY hwnd %p TID %u", hwnd, GetTidForThread()); // 18 Jul 08 SHL fixme
1232# endif
1233 dcd = WinQueryWindowPtr(hwnd, QWL_USER);
1234 if (!dcd)
1235 Runtime_Error(pszSrcFile, __LINE__, NULL);
1236 else {
1237 if (dcd->hwndRestore)
1238 WinSetWindowPos(dcd->hwndRestore,
1239 HWND_TOP,
1240 0,
1241 0,
1242 0,
1243 0,
1244 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
1245 FreeList(dcd->lastselection);
1246 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, NULL); // 13 Apr 10 SHL Set NULL before freeing dcd
1247 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
1248 xfree(dcd, pszSrcFile, __LINE__);
1249 dcd = NULL;
1250 DosReleaseMutexSem(hmtxFiltering);
1251 DosPostEventSem(CompactSem);
1252 }
1253# ifdef FORTIFY
1254 Fortify_LeaveScope();
1255# endif
1256 // 22 Jul 08 SHL fixme to understand
1257 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
1258 WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
1259 break;
1260 }
1261 return WinDefWindowProc(hwnd, msg, mp1, mp2);
1262}
1263
1264MRESULT EXPENTRY DirCnrWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1265{
1266 DIRCNRDATA *dcd = INSTDATA(hwnd);
1267 CHAR tf[64];
1268 CHAR tb[64];
1269 CHAR s[CCHMAXPATH];
1270
1271 switch (msg) {
1272 case WM_CREATE:
1273# ifdef FORTIFY
1274 Fortify_EnterScope();
1275# endif
1276 break;
1277
1278 case DM_PRINTOBJECT:
1279 return MRFROMLONG(DRR_TARGET);
1280
1281 case DM_DISCARDOBJECT:
1282 if (dcd)
1283 return WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
1284 else
1285 return MRFROMLONG(DRR_TARGET);
1286
1287 case WM_CHAR:
1288 shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
1289 if (SHORT1FROMMP(mp1) & KC_KEYUP)
1290 return (MRESULT) TRUE;
1291 if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
1292 switch (SHORT2FROMMP(mp2)) {
1293 case VK_INSERT:
1294 if ((shiftstate & KC_CTRL) == KC_CTRL)
1295 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_MKDIR, 0), MPVOID);
1296 // Alt-Insert - create file
1297 else if ((shiftstate & KC_ALT) == KC_ALT)
1298 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_CREATE, 0), MPVOID);
1299 break;
1300 case VK_PAGEUP:
1301 if ((shiftstate & KC_CTRL) == KC_CTRL)
1302 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PARENT, 0), MPVOID);
1303 break;
1304 case VK_PAGEDOWN:
1305 if ((shiftstate & KC_CTRL) == KC_CTRL)
1306 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PREVIOUS, 0), MPVOID);
1307 break;
1308 case VK_HOME:
1309 if ((shiftstate & KC_CTRL) == KC_CTRL && dcd) {
1310 PSZ p;
1311 strcpy(s, dcd->directory);
1312 p = strchr(s, '\\');
1313 if (p) {
1314 p++;
1315 *p = 0;
1316 WinSendMsg(hwnd, UM_SETDIR, MPFROMP(s), MPVOID);
1317 }
1318 }
1319 break;
1320 case VK_DELETE:
1321 if ((shiftstate & KC_CTRL) == KC_CTRL)
1322 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PERMDELETE, 0), MPVOID);
1323 else if ((shiftstate & KC_SHIFT) == KC_SHIFT)
1324 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_SAVETOCLIP, 0), MPVOID);
1325 else
1326 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DELETE, 0), MPVOID);
1327 break;
1328 } // switch
1329 }
1330
1331 if (SearchContainer(hwnd, msg, mp1, mp2))
1332 return (MRESULT)TRUE; // Avoid default handler
1333 break; // Let default handler see key too
1334
1335 case WM_MOUSEMOVE:
1336 case WM_BUTTON1UP:
1337 case WM_BUTTON2UP:
1338 case WM_BUTTON3UP:
1339 case WM_CHORD:
1340 shiftstate = (SHORT2FROMMP(mp2) & (KC_ALT | KC_SHIFT | KC_CTRL));
1341 break;
1342
1343 case WM_BUTTON1MOTIONEND:
1344 {
1345 CNRINFO cnri;
1346
1347 memset(&cnri, 0, sizeof(CNRINFO));
1348 cnri.cb = sizeof(CNRINFO);
1349 if (WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
1350 MPFROMLONG(sizeof(CNRINFO)))) {
1351 if (cnri.flWindowAttr & CV_DETAIL)
1352 PrfWriteProfileData(fmprof, appname, "CnrSplitBar",
1353 (PVOID) & cnri.xVertSplitbar, sizeof(LONG));
1354 }
1355 }
1356 break;
1357
1358 case UM_COMPARE:
1359 if (dcd && mp1 && mp2) {
1360
1361 COMPARE *cmp;
1362 CHAR *leftdir = (CHAR *)mp1, *rightdir = (CHAR *)mp2;
1363
1364 if (!IsFile(leftdir) && !IsFile(rightdir)) {
1365# ifdef FORTIFY
1366 Fortify_EnterScope();
1367# endif
1368 cmp = xmallocz(sizeof(COMPARE), pszSrcFile, __LINE__);
1369 if (cmp) {
1370 cmp->size = sizeof(COMPARE);
1371 strcpy(cmp->leftdir, leftdir);
1372 strcpy(cmp->rightdir, rightdir);
1373 cmp->hwndParent = dcd->hwndParent;
1374 cmp->dcd.hwndParent = dcd->hwndParent;
1375 WinDlgBox(HWND_DESKTOP,
1376 HWND_DESKTOP,
1377 CompareDlgProc, FM3ModHandle, COMP_FRAME, MPFROMP(cmp));
1378 }
1379# ifdef FORTIFY
1380 Fortify_LeaveScope();
1381# endif
1382 }
1383 }
1384 return 0;
1385
1386 case WM_PRESPARAMCHANGED:
1387 PresParamChanged(hwnd, PCSZ_DIRCNR, mp1, mp2);
1388 break;
1389
1390 case UM_UPDATERECORDLIST:
1391 if (dcd && mp1)
1392 WinSendMsg(dcd->hwndObject, msg, mp1, mp2);
1393 return 0;
1394
1395 case UM_UPDATERECORD:
1396 if (dcd && mp1) {
1397
1398 CHAR *filename;
1399
1400 filename = mp1;
1401 if (filename)
1402 UpdateCnrRecord(hwnd, filename, TRUE, dcd);
1403 }
1404 return 0;
1405
1406 case WM_SETFOCUS:
1407 // put name of our window (directory name) on status line
1408 if (mp2) {
1409 // Getting focus
1410 if (dcd && hwndStatus) {
1411 // put name of our window (directory name) on status line
1412 PCNRITEM pci = NULL;
1413 if (fAutoView && hwndMain) {
1414 pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
1415 MPFROMSHORT(CRA_CURSORED));
1416 if (pci && (INT) pci != -1 &&
1417 (!(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_SLOW)))
1418 WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
1419 else
1420 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1421 }
1422 if (*dcd->directory) {
1423 if (hwndMain)
1424 WinSendMsg(hwndMain,
1425 UM_SETUSERLISTNAME, MPFROMP(dcd->directory), MPVOID);
1426 else
1427 add_udir(FALSE, dcd->directory);
1428 }
1429
1430 if (hwndMain)
1431 PostMsg(hwndMain, UM_ADVISEFOCUS, MPFROMLONG(dcd->hwndFrame), MPVOID);
1432 }
1433
1434 LastDir = hwnd;
1435 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1436 // 2015-08-13 SHL
1437 if (fSwitchTreeOnFocus && hwndTree && dcd && *dcd->directory) {
1438 PSZ pszTempDir = xstrdup(dcd->directory, pszSrcFile, __LINE__);
1439 if (pszTempDir) {
1440 if (!PostMsg(hwndTree, UM_SHOWME, MPFROMP(pszTempDir), MPVOID))
1441 free(pszTempDir); // Failed
1442 }
1443 }
1444 }
1445 break;
1446
1447 case UM_SETDIR:
1448 if (dcd && mp1) {
1449
1450 CHAR fullname[CCHMAXPATH];
1451
1452 DosError(FERR_DISABLEHARDERR);
1453 if (!DosQueryPathInfo((CHAR *)mp1,
1454 FIL_QUERYFULLNAME, fullname, sizeof(fullname))) {
1455 if (stricmp(dcd->directory, fullname)) {
1456 strcpy(dcd->previous, dcd->directory);
1457 strcpy(dcd->directory, fullname);
1458 dcd->stopflag++;
1459 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
1460 strcpy(dcd->directory, dcd->previous);
1461 dcd->stopflag--;
1462 }
1463 else if (*dcd->directory) {
1464 if (hwndMain)
1465 WinSendMsg(hwndMain,
1466 UM_SETUSERLISTNAME, MPFROMP(dcd->directory), MPVOID);
1467 else
1468 add_udir(FALSE, dcd->directory);
1469 }
1470 }
1471 }
1472 }
1473 break;
1474
1475 case WM_TIMER:
1476 // Started/stopped by DirObjWndPro
1477 if (dcd) {
1478 commafmt(tb, sizeof(tb), dcd->totalfiles);
1479 CommaFmtULL(tf, sizeof(tf), dcd->ullTotalBytes, 'K');
1480 sprintf(s, "%s / %s", tb, tf);
1481 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, s);
1482 }
1483 break; // WM_TIMER
1484
1485 case UM_RESCAN:
1486 if (dcd) {
1487
1488 CNRINFO cnri;
1489 CHAR szDate[DATE_BUF_BYTES];
1490 PCNRITEM pci;
1491
1492 memset(&cnri, 0, sizeof(CNRINFO));
1493 cnri.cb = sizeof(CNRINFO);
1494 WinSendMsg(hwnd,
1495 CM_QUERYCNRINFO,
1496 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1497 cnri.pszCnrTitle = dcd->directory;
1498 WinSendMsg(hwnd,
1499 CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_CNRTITLE));
1500 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
1501 dcd->totalfiles = cnri.cRecords;
1502 commafmt(tb, sizeof(tb), dcd->totalfiles);
1503 CommaFmtULL(tf, sizeof(tf), dcd->ullTotalBytes, 'K');
1504 DosReleaseMutexSem(hmtxFiltering);
1505 sprintf(s, "%s / %s", tb, tf);
1506 WinSetDlgItemText(dcd->hwndClient, DIR_TOTALS, s);
1507 commafmt(tb, sizeof(tb), dcd->selectedfiles);
1508 CommaFmtULL(tf, sizeof(tf), dcd->selectedbytes, 'K');
1509 sprintf(s, "%s / %s", tb, tf);
1510 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
1511 if (hwndStatus &&
1512 dcd->hwndFrame == WinQueryActiveWindow(dcd->hwndParent)) {
1513 PostMsg(dcd->hwndObject, UM_RESCAN2, MPVOID, MPVOID);
1514 if ((fSplitStatus && hwndStatus2) || fMoreButtons) {
1515 pci = WinSendMsg(hwnd,
1516 CM_QUERYRECORDEMPHASIS,
1517 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1518 if (pci && (INT) pci != -1) {
1519 if (fSplitStatus && hwndStatus2) {
1520 CommaFmtULL(tb, sizeof(tb), pci->cbFile + pci->easize, ' ');
1521 if (!fMoreButtons) {
1522 DateFormat(szDate, pci->date);
1523 sprintf(s, " %s %s %02u%s%02u%s%02u [%s] %s",
1524 tb,
1525 szDate,
1526 pci->time.hours,
1527 TimeSeparator,
1528 pci->time.minutes,
1529 TimeSeparator,
1530 pci->time.seconds,
1531 pci->pszDispAttr, pci->pszFileName);
1532 }
1533 else {
1534 *tf = 0;
1535 if (pci->cbFile + pci->easize > 1024) {
1536 CommaFmtULL(tf, sizeof(tf), pci->cbFile + pci->easize, 'K');
1537 }
1538 sprintf(s,
1539 GetPString(IDS_STATUSSIZETEXT),
1540 tb, *tf ? " (" : NullStr, tf, *tf ? ")" : NullStr);
1541 }
1542 WinSetWindowText(hwndStatus2, s);
1543 }
1544 else
1545 WinSetWindowText(hwndStatus2, NullStr);
1546 if (fMoreButtons) {
1547 WinSetWindowText(hwndName, pci->pszFileName);
1548 DateFormat(szDate, pci->date);
1549 sprintf(s, "%s %02u%s%02u%s%02u",
1550 szDate,
1551 pci->time.hours, TimeSeparator,
1552 pci->time.minutes, TimeSeparator,
1553 pci->time.seconds);
1554 WinSetWindowText(hwndDate, s);
1555 WinSetWindowText(hwndAttr, pci->pszDispAttr);
1556 }
1557 }
1558 else {
1559 WinSetWindowText(hwndStatus2, NullStr);
1560 WinSetWindowText(hwndName, NullStr);
1561 WinSetWindowText(hwndDate, NullStr);
1562 WinSetWindowText(hwndAttr, NullStr);
1563 }
1564 }
1565 }
1566 }
1567 return 0;
1568
1569 case UM_SORTRECORD:
1570 if (dcd) {
1571
1572 CNRINFO cnri;
1573
1574 memset(&cnri, 0, sizeof(CNRINFO));
1575 cnri.cb = sizeof(CNRINFO);
1576 WinSendMsg(hwnd,
1577 CM_QUERYCNRINFO,
1578 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1579 cnri.pSortRecord = (PVOID) SortDirCnr;
1580 WinSendMsg(hwnd,
1581 CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_PSORTRECORD));
1582 WinSendMsg(hwnd,
1583 CM_SORTRECORD,
1584 MPFROMP(SortDirCnr), MPFROMLONG(dcd->sortFlags));
1585 }
1586 return 0;
1587
1588 case UM_SETUP:
1589 if (dcd) {
1590 if (!dcd->hwndObject) {
1591 // first time through -- set things up
1592
1593 CNRINFO cnri;
1594
1595 memset(&cnri, 0, sizeof(CNRINFO));
1596 cnri.cb = sizeof(CNRINFO);
1597 WinSendMsg(hwnd,
1598 CM_QUERYCNRINFO,
1599 MPFROMP(&cnri), MPFROMLONG(sizeof(CNRINFO)));
1600 cnri.cyLineSpacing = 0;
1601 cnri.cxTreeIndent = 12L;
1602
1603 cnri.flWindowAttr &= (~(CV_TREE | CV_ICON | CV_DETAIL | CV_TEXT));
1604 cnri.flWindowAttr |= (CV_NAME | CA_DETAILSVIEWTITLES | CV_MINI |
1605 CV_FLOW);
1606 cnri.pSortRecord = (PVOID) SortDirCnr;
1607
1608 {
1609 ULONG size = sizeof(ULONG);
1610
1611 PrfQueryProfileData(fmprof, appname, "DirflWindowAttr",
1612 (PVOID) & cnri.flWindowAttr, &size);
1613 size = sizeof(MASK);
1614 if (!*dcd->mask.szMask &&
1615 !dcd->mask.attrFile && !dcd->mask.antiattr) {
1616 if (PrfQueryProfileSize(fmprof, appname, "DirFilter", &size) && size) {
1617 PrfQueryProfileData(fmprof, appname, "DirFilter", &dcd->mask, &size);
1618 SetMask(dcd->mask.szMask, &dcd->mask);
1619 }
1620 else
1621 dcd->mask.attrFile = (FILE_READONLY | FILE_NORMAL |
1622 FILE_ARCHIVED | FILE_DIRECTORY |
1623 FILE_HIDDEN | FILE_SYSTEM);
1624 }
1625 *(dcd->mask.prompt) = 0;
1626 }
1627 if (dcd->flWindowAttr)
1628 cnri.flWindowAttr = dcd->flWindowAttr;
1629 else
1630 dcd->flWindowAttr = cnri.flWindowAttr;
1631 cnri.flWindowAttr &= (~(CA_MIXEDTARGETEMPH | CA_ORDEREDTARGETEMPH |
1632 CA_TITLEREADONLY | CA_TITLESEPARATOR));
1633 cnri.flWindowAttr |= CV_FLOW;
1634 dcd->flWindowAttr |= CV_FLOW;
1635 if (WinWindowFromID(dcd->hwndFrame, FID_TITLEBAR))
1636 cnri.flWindowAttr &= (~CA_CONTAINERTITLE);
1637 else
1638 cnri.flWindowAttr |= CA_CONTAINERTITLE;
1639 if (!dcd->sortFlags)
1640 dcd->sortFlags = sortFlags;
1641 WinSendMsg(hwnd,
1642 CM_SETCNRINFO,
1643 MPFROMP(&cnri),
1644 MPFROMLONG(CMA_FLWINDOWATTR | CMA_LINESPACING |
1645 CMA_CXTREEINDENT | CMA_PSORTRECORD));
1646 SetCnrCols(hwnd, FALSE);
1647 if (xbeginthread(MakeObjWin,
1648 245760,
1649 dcd,
1650 pszSrcFile,
1651 __LINE__) == -1)
1652 {
1653 Runtime_Error(pszSrcFile, __LINE__,
1654 GetPString(IDS_COULDNTSTARTTHREADTEXT));
1655 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1656 return 0;
1657 }
1658 else
1659 DosSleep(32);
1660 WinEnableMenuItem(DirCnrMenu, IDM_FINDINTREE, (hwndTree != (HWND) 0));
1661 }
1662 // 2014-06-11 SHL fm/2 lite can get here before drive scan completes - may not be true anymore
1663 PostMsg(hwnd, UM_SETUP2, MPVOID, MPVOID);
1664 }
1665 else {
1666 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1667 return 0;
1668 }
1669 return 0;
1670
1671 case UM_SETUP2:
1672 if (dcd) {
1673 AdjustCnrColsForPref(hwnd, NULL, &dcd->ds, FALSE);
1674 SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1675 DIR_FILTER), &dcd->mask, FALSE);
1676 SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1677 DIR_SORT), dcd->sortFlags, FALSE);
1678 SayView(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
1679 DIR_VIEW), dcd->flWindowAttr);
1680 } else
1681 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID);
1682 return 0;
1683
1684 case WM_MENUEND:
1685 if (dcd) {
1686
1687 HWND hwndMenu = (HWND) mp2;
1688
1689 if (hwndMenu == DirCnrMenu ||
1690 hwndMenu == FileMenu ||
1691 hwndMenu == DirMenu) {
1692 MarkAll(hwnd, TRUE, FALSE, TRUE);
1693 if (dcd->cnremphasized) {
1694 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPVOID,
1695 MPFROM2SHORT(FALSE, CRA_SOURCE));
1696 dcd->cnremphasized = FALSE;
1697 }
1698 }
1699 }
1700 break;
1701
1702 case UM_OPENWINDOWFORME:
1703 if (dcd) {
1704 if (mp1 && !IsFile((CHAR *)mp1)) {
1705 OpenDirCnr(hwnd, dcd->hwndParent, dcd->hwndFrame, FALSE, (char *)mp1);
1706 }
1707 else if (mp1 && IsFile(mp1) == 1 &&
1708 CheckDriveSpaceAvail(ArcTempRoot, ullDATFileSpaceNeeded, ullTmpSpaceNeeded) != 2) {
1709 StartArcCnr(HWND_DESKTOP,
1710 dcd->hwndFrame, (CHAR *)mp1, 4, (ARC_TYPE *) mp2);
1711 }
1712 }
1713 return 0;
1714
1715 case MM_PORTHOLEINIT:
1716 if (dcd) {
1717 switch (SHORT1FROMMP(mp1)) {
1718 case 0:
1719 case 1:
1720 {
1721 ULONG wmsg;
1722
1723 wmsg = (SHORT1FROMMP(mp1) == 0) ? UM_FILESMENU : UM_VIEWSMENU;
1724 PortholeInit((HWND) WinSendMsg(dcd->hwndClient,
1725 wmsg, MPVOID, MPVOID), mp1, mp2);
1726 }
1727 break;
1728 }
1729 }
1730 break;
1731
1732 case UM_INITMENU:
1733 case WM_INITMENU:
1734 if (dcd) {
1735 switch (SHORT1FROMMP(mp1)) {
1736 case IDM_FILESMENU:
1737 CopyPresParams((HWND) mp2, hwndMainMenu);
1738 if (isalpha(*dcd->directory)) {
1739 if (driveflags[toupper(*dcd->directory) - 'A'] & DRIVE_NOTWRITEABLE) {
1740 WinEnableMenuItem((HWND) mp2, IDM_MOVEMENU, FALSE);
1741 WinEnableMenuItem((HWND) mp2, IDM_RENAME, FALSE);
1742 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, FALSE);
1743 WinEnableMenuItem((HWND) mp2, IDM_UNDELETE, FALSE);
1744 WinEnableMenuItem((HWND) mp2, IDM_DELETESUBMENU, FALSE);
1745 WinEnableMenuItem((HWND) mp2, IDM_DELETE, FALSE);
1746 WinEnableMenuItem((HWND) mp2, IDM_EDIT, FALSE);
1747 WinEnableMenuItem((HWND) mp2, IDM_EDITTEXT, FALSE);
1748 WinEnableMenuItem((HWND) mp2, IDM_EDITBINARY, FALSE);
1749 WinEnableMenuItem((HWND) mp2, IDM_ATTRS, FALSE);
1750 }
1751 else {
1752 WinEnableMenuItem((HWND) mp2, IDM_MOVEMENU, TRUE);
1753 WinEnableMenuItem((HWND) mp2, IDM_RENAME, TRUE);
1754 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, TRUE);
1755 WinEnableMenuItem((HWND) mp2, IDM_UNDELETE, TRUE);
1756 WinEnableMenuItem((HWND) mp2, IDM_DELETESUBMENU, TRUE);
1757 WinEnableMenuItem((HWND) mp2, IDM_DELETE, TRUE);
1758 WinEnableMenuItem((HWND) mp2, IDM_EDIT, TRUE);
1759 WinEnableMenuItem((HWND) mp2, IDM_EDITTEXT, TRUE);
1760 WinEnableMenuItem((HWND) mp2, IDM_EDITBINARY, TRUE);
1761 WinEnableMenuItem((HWND) mp2, IDM_ATTRS, TRUE);
1762 }
1763 WinEnableMenuItem((HWND) mp2, IDM_UNLOCKFILE, fUnlock);
1764 }
1765 break;
1766
1767 case IDM_VIEWSMENU:
1768 SetViewMenu((HWND) mp2, dcd->flWindowAttr);
1769 CopyPresParams((HWND) mp2, hwndMainMenu);
1770 WinEnableMenuItem((HWND) mp2, IDM_RESELECT,
1771 (dcd->lastselection != NULL));
1772 if (isalpha(*dcd->directory)) {
1773 if (driveflags[toupper(*dcd->directory) - 'A'] & DRIVE_NOTWRITEABLE)
1774 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, FALSE);
1775 else
1776 WinEnableMenuItem((HWND) mp2, IDM_MKDIR, TRUE);
1777 }
1778 WinEnableMenuItem((HWND) mp2,
1779 IDM_SELECTCOMPAREMENU,
1780 (CountDirCnrs(dcd->hwndParent) > 1));
1781 break;
1782
1783 case IDM_DETAILSSETUP:
1784 SetDetailsSwitches((HWND) mp2, &dcd->ds);
1785 break;
1786
1787 case IDM_COMMANDSMENU:
1788 SetupCommandMenu((HWND) mp2, hwnd);
1789 break;
1790
1791 case IDM_SORTSUBMENU:
1792 SetSortChecks((HWND) mp2, dcd->sortFlags);
1793 break;
1794
1795 case IDM_WINDOWSMENU:
1796 SetupWinList((HWND) mp2,
1797 (hwndMain) ? hwndMain : (HWND) 0, dcd->hwndFrame);
1798 break;
1799 }
1800 dcd->hwndLastMenu = (HWND) mp2;
1801 }
1802 if (msg == WM_INITMENU)
1803 break;
1804 return 0;
1805
1806 case UM_FILTER:
1807 if (dcd) {
1808
1809 PCNRITEM pci;
1810
1811 if (mp1)
1812 SetMask((CHAR *)mp1, &dcd->mask);
1813
1814 dcd->suspendview = 1;
1815 WinSendMsg(hwnd, CM_FILTER, MPFROMP(Filter), MPFROMP(&dcd->mask));
1816 dcd->suspendview = 0;
1817 if (fAutoView && hwndMain) {
1818 pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1819 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1820 if (pci && (INT) pci != -1 &&
1821 (!(driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_SLOW)))
1822 WinSendMsg(hwndMain, UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
1823 else
1824 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
1825 }
1826 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
1827 }
1828 return 0;
1829
1830 case UM_COMMAND:
1831 if (mp1) {
1832 if (dcd) {
1833 if (!PostMsg(dcd->hwndObject, UM_COMMAND, mp1, mp2)) {
1834 Runtime_Error(pszSrcFile, __LINE__, PCSZ_POSTMSG);
1835 FreeListInfo((LISTINFO *) mp1);
1836 }
1837 else
1838 return (MRESULT) TRUE;
1839 }
1840 else
1841 FreeListInfo((LISTINFO *) mp1);
1842 }
1843 return 0;
1844
1845 case UM_NOTIFY:
1846 if (mp2)
1847 Notify((CHAR *)mp2);
1848 return 0;
1849
1850 case UM_DRIVECMD:
1851 if (mp1)
1852 WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_SWITCH, 0), mp1);
1853 return 0;
1854
1855 case WM_COMMAND:
1856 DosError(FERR_DISABLEHARDERR);
1857 if (dcd) {
1858 switch (SHORT1FROMMP(mp1)) {
1859 case IDM_SETTARGET:
1860 SetTargetDir(hwnd, FALSE, NULL);
1861 break;
1862
1863 case IDM_CREATE:
1864 {
1865 STRINGINPARMS sip;
1866 CHAR filename[CCHMAXPATHCOMP];
1867
1868 memset(&sip, 0, sizeof(sip));
1869 sip.help = GetPString(IDS_CREATETEXT);
1870 sip.prompt = GetPString(IDS_CREATEPROMPTTEXT);
1871 sip.inputlen = CCHMAXPATHCOMP - (strlen(dcd->directory) - 1);
1872 strcpy(filename, "NEWFILE.TXT");
1873 sip.ret = filename;
1874 sip.title = GetPString(IDS_CREATETITLETEXT);
1875 if (WinDlgBox(HWND_DESKTOP, hwnd, InputDlgProc, FM3ModHandle,
1876 STR_FRAME, &sip)) {
1877 bstrip(sip.ret);
1878 if (*sip.ret) {
1879 CHAR newfile[CCHMAXPATH];
1880 FILE *fp;
1881 INT test;
1882 PCNRITEM pci;
1883
1884 strcpy(newfile, dcd->directory);
1885 AddBackslashToPath(newfile);
1886# if 0
1887 if (newfile[strlen(newfile) - 1] != '\\')
1888 strcat(newfile, "\\");
1889# endif
1890 strcat(newfile, sip.ret);
1891 test = IsFile(newfile);
1892 if (test != 1) {
1893 CHAR *modew = "w";
1894
1895 fp = xfopen(newfile, modew, pszSrcFile, __LINE__, TRUE);
1896 }
1897 if (test != 1 && !fp) {
1898 saymsg(MB_ENTER,
1899 hwnd,
1900 GetPString(IDS_ERRORTEXT),
1901 GetPString(IDS_CREATEERRORTEXT), newfile);
1902 }
1903 else {
1904 if (fp) {
1905 WinSendMsg(hwnd, UM_UPDATERECORD, MPFROMP(newfile), MPVOID);
1906 fclose(fp);
1907 }
1908 if (*editor) {
1909
1910 CHAR *dummy[2];
1911
1912 dummy[0] = newfile;
1913 dummy[1] = NULL;
1914 ExecOnList(hwnd,
1915 editor, WINDOWED | SEPARATE, NULL, NULL,
1916 dummy, NULL, pszSrcFile, __LINE__);
1917 }
1918 else
1919 StartMLEEditor(dcd->hwndParent, 4, newfile, dcd->hwndFrame);
1920 pci = FindCnrRecord(hwnd, newfile, NULL, TRUE, FALSE, TRUE);
1921 if (pci && (INT) pci != -1)
1922 // make sure that record shows in viewport
1923 ShowCnrRecord(hwnd, (PMINIRECORDCORE) pci);
1924 }
1925 }
1926 }
1927 }
1928 break;
1929
1930 case IDM_CONTEXTMENU:
1931 {
1932 PCNRITEM pci;
1933
1934 pci = (PCNRITEM) CurrentRecord(hwnd);
1935 PostMsg(hwnd, WM_CONTROL, MPFROM2SHORT(DIR_CNR, CN_CONTEXTMENU),
1936 MPFROMP(pci));
1937 }
1938 break;
1939
1940 case IDM_MAXIMIZE:
1941 PostMsg(hwndMain, UM_MAXIMIZE, MPFROMLONG(dcd->hwndFrame), MPVOID);
1942 break;
1943
1944 case IDM_SHOWALLFILESCNR:
1945 StartSeeAll(HWND_DESKTOP, FALSE, dcd->directory);
1946 break;
1947
1948 case IDM_SHOWALLFILES:
1949 {
1950 PCNRITEM pci;
1951
1952 pci = WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
1953 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
1954 if (pci && (INT) pci != -1) {
1955
1956 static CHAR dirname[CCHMAXPATH];
1957
1958 strcpy(dirname, pci->pszFileName);
1959 MakeValidDir(dirname);
1960 StartSeeAll(HWND_DESKTOP, FALSE, dirname);
1961 }
1962 }
1963 break;
1964
1965 case IDM_FINDINTREE:
1966 if (hwndTree) {
1967 PSZ pszTempDir = xstrdup(dcd->directory, pszSrcFile, __LINE__);
1968
1969 if (pszTempDir) {
1970 if (!PostMsg(hwndTree, UM_SHOWME, MPFROMP(pszTempDir),
1971 MPFROMLONG(1L)))
1972 free(pszTempDir);
1973 }
1974 }
1975 break;
1976
1977 case IDM_BEGINEDIT:
1978 OpenEdit(hwnd);
1979 break;
1980
1981 case IDM_ENDEDIT:
1982 WinSendMsg(hwnd, CM_CLOSEEDIT, MPVOID, MPVOID);
1983 break;
1984
1985 case IDM_SHOWSELECT:
1986 QuickPopup(hwnd,
1987 dcd,
1988 CheckMenu(hwnd, &DirCnrMenu, DIRCNR_POPUP), IDM_SELECTSUBMENU);
1989 break;
1990
1991 case IDM_SHOWSORT:
1992 QuickPopup(hwnd, dcd, CheckMenu(hwnd, &DirCnrMenu, DIRCNR_POPUP),
1993 IDM_SORTSUBMENU);
1994 break;
1995
1996 case IDM_VIEWORARC:
1997 {
1998 SWP swp;
1999 PCNRITEM pci;
2000
2001 pci = (PCNRITEM) WinSendMsg(hwnd, CM_QUERYRECORDEMPHASIS,
2002 MPFROMLONG(CMA_FIRST),
2003 MPFROMSHORT(CRA_CURSORED));
2004 if (pci && (INT) pci != -1) {
2005 WinQueryWindowPos(dcd->hwndFrame, &swp);
2006 DefaultViewKeys(hwnd,
2007 dcd->hwndFrame,
2008 dcd->hwndParent, &swp, pci->pszFileName);
2009 }
2010 }
2011 break;
2012
2013 case IDM_DIRCNRSETTINGS:
2014 if (!ParentIsDesktop(dcd->hwndParent, dcd->hwndParent))
2015 PostMsg(dcd->hwndParent, msg, MPFROMLONG(IDM_DIRCNRSETTINGS), mp2);
2016 else {
2017 WinDlgBox(HWND_DESKTOP,
2018 hwnd,
2019 CfgDlgProc,
2020 FM3ModHandle,
2021 CFG_FRAME,
2022 MPFROMLONG(IDM_DIRCNRSETTINGS));
2023 }
2024 break;
2025
2026 case IDM_QTREE:
2027 case IDM_TREE:
2028 {
2029 CHAR newpath[CCHMAXPATH];
2030 APIRET rc;
2031 PCNRITEM pci;
2032
2033 if (SHORT1FROMMP(mp1) == IDM_TREE) {
2034 pci = (PCNRITEM) CurrentRecord(hwnd);
2035 if (pci && (INT) pci != -1)
2036 strcpy(newpath, pci->pszFileName);
2037 else
2038 strcpy(newpath, dcd->directory);
2039 }
2040 else
2041 strcpy(newpath, dcd->directory);
2042 MakeValidDir(newpath);
2043 rc = WinDlgBox(HWND_DESKTOP, dcd->hwndClient, ObjCnrDlgProc,
2044 FM3ModHandle, QTREE_FRAME, MPFROMP(newpath));
2045 if (rc)
2046 WinSendMsg(hwnd, UM_SETDIR, MPFROMP(newpath), MPVOID);
2047 }
2048 break;
2049
2050 case IDM_RESELECT:
2051 SelectList(hwnd, TRUE, FALSE, FALSE, NULL, NULL, dcd->lastselection);
2052 break;
2053
2054 case IDM_HELP:
2055 if (hwndHelp) {
2056 if (!ParentIsDesktop(dcd->hwndFrame, dcd->hwndParent))
2057 PostMsg(dcd->hwndParent, UM_COMMAND, mp1, mp2);
2058 else
2059 WinSendMsg(hwndHelp, HM_HELP_CONTENTS, MPVOID, MPVOID);
2060 }
2061 break;
2062
2063 case IDM_WINDOWDLG:
2064 if (!ParentIsDesktop(dcd->hwndFrame, dcd->hwndParent))
2065 PostMsg(dcd->hwndParent, UM_COMMAND,
2066 MPFROM2SHORT(IDM_WINDOWDLG, 0), MPVOID);
2067 break;
2068
2069 case IDM_SORTSMARTNAME:
2070 case IDM_SORTNAME:
2071 case IDM_SORTFILENAME:
2072 case IDM_SORTSIZE:
2073 case IDM_SORTEASIZE:
2074 case IDM_SORTFIRST:
2075 case IDM_SORTLAST:
2076 case IDM_SORTLWDATE:
2077 case IDM_SORTLADATE:
2078 case IDM_SORTCRDATE:
2079 case IDM_SORTSUBJECT:
2080 dcd->sortFlags &= (SORT_REVERSE | SORT_DIRSFIRST | SORT_DIRSLAST);
2081 case IDM_SORTDIRSFIRST:
2082 case IDM_SORTDIRSLAST:
2083 case IDM_SORTREVERSE:
2084 switch (SHORT1FROMMP(mp1)) {
2085 case IDM_SORTSUBJECT:
2086 dcd->sortFlags |= SORT_SUBJECT;
2087 break;
2088 case IDM_SORTSMARTNAME:
2089 case IDM_SORTFILENAME:
2090 dcd->sortFlags |= SORT_FILENAME;
2091 break;
2092 case IDM_SORTSIZE:
2093 dcd->sortFlags |= SORT_SIZE;
2094 break;
2095 case IDM_SORTEASIZE:
2096 dcd->sortFlags |= SORT_EASIZE;
2097 break;
2098 case IDM_SORTFIRST:
2099 dcd->sortFlags |= SORT_FIRSTEXTENSION;
2100 break;
2101 case IDM_SORTLAST:
2102 dcd->sortFlags |= SORT_LASTEXTENSION;
2103 break;
2104 case IDM_SORTLWDATE:
2105 dcd->sortFlags |= SORT_LWDATE;
2106 break;
2107 case IDM_SORTLADATE:
2108 dcd->sortFlags |= SORT_LADATE;
2109 break;
2110 case IDM_SORTCRDATE:
2111 dcd->sortFlags |= SORT_CRDATE;
2112 break;
2113 case IDM_SORTDIRSFIRST:
2114 if (dcd->sortFlags & SORT_DIRSFIRST)
2115 dcd->sortFlags &= (~SORT_DIRSFIRST);
2116 else {
2117 dcd->sortFlags |= SORT_DIRSFIRST;
2118 dcd->sortFlags &= (~SORT_DIRSLAST);
2119 }
2120 break;
2121 case IDM_SORTDIRSLAST:
2122 if (dcd->sortFlags & SORT_DIRSLAST)
2123 dcd->sortFlags &= (~SORT_DIRSLAST);
2124 else {
2125 dcd->sortFlags |= SORT_DIRSLAST;
2126 dcd->sortFlags &= (~SORT_DIRSFIRST);
2127 }
2128 break;
2129 case IDM_SORTREVERSE:
2130 if (dcd->sortFlags & SORT_REVERSE)
2131 dcd->sortFlags &= (~SORT_REVERSE);
2132 else
2133 dcd->sortFlags |= SORT_REVERSE;
2134 break;
2135 }
2136 WinSendMsg(hwnd, CM_SORTRECORD, MPFROMP(SortDirCnr),
2137 MPFROMLONG(dcd->sortFlags));
2138 SaySort(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2139 DIR_SORT), dcd->sortFlags, FALSE);
2140 break;
2141
2142 case IDM_COLLECT:
2143 case IDM_GREP:
2144 if (!Collector) {
2145
2146 HWND hwndC;
2147 SWP swp;
2148
2149 if (!ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
2150 (!fExternalCollector && !strcmp(realappname, FM3Str)))
2151 GetNextWindowPos(dcd->hwndParent, &swp, NULL, NULL);
2152 hwndC = StartCollector((fExternalCollector ||
2153 strcmp(realappname, FM3Str)) ?
2154 HWND_DESKTOP : dcd->hwndParent, 4);
2155 if (hwndC) {
2156 if (!ParentIsDesktop(hwnd, dcd->hwndParent) && !fAutoTile &&
2157 (!fExternalCollector && !strcmp(realappname, FM3Str)))
2158 WinSetWindowPos(hwndC, HWND_TOP, swp.x, swp.y,
2159 swp.cx, swp.cy, SWP_MOVE | SWP_SIZE |
2160 SWP_SHOW | SWP_ZORDER);
2161 else if (!ParentIsDesktop(hwnd, dcd->hwndParent) && fAutoTile &&
2162 !strcmp(realappname, FM3Str))
2163 TileChildren(dcd->hwndParent, TRUE);
2164 WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
2165 DosSleep(100);
2166 }
2167 }
2168 else
2169 StartCollector(dcd->hwndParent, 4);
2170 if (SHORT1FROMMP(mp1) == IDM_GREP) {
2171 PCNRITEM pci = NULL;
2172
2173 pci = WinSendMsg(hwnd,
2174 CM_QUERYRECORDEMPHASIS,
2175 MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED));
2176 if (pci && (INT) pci != -1)
2177 PostMsg(Collector, WM_COMMAND,
2178 MPFROM2SHORT(IDM_GREP, 0), MPFROMP(pci->pszFileName));
2179 else
2180 PostMsg(Collector, WM_COMMAND,
2181 MPFROM2SHORT(IDM_GREP, 0), MPVOID);
2182 }
2183 else
2184 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_COLLECTOR, 0), MPVOID);
2185 break;
2186
2187 case IDM_COLLECTOR:
2188 DosSleep(32);
2189 {
2190 CHAR **list;
2191
2192 list = BuildList(hwnd);
2193 if (list) {
2194 if (Collector) {
2195 if (!PostMsg(Collector,
2196 WM_COMMAND,
2197 MPFROM2SHORT(IDM_COLLECTOR, 0), MPFROMP(list)))
2198 FreeList(list);
2199 else if (fUnHilite)
2200 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
2201 }
2202 else
2203 FreeList(list);
2204 }
2205 }
2206 break;
2207
2208 case IDM_UNDELETE:
2209 {
2210 PCNRITEM pci;
2211 CHAR path[CCHMAXPATH];
2212 HOBJECT hObject;
2213 HWND hwndDesktop;
2214
2215 hObject = WinQueryObject("<XWP_TRASHCAN>");
2216 if (hObject != NULLHANDLE && fTrashCan) {
2217 hwndDesktop = WinQueryDesktopWindow((HAB) 0, NULLHANDLE);
2218 WinSetFocus(HWND_DESKTOP, hwndDesktop);
2219 WinOpenObject(hObject, 0, TRUE);
2220 }
2221 else {
2222 pci = (PCNRITEM) CurrentRecord(hwnd);
2223 if (pci && (INT) pci != -1) {
2224 strcpy(path, pci->pszFileName);
2225 MakeValidDir(path);
2226 WinDlgBox(HWND_DESKTOP, hwnd, UndeleteDlgProc, FM3ModHandle,
2227 UNDEL_FRAME, MPFROMP(path));
2228 }
2229 }
2230 }
2231 break;
2232
2233 case IDM_UNDELETESPEC:
2234 {
2235 HOBJECT hObject;
2236 HWND hwndDesktop;
2237
2238 hObject = WinQueryObject("<XWP_TRASHCAN>");
2239 if (hObject != NULLHANDLE && fTrashCan) {
2240 hwndDesktop = WinQueryDesktopWindow((HAB) 0, NULLHANDLE);
2241 WinSetFocus(HWND_DESKTOP, hwndDesktop);
2242 WinOpenObject(hObject, 0, TRUE);
2243 }
2244 else
2245 WinDlgBox(HWND_DESKTOP,
2246 hwnd,
2247 UndeleteDlgProc,
2248 FM3ModHandle, UNDEL_FRAME, MPFROMP(dcd->directory));
2249 }
2250 break;
2251
2252 case IDM_RESORT:
2253# if 0
2254 WinSendMsg(hwnd,
2255 CM_SORTRECORD,
2256 MPFROMP(SortDirCnr),
2257 MPFROMLONG((fSyncUpdates) ? sortFlags : dcd->sortFlags));
2258#endif
2259 WinSendMsg(hwnd,
2260 CM_SORTRECORD,
2261 MPFROMP(SortDirCnr), MPFROMLONG(dcd->sortFlags));
2262 break;
2263
2264 case IDM_FILTER:
2265 {
2266 BOOL empty = FALSE;
2267 PCNRITEM pci;
2268 CHAR *p;
2269
2270 if (!*dcd->mask.szMask) {
2271 empty = TRUE;
2272 pci = (PCNRITEM) CurrentRecord(hwnd);
2273 if (pci && !(pci->attrFile & FILE_DIRECTORY)) {
2274 p = strrchr(pci->pszFileName, '\\');
2275 if (p) {
2276 p++;
2277 strcpy(dcd->mask.szMask, p);
2278 }
2279 }
2280 }
2281 *(dcd->mask.prompt) = 0;
2282
2283 if (WinDlgBox(HWND_DESKTOP, hwnd, PickMaskDlgProc,
2284 FM3ModHandle, MSK_FRAME, MPFROMP(&dcd->mask)))
2285 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2286 else if (empty)
2287 *dcd->mask.szMask = 0;
2288 SayFilter(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2289 DIR_FILTER), &dcd->mask, FALSE);
2290 }
2291 break;
2292
2293 case IDM_UNHIDEALL:
2294 WinSendMsg(hwnd, CM_FILTER, MPFROMP(Filter), MPFROMP(&dcd->mask));
2295 break;
2296
2297 case IDM_HIDEALL:
2298 if (fAutoView && hwndMain)
2299 PostMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
2300 dcd->suspendview = 1;
2301 HideAll(hwnd);
2302 dcd->suspendview = 0;
2303 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2304 break;
2305
2306 case IDM_SELECTBOTH:
2307 case IDM_SELECTONE:
2308 case IDM_SELECTMORE:
2309 case IDM_SELECTNEWER:
2310 case IDM_SELECTOLDER:
2311 case IDM_SELECTBIGGER:
2312 case IDM_SELECTSMALLER:
2313 case IDM_DESELECTBOTH:
2314 case IDM_DESELECTONE:
2315 case IDM_DESELECTMORE:
2316 case IDM_DESELECTNEWER:
2317 case IDM_DESELECTOLDER:
2318 case IDM_DESELECTBIGGER:
2319 case IDM_DESELECTSMALLER:
2320 if (ParentIsDesktop(hwnd, dcd->hwndParent)) {
2321 Runtime_Error(pszSrcFile, __LINE__, "ParentIsDesktop unexpected");
2322 break;
2323 }
2324 case IDM_SELECTLIST:
2325 case IDM_SELECTALL:
2326 case IDM_DESELECTALL:
2327 case IDM_SELECTALLFILES:
2328 case IDM_DESELECTALLFILES:
2329 case IDM_SELECTALLDIRS:
2330 case IDM_DESELECTALLDIRS:
2331 case IDM_SELECTMASK:
2332 case IDM_DESELECTMASK:
2333 case IDM_INVERT:
2334 case IDM_SELECTCLIP:
2335 case IDM_DESELECTCLIP:
2336 {
2337 PCNRITEM pci;
2338
2339 pci = (PCNRITEM) CurrentRecord(hwnd);
2340 if ((INT) pci == -1)
2341 pci = NULL;
2342 if (SHORT1FROMMP(mp1) == IDM_HIDEALL) {
2343 if (pci) {
2344 if (!(pci->rc.flRecordAttr & CRA_SELECTED))
2345 pci->rc.flRecordAttr |= CRA_FILTERED;
2346 WinSendMsg(hwnd, CM_INVALIDATERECORD, MPFROMP(&pci),
2347 MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION));
2348 break;
2349 }
2350 }
2351 PostMsg(dcd->hwndObject, UM_SELECT, mp1, MPFROMP(pci));
2352 }
2353 break;
2354
2355 case IDM_RESCAN:
2356 dcd->stopflag++;
2357 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPVOID)) {
2358 dcd->stopflag--;
2359 }
2360 break;
2361
2362 case IDM_SHOWLNAMES:
2363 case IDM_SHOWSUBJECT:
2364 case IDM_SHOWEAS:
2365 case IDM_SHOWSIZE:
2366 case IDM_SHOWICON:
2367 case IDM_SHOWLWDATE:
2368 case IDM_SHOWLWTIME:
2369 case IDM_SHOWLADATE:
2370 case IDM_SHOWLATIME:
2371 case IDM_SHOWCRDATE:
2372 case IDM_SHOWCRTIME:
2373 case IDM_SHOWATTR:
2374 AdjustDetailsSwitches(hwnd,
2375 dcd->hwndLastMenu,
2376 SHORT1FROMMP(mp1),
2377 dcd->directory, NULL, &dcd->ds, FALSE);
2378 break;
2379
2380 case IDM_TREEVIEW:
2381 case IDM_ICON:
2382 case IDM_TEXT:
2383 case IDM_DETAILS:
2384 case IDM_NAME:
2385 case IDM_MINIICONS:
2386 case IDM_DETAILSTITLES:
2387 {
2388 CNRINFO cnri;
2389
2390 memset(&cnri, 0, sizeof(CNRINFO));
2391 cnri.cb = sizeof(CNRINFO);
2392 WinSendMsg(hwnd, CM_QUERYCNRINFO, MPFROMP(&cnri),
2393 MPFROMLONG(sizeof(CNRINFO)));
2394 switch (SHORT1FROMMP(mp1)) {
2395 case IDM_TREEVIEW:
2396 if (!(cnri.flWindowAttr & CV_TREE))
2397 dcd->lastattr = cnri.flWindowAttr;
2398 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2399 CV_DETAIL | CV_NAME | CA_TREELINE));
2400 cnri.flWindowAttr |= CA_TREELINE | CV_TREE | CV_ICON;
2401 if (!dcd->firsttree)
2402 PostMsg(dcd->hwndObject, UM_FLESH, MPVOID, MPVOID);
2403 break;
2404 case IDM_ICON:
2405 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2406 CV_DETAIL | CV_NAME | CA_TREELINE));
2407 cnri.flWindowAttr |= CV_ICON;
2408 break;
2409 case IDM_NAME:
2410 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2411 CV_DETAIL | CV_NAME | CA_TREELINE));
2412 cnri.flWindowAttr |= CV_NAME;
2413 break;
2414 case IDM_TEXT:
2415 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2416 CV_DETAIL | CV_NAME | CA_TREELINE));
2417 cnri.flWindowAttr |= CV_TEXT;
2418 break;
2419 case IDM_DETAILS:
2420 cnri.flWindowAttr &= (~(CV_ICON | CV_TREE | CV_TEXT |
2421 CV_DETAIL | CV_NAME | CA_TREELINE));
2422 cnri.flWindowAttr |= CV_DETAIL;
2423 break;
2424 case IDM_MINIICONS:
2425 if (cnri.flWindowAttr & CV_MINI)
2426 cnri.flWindowAttr &= (~CV_MINI);
2427 else
2428 cnri.flWindowAttr |= CV_MINI;
2429 break;
2430 case IDM_DETAILSTITLES:
2431 if (cnri.flWindowAttr & CA_DETAILSVIEWTITLES)
2432 cnri.flWindowAttr &= (~CA_DETAILSVIEWTITLES);
2433 else
2434 cnri.flWindowAttr |= CA_DETAILSVIEWTITLES;
2435 break;
2436 }
2437 cnri.flWindowAttr &= (~(CA_ORDEREDTARGETEMPH | CA_MIXEDTARGETEMPH));
2438 cnri.flWindowAttr |= CV_FLOW;
2439 dcd->flWindowAttr = cnri.flWindowAttr;
2440 WinSendMsg(hwnd, CM_SETCNRINFO, MPFROMP(&cnri),
2441 MPFROMLONG(CMA_FLWINDOWATTR));
2442 WinSendMsg(hwnd, CM_INVALIDATERECORD, MPVOID,
2443 MPFROM2SHORT(0, CMA_ERASE | CMA_REPOSITION));
2444 SayView(WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
2445 DIR_VIEW), dcd->flWindowAttr);
2446 }
2447 break;
2448
2449 case IDM_SAVETOLIST:
2450 WinDlgBox(HWND_DESKTOP, hwnd, SaveListDlgProc, FM3ModHandle,
2451 SAV_FRAME, MPFROMP(&hwnd));
2452 break;
2453
2454 case IDM_SIZES:
2455 {
2456 PCNRITEM pci;
2457 CHAR path[CCHMAXPATH];
2458
2459 pci = (PCNRITEM) CurrentRecord(hwnd);
2460 if (pci && (INT) pci != -1)
2461 strcpy(path, pci->pszFileName);
2462 else
2463 strcpy(path, dcd->directory);
2464 MakeValidDir(path);
2465 WinDlgBox(HWND_DESKTOP,
2466 HWND_DESKTOP, DirSizeProc, FM3ModHandle, DSZ_FRAME, path);
2467 }
2468 break;
2469
2470 case IDM_MKDIR:
2471 {
2472 PCNRITEM pci;
2473 BOOL saved;
2474
2475 saved = fSelectedAlways;
2476 fSelectedAlways = FALSE;
2477 pci = (PCNRITEM)CurrentRecord(hwnd);
2478 // 01 Oct 07 SHL Make below selected directory or in current directory
2479 PMMkDir(dcd->hwndParent,
2480 pci && (INT)pci != -1 ? pci->pszFileName : dcd->directory,
2481 FALSE);
2482 fSelectedAlways = saved;
2483 }
2484 break;
2485
2486 case IDM_SWITCH:
2487 if (mp2) {
2488 strcpy(dcd->previous, dcd->directory);
2489 strcpy(dcd->directory, (CHAR *)mp2);
2490 dcd->stopflag++;
2491 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
2492 strcpy(dcd->directory, dcd->previous);
2493 dcd->stopflag--;
2494 }
2495 else if (*dcd->directory) {
2496 if (hwndMain)
2497 WinSendMsg(hwndMain,
2498 UM_SETUSERLISTNAME, MPFROMP(dcd->directory), MPVOID);
2499 else
2500 add_udir(FALSE, dcd->directory);
2501 }
2502 }
2503 break;
2504
2505 case IDM_PARENT:
2506 {
2507 CHAR tempname1[CCHMAXPATH], tempname2[CCHMAXPATH];
2508
2509 strcpy(tempname1, dcd->directory);
2510 AddBackslashToPath(tempname1);
2511 strcat(tempname1, "..");
2512 DosError(FERR_DISABLEHARDERR);
2513 if (!DosQueryPathInfo(tempname1,
2514 FIL_QUERYFULLNAME,
2515 tempname2, sizeof(tempname2))) {
2516 if (stricmp(dcd->directory, tempname2)) {
2517 strcpy(dcd->previous, dcd->directory);
2518 strcpy(dcd->directory, tempname2);
2519 dcd->stopflag++;
2520 if (!PostMsg(dcd->hwndObject,
2521 UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
2522 strcpy(dcd->directory, dcd->previous);
2523 dcd->stopflag--;
2524 }
2525 else if (*dcd->directory) {
2526 if (hwndMain)
2527 WinSendMsg(hwndMain,
2528 UM_SETUSERLISTNAME,
2529 MPFROMP(dcd->directory), MPVOID);
2530 else
2531 add_udir(FALSE, dcd->directory);
2532 }
2533 }
2534 }
2535 }
2536 break;
2537
2538 case IDM_PREVIOUS:
2539 if (*dcd->previous && stricmp(dcd->directory, dcd->previous)) {
2540
2541 CHAR tempname[CCHMAXPATH];
2542
2543 if (IsValidDir(dcd->previous)) {
2544 strcpy(tempname, dcd->directory);
2545 strcpy(dcd->directory, dcd->previous);
2546 strcpy(dcd->previous, tempname);
2547 dcd->stopflag++;
2548 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
2549 strcpy(dcd->directory, dcd->previous);
2550 dcd->stopflag--;
2551 }
2552 else if (*dcd->directory) {
2553 if (hwndMain)
2554 WinSendMsg(hwndMain,
2555 UM_SETUSERLISTNAME,
2556 MPFROMP(dcd->directory), MPVOID);
2557 else
2558 add_udir(FALSE, dcd->directory);
2559 }
2560 }
2561 else
2562 *dcd->previous = 0;
2563 }
2564 break;
2565
2566 case IDM_WALKDIR:
2567 {
2568 CHAR newdir[CCHMAXPATH];
2569
2570 strcpy(newdir, dcd->directory);
2571 if (!WinDlgBox(HWND_DESKTOP,
2572 dcd->hwndParent,
2573 WalkAllDlgProc,
2574 FM3ModHandle,
2575 WALK_FRAME, MPFROMP(newdir)) || !*newdir)
2576 break;
2577 if (stricmp(newdir, dcd->directory)) {
2578 strcpy(dcd->previous, dcd->directory);
2579 strcpy(dcd->directory, newdir);
2580 dcd->stopflag++;
2581 if (!PostMsg(dcd->hwndObject, UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
2582 strcpy(dcd->directory, dcd->previous);
2583 dcd->stopflag--;
2584 }
2585 else if (*dcd->directory) {
2586 if (hwndMain)
2587 WinSendMsg(hwndMain,
2588 UM_SETUSERLISTNAME,
2589 MPFROMP(dcd->directory), MPVOID);
2590 else
2591 add_udir(FALSE, dcd->directory);
2592 }
2593 }
2594 }
2595 break;
2596
2597 case IDM_OPENICONME:
2598 OpenObject(dcd->directory, PCSZ_ICON, dcd->hwndFrame);
2599 break;
2600 case IDM_OPENDETAILSME:
2601 OpenObject(dcd->directory, Details, dcd->hwndFrame);
2602 break;
2603 case IDM_OPENTREEME:
2604 OpenObject(dcd->directory, PCSZ_TREE, dcd->hwndFrame);
2605 break;
2606 case IDM_OPENSETTINGSME:
2607 OpenObject(dcd->directory, Settings, dcd->hwndFrame);
2608 break;
2609
2610 case IDM_DOITYOURSELF:
2611 case IDM_UPDATE:
2612 case IDM_OPENWINDOW:
2613 case IDM_OPENSETTINGS:
2614 case IDM_OPENDEFAULT:
2615 case IDM_OPENICON:
2616 case IDM_OPENDETAILS:
2617 case IDM_OPENTREE:
2618 case IDM_OBJECT:
2619 case IDM_SHADOW:
2620 case IDM_SHADOW2:
2621 case IDM_JAVAEXE:
2622 case IDM_DELETE:
2623 case IDM_PERMDELETE:
2624 case IDM_PRINT:
2625 case IDM_ATTRS:
2626 case IDM_INFO:
2627 case IDM_COPY:
2628 case IDM_MOVE:
2629 case IDM_WPSMOVE:
2630 case IDM_WPSCOPY:
2631 case IDM_WILDCOPY:
2632 case IDM_WILDMOVE:
2633 case IDM_RENAME:
2634 case IDM_COMPARE:
2635 case IDM_EAS:
2636 case IDM_SUBJECT:
2637 case IDM_VIEW:
2638 case IDM_VIEWTEXT:
2639 case IDM_VIEWBINARY:
2640 case IDM_VIEWARCHIVE:
2641 case IDM_EDIT:
2642 case IDM_EDITTEXT:
2643 case IDM_EDITBINARY:
2644 case IDM_SAVETOCLIP:
2645 case IDM_SAVETOCLIPFILENAME:
2646 case IDM_APPENDTOCLIP:
2647 case IDM_APPENDTOCLIPFILENAME:
2648 case IDM_ARCHIVE:
2649 case IDM_ARCHIVEM:
2650 case IDM_EXTRACT:
2651 case IDM_MCIPLAY:
2652 case IDM_COLLECTFROMFILE:
2653 case IDM_UUDECODE:
2654 case IDM_UNLOCKFILE:
2655 case IDM_MERGE:
2656 {
2657 LISTINFO *li;
2658 ULONG action = UM_ACTION;
2659 li = xmallocz(sizeof(LISTINFO), pszSrcFile, __LINE__);
2660 if (li) {
2661 li->type = SHORT1FROMMP(mp1);
2662 li->hwnd = hwnd;
2663 li->list = BuildList(hwnd);
2664 if (li->type == IDM_DELETE)
2665 ignorereadonly = FALSE;
2666 switch (SHORT1FROMMP(mp1)) {
2667 case IDM_WILDMOVE:
2668 case IDM_WILDCOPY:
2669 case IDM_MOVE:
2670 case IDM_COPY:
2671 case IDM_WPSMOVE:
2672 case IDM_WPSCOPY:
2673 break;
2674 default:
2675 strcpy(li->targetpath, dcd->directory);
2676 break;
2677 }
2678 if (li->list) {
2679 if (SHORT1FROMMP(mp1) == IDM_COLLECTFROMFILE) {
2680 if (!Collector) {
2681
2682 HWND hwndC;
2683 SWP swp;
2684
2685 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2686 !fAutoTile &&
2687 (!fExternalCollector && !strcmp(realappname, FM3Str)))
2688 GetNextWindowPos(dcd->hwndParent, &swp, NULL, NULL);
2689 hwndC = StartCollector((fExternalCollector ||
2690 strcmp(realappname, FM3Str)) ?
2691 HWND_DESKTOP : dcd->hwndParent, 4);
2692 if (hwndC) {
2693 if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2694 !fAutoTile && (!fExternalCollector &&
2695 !strcmp(realappname, FM3Str)))
2696 WinSetWindowPos(hwndC, HWND_TOP, swp.x, swp.y,
2697 swp.cx, swp.cy, SWP_MOVE | SWP_SIZE |
2698 SWP_SHOW | SWP_ZORDER);
2699 else if (!ParentIsDesktop(hwnd, dcd->hwndParent) &&
2700 fAutoTile && !strcmp(realappname, FM3Str))
2701 TileChildren(dcd->hwndParent, TRUE);
2702 WinSetWindowPos(hwndC, HWND_TOP, 0, 0, 0, 0,
2703 SWP_ACTIVATE);
2704 DosSleep(100);
2705 }
2706 }
2707 else
2708 StartCollector(dcd->hwndParent, 4);
2709 }
2710 switch (SHORT1FROMMP(mp1)) {
2711 case IDM_APPENDTOCLIP:
2712 case IDM_APPENDTOCLIPFILENAME:
2713 case IDM_SAVETOCLIP:
2714 case IDM_SAVETOCLIPFILENAME:
2715 case IDM_ARCHIVE:
2716 case IDM_ARCHIVEM:
2717 case IDM_DELETE:
2718 case IDM_PERMDELETE:
2719 case IDM_ATTRS:
2720 case IDM_PRINT:
2721 case IDM_SHADOW:
2722 case IDM_SHADOW2:
2723 case IDM_JAVAEXE:
2724 case IDM_OBJECT:
2725 case IDM_VIEW:
2726 case IDM_VIEWTEXT:
2727 case IDM_VIEWBINARY:
2728 case IDM_EDIT:
2729 case IDM_EDITTEXT:
2730 case IDM_EDITBINARY:
2731 case IDM_MCIPLAY:
2732 case IDM_UPDATE:
2733 case IDM_DOITYOURSELF:
2734 case IDM_INFO:
2735 case IDM_EAS:
2736 action = UM_MASSACTION;
2737 break;
2738 }
2739 if (li->type == IDM_DELETE)
2740 ignorereadonly = FALSE;
2741 if (SHORT1FROMMP(mp1) == IDM_OBJECT ||
2742 SHORT1FROMMP(mp1) == IDM_SHADOW ||
2743 SHORT1FROMMP(mp1) == IDM_SHADOW2)
2744 *li->targetpath = 0;
2745 if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID)) {
2746 Runtime_Error(pszSrcFile, __LINE__, PCSZ_POSTMSG);
2747 FreeListInfo(li);
2748 }
2749 else if (fUnHilite)
2750 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
2751 }
2752 else
2753 free(li);
2754 }
2755 }
2756 break;
2757
2758 case IDM_DRIVESMENU:
2759 if (!hwndMain)
2760 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_WALKDIR, 0), MPVOID);
2761 break;
2762
2763 default:
2764 if (SwitchCommand(dcd->hwndLastMenu, SHORT1FROMMP(mp1)))
2765 return 0;
2766 else {
2767 if (SHORT1FROMMP(mp1) >= IDM_COMMANDSTART &&
2768 SHORT1FROMMP(mp1) < IDM_QUICKTOOLSTART) {
2769
2770 register INT x;
2771
2772 if (!cmdloaded)
2773 load_commands();
2774 x = SHORT1FROMMP(mp1);
2775 if (x >= 0) {
2776 RunCommand(hwnd, x);
2777 if (fUnHilite)
2778 UnHilite(hwnd, TRUE, &dcd->lastselection, 0);
2779 }
2780 }
2781 }
2782 break;
2783 }
2784 }
2785 return 0;
2786
2787 case UM_FIXCNRMLE:
2788 case UM_FIXEDITNAME:
2789 return CommonCnrProc(hwnd, msg, mp1, mp2);
2790
2791 case UM_FILESMENU:
2792 {
2793 PCNRITEM pci;
2794 HWND menuHwnd = (HWND) 0;
2795
2796 pci = (PCNRITEM) CurrentRecord(hwnd);
2797 if (pci && (INT) pci != -1) {
2798 if (pci->attrFile & FILE_DIRECTORY) {
2799 menuHwnd = CheckMenu(hwndMainMenu, &DirMenu, DIR_POPUP);
2800 }
2801 else
2802 menuHwnd = CheckMenu(hwndMainMenu, &FileMenu, FILE_POPUP);
2803 }
2804 return MRFROMLONG(menuHwnd);
2805 }
2806
2807 case WM_CONTROL:
2808 DosError(FERR_DISABLEHARDERR);
2809 if (dcd) {
2810 switch (SHORT2FROMMP(mp1)) {
2811 case CN_COLLAPSETREE:
2812 case CN_EXPANDTREE:
2813 {
2814 PCNRITEM pci = (PCNRITEM) mp2;
2815
2816 if (pci && (INT) pci != -1 && !(pci->flags & RECFLAGS_ENV)) {
2817 if (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_REMOVABLE) {
2818 struct
2819 {
2820 ULONG serial;
2821 CHAR volumelength;
2822 CHAR volumelabel[CCHMAXPATH];
2823 }
2824 volser;
2825 APIRET rc;
2826
2827 memset(&volser, 0, sizeof(volser));
2828 DosError(FERR_DISABLEHARDERR);
2829 // fixme?
2830 rc = DosQueryFSInfo(toupper(*pci->pszFileName) - '@',
2831 FSIL_VOLSER, &volser, sizeof(volser));
2832 if (rc) {
2833 Dos_Error(MB_ENTER, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
2834 GetPString(IDS_CANTFINDDIRTEXT),
2835 pci->pszFileName);
2836 if (!fErrorBeepOff)
2837 DosBeep(250,100);
2838 driveserial[toupper(*pci->pszFileName) - 'A'] = -1;
2839 AddFleshWorkRequest(hwnd, pci, eUnFlesh);
2840 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
2841 }
2842 else {
2843 if (SHORT2FROMMP(mp1) == CN_COLLAPSETREE &&
2844 !volser.serial ||
2845 driveserial[toupper(*pci->pszFileName) - 'A'] !=
2846 volser.serial)
2847 AddFleshWorkRequest(hwnd, pci, eUnFlesh);
2848 if (SHORT2FROMMP(mp1) != CN_COLLAPSETREE ||
2849 (!volser.serial ||
2850 driveserial[toupper(*pci->pszFileName) - 'A'] !=
2851 volser.serial)) {
2852 // 2015-08-07 SHL FIXME to wait for Flesh to finish before PostMsg
2853 // 2015-09-26 GKY Waits (WaitFleshWorkListEmpty) in object window
2854 if (SHORT2FROMMP(mp1) == CN_EXPANDTREE && AddFleshWorkRequest(hwnd, pci, eFlesh) &&
2855 !dcd->suspendview && fTopDir) {
2856 PostMsg(dcd->hwndObject, UM_TOPDIR, MPFROMP(pci), MPVOID);
2857 }
2858 }
2859 driveserial[toupper(*pci->pszFileName) - 'A'] = volser.serial;
2860 }
2861 }
2862 else if (SHORT2FROMMP(mp1) == CN_EXPANDTREE) {
2863 if (AddFleshWorkRequest(hwnd, pci, eFlesh) && !dcd->suspendview &&
2864 fTopDir) {
2865 // 2015-08-07 SHL FIXME to wait for Flesh to finish before PostMsg
2866 // 2015-09-26 GKY Waits (WaitFleshWorkListEmpty) in object window
2867 PostMsg(dcd->hwndObject, UM_TOPDIR, MPFROMP(pci), MPVOID);
2868 }
2869 }
2870 if (SHORT2FROMMP(mp1) == CN_EXPANDTREE && !dcd->suspendview)
2871 WinSendMsg(hwnd, UM_FILTER, MPVOID, MPVOID);
2872
2873 }
2874 }
2875 break;
2876
2877 case CN_CONTEXTMENU:
2878 {
2879 PCNRITEM pci = (PCNRITEM) mp2;
2880
2881 if (pci) {
2882 WinSendMsg(hwnd,
2883 CM_SETRECORDEMPHASIS,
2884 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_CURSORED));
2885 MarkAll(hwnd, FALSE, FALSE, TRUE);
2886 if (pci->attrFile & FILE_DIRECTORY)
2887 dcd->hwndLastMenu = CheckMenu(hwndMainMenu, &DirMenu, DIR_POPUP);
2888 else
2889 dcd->hwndLastMenu = CheckMenu(hwndMainMenu, &FileMenu, FILE_POPUP);
2890 }
2891 else {
2892 dcd->hwndLastMenu = CheckMenu(hwnd, &DirCnrMenu, DIRCNR_POPUP);
2893 if (dcd->hwndLastMenu && !dcd->cnremphasized) {
2894 WinSendMsg(hwnd,
2895 CM_SETRECORDEMPHASIS,
2896 MPVOID, MPFROM2SHORT(TRUE, CRA_SOURCE));
2897 dcd->cnremphasized = TRUE;
2898 }
2899 }
2900 if (dcd->hwndLastMenu) {
2901 if (dcd->hwndLastMenu == DirCnrMenu) {
2902 if (dcd->flWindowAttr & CV_MINI)
2903 WinCheckMenuItem(dcd->hwndLastMenu, IDM_MINIICONS, TRUE);
2904 }
2905 if (dcd->hwndLastMenu == DirMenu)
2906 WinEnableMenuItem(DirMenu, IDM_TREE, TRUE);
2907 if (!PopupMenu(hwnd, hwnd, dcd->hwndLastMenu)) {
2908 if (dcd->cnremphasized) {
2909 WinSendMsg(hwnd,
2910 CM_SETRECORDEMPHASIS,
2911 MPVOID, MPFROM2SHORT(FALSE, CRA_SOURCE));
2912 dcd->cnremphasized = TRUE;
2913 }
2914 MarkAll(hwnd, TRUE, FALSE, TRUE);
2915 }
2916 }
2917 }
2918 break;
2919
2920 case CN_DROPHELP:
2921 if (mp2) {
2922
2923 PDRAGINFO pDInfo;
2924 PCNRITEM pci;
2925 ULONG numitems;
2926 USHORT usOperation;
2927
2928 pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2929 pDInfo = (PDRAGINFO) ((PCNRDRAGINFO) mp2)->pDragInfo;
2930 if (!DrgAccessDraginfo(pDInfo)) {
2931 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__,
2932 GetPString(IDS_DROPERRORTEXT));
2933 }
2934 else {
2935 numitems = DrgQueryDragitemCount(pDInfo);
2936 usOperation = pDInfo->usOperation;
2937 if (usOperation == DO_DEFAULT)
2938 usOperation = fCopyDefault ? DO_COPY : DO_MOVE;
2939 FreeDragInfoData(hwnd, pDInfo);
2940 saymsg(MB_ENTER | MB_ICONASTERISK,
2941 hwnd,
2942 GetPString(IDS_DROPHELPHDRTEXT),
2943 GetPString(IDS_DROPHELPTEXT),
2944 numitems,
2945 &"s"[numitems == 1L],
2946 pci ? NullStr : GetPString(IDS_NOTEXT),
2947 pci ? NullStr : " ",
2948 pci ? pci->pszFileName : NullStr,
2949 pci ? " " : NullStr,
2950 GetPString((usOperation == DO_MOVE) ?
2951 IDS_MOVETEXT :
2952 (usOperation == DO_LINK) ?
2953 IDS_LINKTEXT : IDS_COPYTEXT));
2954 }
2955 }
2956 return 0;
2957
2958 case CN_DRAGLEAVE:
2959 return 0;
2960
2961 case CN_DRAGAFTER:
2962 case CN_DRAGOVER:
2963 if (mp2) {
2964
2965 PDRAGITEM pDItem; // Pointer to DRAGITEM
2966 PDRAGINFO pDInfo; // Pointer to DRAGINFO
2967 PCNRITEM pci;
2968 USHORT uso;
2969
2970 pci = (PCNRITEM) ((PCNRDRAGINFO) mp2)->pRecord;
2971 pDInfo = ((PCNRDRAGINFO) mp2)->pDragInfo;
2972 if (!DrgAccessDraginfo(pDInfo)) {
2973 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
2974 PCSZ_DRGACCESSDRAGINFO);
2975 return (MRFROM2SHORT(DOR_NEVERDROP, 0));
2976 }
2977 if (*dcd->directory &&
2978 (driveflags[toupper(*dcd->directory) - 'A'] &
2979 DRIVE_NOTWRITEABLE)) {
2980 DrgFreeDraginfo(pDInfo);
2981 return MRFROM2SHORT(DOR_DROP, // Return okay to link
2982 DO_LINK); // (compare) only
2983 }
2984 if (pci) {
2985 if (pci->rc.flRecordAttr & CRA_SOURCE) {
2986 DrgFreeDraginfo(pDInfo);
2987 return (MRFROM2SHORT(DOR_NODROP, 0));
2988 }
2989 uso = pDInfo->usOperation;
2990 if (uso == DO_DEFAULT)
2991 uso = fCopyDefault ? DO_COPY : DO_MOVE;
2992 if (!(pci->attrFile & FILE_DIRECTORY)) {
2993 if (uso != DO_LINK && uso != DO_COPY && uso != DO_MOVE) {
2994 DrgFreeDraginfo(pDInfo);
2995 return MRFROM2SHORT(DOR_NODROP, 0);
2996 }
2997 if (uso != DO_LINK &&
2998 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
2999 DRIVE_NOTWRITEABLE)) {
3000
3001 ARC_TYPE *info = NULL;
3002
3003 if (!fQuickArcFind &&
3004 !(driveflags[toupper(*pci->pszFileName) - 'A'] &
3005 DRIVE_SLOW))
3006 info = find_type(pci->pszFileName, NULL);
3007 else
3008 info = quick_find_type(pci->pszFileName, NULL);
3009 if (!info || ((uso == DO_MOVE && !info->move) ||
3010 (uso == DO_COPY && !info->create))) {
3011 DrgFreeDraginfo(pDInfo);
3012 return MRFROM2SHORT(DOR_NODROP, 0);
3013 }
3014 }
3015 }
3016 }
3017
3018 /**
3019 * Access DRAGITEM index to DRAGITEM
3020 * Check valid rendering mechanisms and data
3021 */
3022 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
3023 if (DrgVerifyRMF(pDItem, (CHAR *) DRM_OS2FILE, NULL) ||
3024 ((!pci || (pci->attrFile & FILE_DIRECTORY)) &&
3025 DrgVerifyRMF(pDItem, (CHAR *) DRM_FM2ARCMEMBER, (CHAR *) DRF_FM2ARCHIVE))) {
3026 DrgFreeDraginfo(pDInfo);
3027 if (driveflags[toupper(*dcd->directory) - 'A'] &
3028 DRIVE_NOTWRITEABLE)
3029 return MRFROM2SHORT(DOR_DROP, DO_LINK);
3030 if (toupper(*dcd->directory) < 'C')
3031 return MRFROM2SHORT(DOR_DROP, DO_COPY);
3032 return MRFROM2SHORT(DOR_DROP, // Return okay to drop
3033 ((fCopyDefault) ? DO_COPY : DO_MOVE));
3034 }
3035 DrgFreeDraginfo(pDInfo); // Free DRAGINFO
3036 }
3037 return MRFROM2SHORT(DOR_NODROP, 0); // Drop not valid
3038
3039 case CN_INITDRAG:
3040 {
3041 BOOL wasemphasized = FALSE;
3042 PCNRDRAGINIT pcd = (PCNRDRAGINIT) mp2;
3043 PCNRITEM pci;
3044
3045 if (pcd) {
3046 pci = (PCNRITEM) pcd->pRecord;
3047 if (pci) {
3048 if ((INT) pci == -1)
3049 pci = NULL;
3050 else if (pci->rc.flRecordAttr & CRA_SELECTED)
3051 wasemphasized = TRUE;
3052 }
3053 else if (!*dcd->directory) {
3054 Runtime_Error(pszSrcFile, __LINE__, NULL);
3055 break;
3056 }
3057 else if (IsRoot(dcd->directory)) {
3058 saymsg(MB_ENTER, hwnd, GetPString(IDS_ERRORTEXT),
3059 GetPString(IDS_CANTDRAGROOTDIR));
3060 break;
3061 }
3062 if (hwndStatus2) {
3063 if (pci)
3064 WinSetWindowText(hwndStatus2, (CHAR *) GetPString(IDS_DRAGFILEOBJTEXT));
3065 else
3066 WinSetWindowText(hwndStatus2, (CHAR *) GetPString(IDS_DRAGDIRTEXT));
3067 }
3068 if (DoFileDrag(hwnd,
3069 dcd->hwndObject,
3070 mp2,
3071 NULL,
3072 pci ? NULL : dcd->directory,
3073 pci ? TRUE : FALSE)) {
3074 if ((pci && fUnHilite && wasemphasized) || dcd->ulItemsToUnHilite) {
3075 UnHilite(hwnd, TRUE, &dcd->lastselection, dcd->ulItemsToUnHilite);
3076 }
3077 }
3078 if (hwndStatus2) {
3079 WinSetFocus(HWND_DESKTOP, hwnd);
3080 PostMsg(hwnd, UM_RESCAN, MPVOID, MPVOID);
3081 }
3082 }
3083 }
3084 return 0;
3085
3086 case CN_DROP:
3087 if (mp2) {
3088
3089 LISTINFO *li;
3090 ULONG action = UM_ACTION;
3091
3092 li = DoFileDrop(hwnd, dcd->directory, TRUE, mp1, mp2);
3093 CheckPmDrgLimit(((PCNRDRAGINFO)mp2)->pDragInfo);
3094 if (li) {
3095 if (li->list && li->list[0] && IsRoot(li->list[0]))
3096 li->type = DO_LINK;
3097 else if (fDragndropDlg && (!*li->arcname || !li->info)) {
3098
3099 CHECKLIST cl;
3100
3101 memset(&cl, 0, sizeof(cl));
3102 cl.size = sizeof(cl);
3103 cl.flags = li->type;
3104 cl.list = li->list;
3105 cl.cmd = li->type;
3106 cl.prompt = li->targetpath;
3107 li->type = WinDlgBox(HWND_DESKTOP, dcd->hwndParent,
3108 DropListProc, FM3ModHandle,
3109 DND_FRAME, MPFROMP(&cl));
3110 if (li->type == DID_ERROR)
3111 Win_Error(DND_FRAME, HWND_DESKTOP, pszSrcFile, __LINE__,
3112 GetPString(IDS_DRAGDROPDIALOGTEXT));
3113 if (!li->type) {
3114 FreeListInfo(li);
3115 return 0;
3116 }
3117 li->list = cl.list;
3118 if (!li->list || !li->list[0]) {
3119 FreeListInfo(li);
3120 return 0;
3121 }
3122 }
3123 switch (li->type) {
3124 case DND_LAUNCH:
3125 strcat(li->targetpath, " %a");
3126 ExecOnList(dcd->hwndParent, li->targetpath,
3127 PROMPT | WINDOWED, NULL, NULL, li->list, NULL,
3128 pszSrcFile, __LINE__);
3129 FreeList(li->list);
3130 li->list = NULL;
3131 break;
3132 case DO_LINK:
3133 if (fLinkSetsIcon) {
3134 li->type = IDM_SETICON;
3135 action = UM_MASSACTION;
3136 }
3137 else
3138 li->type = IDM_COMPARE;
3139 break;
3140 case DND_EXTRACT:
3141 if (*li->targetpath && !IsFile(li->targetpath))
3142 li->type = IDM_EXTRACT;
3143 break;
3144 case DND_MOVE:
3145 li->type = IDM_MOVE;
3146 if (*li->targetpath && IsFile(li->targetpath) == 1) {
3147 action = UM_MASSACTION;
3148 li->type = IDM_ARCHIVEM;
3149 }
3150 break;
3151 case DND_WILDMOVE:
3152 li->type = IDM_WILDMOVE;
3153 if (*li->targetpath && IsFile(li->targetpath) == 1) {
3154 action = UM_MASSACTION;
3155 li->type = IDM_ARCHIVEM;
3156 }
3157 break;
3158 case DND_OBJECT:
3159 li->type = IDM_OBJECT;
3160 action = UM_MASSACTION;
3161 break;
3162 case DND_SHADOW:
3163 li->type = IDM_SHADOW;
3164 action = UM_MASSACTION;
3165 break;
3166 case DND_COMPARE:
3167 li->type = IDM_COMPARE;
3168 break;
3169 case DND_SETICON:
3170 action = UM_MASSACTION;
3171 li->type = IDM_SETICON;
3172 break;
3173 case DND_COPY:
3174 li->type = IDM_COPY;
3175 if (*li->targetpath && IsFile(li->targetpath) == 1) {
3176 action = UM_MASSACTION;
3177 li->type = IDM_ARCHIVE;
3178 }
3179 break;
3180 case DND_WILDCOPY:
3181 li->type = IDM_WILDCOPY;
3182 if (*li->targetpath && IsFile(li->targetpath) == 1) {
3183 action = UM_MASSACTION;
3184 li->type = IDM_ARCHIVE;
3185 }
3186 break;
3187 default:
3188 if (*li->arcname && li->info) {
3189 action = UM_MASSACTION;
3190 li->type =
3191 (li->type == DO_MOVE) ? IDM_FAKEEXTRACTM : IDM_FAKEEXTRACT;
3192 }
3193 else if (*li->targetpath && IsFile(li->targetpath) == 1) {
3194 action = UM_MASSACTION;
3195 li->type = (li->type == DO_MOVE) ? IDM_ARCHIVEM : IDM_ARCHIVE;
3196 }
3197 else
3198 li->type = (li->type == DO_MOVE) ? IDM_MOVE : IDM_COPY;
3199 break;
3200 }
3201 if (!li->list || !li->list[0])
3202 FreeListInfo(li);
3203 else if (!PostMsg(dcd->hwndObject, action, MPFROMP(li), MPVOID))
3204 FreeListInfo(li);
3205 else {
3206
3207 USHORT usop = 0;
3208
3209 switch (li->type) {
3210 case IDM_COPY:
3211 case IDM_WILDCOPY:
3212 usop = DO_COPY;
3213 break;
3214 case IDM_MOVE:
3215 case IDM_WILDMOVE:
3216 case IDM_ARCHIVEM:
3217 usop = DO_MOVE;
3218 break;
3219 }
3220 if (usop)
3221 return MRFROM2SHORT(DOR_DROP, usop);
3222 }
3223 }
3224 }
3225 return 0;
3226
3227 case CN_ENDEDIT:
3228 case CN_BEGINEDIT:
3229 {
3230 PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
3231 PCNRITEM pci = (PCNRITEM) ((PCNREDITDATA) mp2)->pRecord;
3232
3233 if (pfi || pci) {
3234
3235 MRESULT mre;
3236
3237 mre = CnrDirectEdit(hwnd, msg, mp1, mp2);
3238 if (mre != (MRESULT) - 1)
3239 return mre;
3240 }
3241 else if (!pfi && !pci)
3242 PostMsg(hwnd, UM_FIXCNRMLE, MPFROMLONG(CCHMAXPATH), MPVOID);
3243 }
3244 return 0;
3245
3246 case CN_REALLOCPSZ:
3247 {
3248 PFIELDINFO pfi = ((PCNREDITDATA) mp2)->pFieldInfo;
3249 PCNRITEM pci = (PCNRITEM) ((PCNREDITDATA) mp2)->pRecord;
3250 HWND hwndMLE;
3251 CHAR testname[CCHMAXPATH];
3252
3253 if (!pci && !pfi) {
3254 hwndMLE = WinWindowFromID(hwnd, CID_MLE);
3255 WinQueryWindowText(hwndMLE, sizeof(s), s);
3256 chop_at_crnl(s);
3257 bstrip(s);
3258 if (*s) {
3259 if (!DosQueryPathInfo(s,
3260 FIL_QUERYFULLNAME,
3261 testname, sizeof(testname))) {
3262 if (!SetDir(dcd->hwndParent, hwnd, testname, 1)) {
3263 PostMsg(hwnd, UM_SETDIR, MPFROMP(testname), MPVOID);
3264 }
3265 }
3266 }
3267 }
3268 else {
3269
3270 MRESULT mre;
3271
3272 mre = CnrDirectEdit(hwnd, msg, mp1, mp2);
3273 if (mre != (MRESULT) - 1)
3274 return mre;
3275 }
3276 }
3277 return 0;
3278
3279 case CN_EMPHASIS:
3280 if (!mp2)
3281 Runtime_Error(pszSrcFile, __LINE__, "mp2 NULL");
3282 else {
3283 PNOTIFYRECORDEMPHASIS pre = mp2;
3284 PCNRITEM pci;
3285 CHAR s[CCHMAXPATHCOMP + 91];
3286
3287 pci = (PCNRITEM) (pre ? pre->pRecord : NULL);
3288 if (!pci) {
3289 if (hwndStatus2)
3290 WinSetWindowText(hwndStatus2, NullStr);
3291 if (fMoreButtons) {
3292 WinSetWindowText(hwndName, NullStr);
3293 WinSetWindowText(hwndDate, NullStr);
3294 WinSetWindowText(hwndAttr, NullStr);
3295 }
3296 if (hwndMain)
3297 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
3298 break;
3299 }
3300 if (pre->fEmphasisMask & CRA_SELECTED) {
3301 if (pci->rc.flRecordAttr & CRA_SELECTED) {
3302 dcd->selectedbytes += (pci->cbFile + pci->easize);
3303 dcd->selectedfiles++;
3304 }
3305 else if (dcd->selectedfiles) {
3306 dcd->selectedbytes -= (pci->cbFile + pci->easize);
3307 dcd->selectedfiles--;
3308 }
3309 if (!dcd->suspendview) {
3310 commafmt(tf, sizeof(tf), dcd->selectedfiles);
3311 CommaFmtULL(tb, sizeof(tb), dcd->selectedbytes, 'K');
3312 sprintf(s, "%s / %s", tf, tb);
3313 WinSetDlgItemText(dcd->hwndClient, DIR_SELECTED, s);
3314 }
3315 }
3316 if (!dcd->suspendview && hwndMain && pci->pszFileName != NullStr &&
3317 (pre->fEmphasisMask & CRA_CURSORED) &&
3318 (pci->rc.flRecordAttr & CRA_CURSORED) &&
3319 WinQueryActiveWindow(dcd->hwndParent) == dcd->hwndFrame) {
3320 if (driveflags[toupper(*pci->pszFileName) - 'A'] & DRIVE_SLOW)
3321 WinSendMsg(hwndMain, UM_LOADFILE, MPVOID, MPVOID);
3322 else
3323 WinSendMsg(hwndMain,
3324 UM_LOADFILE, MPFROMP(pci->pszFileName), MPVOID);
3325 }
3326 if (!dcd->suspendview &&
3327 WinQueryActiveWindow(dcd->hwndParent) == dcd->hwndFrame) {
3328 if (pre->fEmphasisMask & CRA_CURSORED) {
3329 if (pci->rc.flRecordAttr & CRA_CURSORED) {
3330 if (fSplitStatus && hwndStatus2) {
3331 CommaFmtULL(tb, sizeof(tb), pci->cbFile + pci->easize, ' ');
3332 if (!fMoreButtons) {
3333 CHAR date[11];
3334
3335 DateFormat(date, pci->date);
3336 sprintf(s, " %s %s %02u%s%02u%s%02u [%s] %s",
3337 tb, date, pci->time.hours, TimeSeparator,
3338 pci->time.minutes, TimeSeparator, pci->time.seconds,
3339 pci->pszDispAttr, pci->pszFileName);
3340 }
3341 else {
3342 *tf = 0;
3343 if (pci->cbFile + pci->easize > 1024) {
3344 CommaFmtULL(tf, sizeof(tf),
3345 pci->cbFile + pci->easize, 'K');
3346 }
3347 sprintf(s, GetPString(IDS_STATUSSIZETEXT),
3348 tb,
3349 *tf ? " (" : NullStr, tf, *tf ? ")" : NullStr);
3350 }
3351 WinSetWindowText(hwndStatus2, s);
3352 }
3353 if (fMoreButtons) {
3354 CHAR szDate[DATE_BUF_BYTES];
3355
3356 WinSetWindowText(hwndName, pci->pszFileName);
3357 DateFormat(szDate, pci->date);
3358 sprintf(s, "%s %02u%s%02u%s%02u",
3359 szDate, pci->time.hours, TimeSeparator, pci->time.minutes,
3360 TimeSeparator, pci->time.seconds);
3361 WinSetWindowText(hwndDate, s);
3362 WinSetWindowText(hwndAttr, pci->pszDispAttr);
3363 }
3364 }
3365 }
3366 }
3367 }
3368 break;
3369
3370 case CN_ENTER:
3371 if (mp2) {
3372
3373 PCNRITEM pci = (PCNRITEM) ((PNOTIFYRECORDENTER) mp2)->pRecord;
3374 FILEFINDBUF3 ffb;
3375 HDIR hDir = HDIR_CREATE;
3376 ULONG nm = 1;
3377 APIRET status = 0;
3378
3379 SetShiftState();
3380 if (pci) {
3381 if (pci->rc.flRecordAttr & CRA_INUSE)
3382 break;
3383 DosError(FERR_DISABLEHARDERR);
3384 status = DosFindFirst(pci->pszFileName,
3385 &hDir,
3386 FILE_NORMAL | FILE_DIRECTORY |
3387 FILE_ARCHIVED | FILE_READONLY |
3388 FILE_HIDDEN | FILE_SYSTEM,
3389 &ffb, sizeof(ffb), &nm, FIL_STANDARD);
3390 priority_bumped();
3391 if (!status) {
3392 DosFindClose(hDir);
3393 if (ffb.attrFile & FILE_DIRECTORY) {
3394 if ((shiftstate & (KC_CTRL | KC_ALT)) == (KC_CTRL | KC_ALT))
3395 PostMsg(hwnd,
3396 WM_COMMAND,
3397 MPFROM2SHORT(IDM_SHOWALLFILES, 0), MPVOID);
3398 else if ((shiftstate & (KC_CTRL | KC_SHIFT)) ==
3399 (KC_CTRL | KC_SHIFT))
3400 OpenObject(pci->pszFileName, Settings, dcd->hwndFrame);
3401 else if (shiftstate & KC_CTRL)
3402 OpenObject(pci->pszFileName, Default, dcd->hwndFrame);
3403 else if (shiftstate & KC_SHIFT) {
3404
3405 HWND hwndDir;
3406
3407 hwndDir = OpenDirCnr((HWND) 0,
3408 dcd->hwndParent,
3409 dcd->hwndFrame,
3410 FALSE, pci->pszFileName);
3411 if (hwndDir) {
3412 if (fMinOnOpen)
3413 WinSetWindowPos(dcd->hwndFrame,
3414 HWND_BOTTOM,
3415 0, 0, 0, 0, SWP_MINIMIZE | SWP_ZORDER);
3416 if (fAutoTile)
3417 TileChildren(dcd->hwndParent, TRUE);
3418 WinSetWindowPos(hwndDir,
3419 HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
3420 }
3421 }
3422 else {
3423 strcpy(dcd->previous, dcd->directory);
3424 strcpy(dcd->directory, pci->pszFileName);
3425 dcd->stopflag++;
3426 if (!PostMsg(dcd->hwndObject,
3427 UM_RESCAN, MPVOID, MPFROMLONG(1))) {
3428 dcd->stopflag--;
3429 }
3430 else if (*dcd->directory) {
3431 if (hwndMain)
3432 WinSendMsg(hwndMain,
3433 UM_SETUSERLISTNAME,
3434 MPFROMP(dcd->directory), MPVOID);
3435 else
3436 add_udir(FALSE, dcd->directory);
3437 }
3438 }
3439 }
3440 else {
3441
3442 SWP swp;
3443
3444 WinQueryWindowPos(dcd->hwndFrame, &swp);
3445 WinSendMsg(hwnd,
3446 CM_SETRECORDEMPHASIS,
3447 MPFROMP(pci), MPFROM2SHORT(TRUE, CRA_INUSE));
3448 DefaultViewKeys(hwnd,
3449 dcd->hwndFrame,
3450 dcd->hwndParent, &swp, pci->pszFileName);
3451 WinSendMsg(hwnd,
3452 CM_SETRECORDEMPHASIS,
3453 MPFROMP(pci),
3454 MPFROM2SHORT(FALSE,
3455 CRA_INUSE |
3456 ((fUnHilite) ? CRA_SELECTED : 0)));
3457 }
3458 }
3459 else {
3460 if (!*dcd->directory || IsValidDir(dcd->directory)) {
3461 NotifyError(pci->pszFileName, status);
3462 RemoveCnrItems(hwnd, pci, 1, CMA_FREE | CMA_INVALIDATE | CMA_ERASE);
3463 if (hwndStatus)
3464 WinSetWindowText(hwndStatus,
3465 (CHAR *) GetPString(IDS_RESCANSUGGESTEDTEXT));
3466 }
3467 else {
3468 dcd->stopflag++;
3469 if (!PostMsg(dcd->hwndObject,
3470 UM_RESCAN, MPVOID, MPFROMLONG(1L))) {
3471 dcd->stopflag--;
3472 }
3473 else if (*dcd->directory) {
3474 if (hwndMain)
3475 WinSendMsg(hwndMain,
3476 UM_SETUSERLISTNAME,
3477 MPFROMP(dcd->directory), MPVOID);
3478 else
3479 add_udir(FALSE, dcd->directory);
3480 }
3481 }
3482 }
3483 }
3484 else if (*dcd->directory)
3485 OpenObject(dcd->directory, Default, hwnd);
3486 } // CN_ENTER
3487 break;
3488 } // switch mp1
3489 break;
3490 } // if dcd
3491 return 0;
3492
3493 case UM_LOADFILE:
3494 if (dcd && mp2) {
3495
3496 HWND hwnd;
3497
3498 if ((INT)mp1 == 5 || (INT)mp1 == 13 || (INT)mp1 == 21)
3499 hwnd = StartViewer(HWND_DESKTOP, (INT)mp1,
3500 (CHAR *)mp2, dcd->hwndFrame);
3501 else
3502 hwnd = StartMLEEditor(dcd->hwndParent,
3503 (INT)mp1, (CHAR *)mp2, dcd->hwndFrame);
3504 xfree((CHAR *)mp2, pszSrcFile, __LINE__);
3505 return MRFROMLONG(hwnd);
3506 }
3507 return 0;
3508
3509 case WM_SAVEAPPLICATION:
3510 if (dcd && ParentIsDesktop(hwnd, dcd->hwndParent)) {
3511
3512 SWP swp;
3513
3514 WinQueryWindowPos(dcd->hwndFrame, &swp);
3515 if (!(swp.fl & (SWP_HIDE | SWP_MINIMIZE | SWP_MAXIMIZE)))
3516 PrfWriteProfileData(fmprof, appname, "VDirSizePos", &swp, sizeof(swp));
3517 }
3518 break;
3519
3520 case WM_CLOSE:
3521 WinSendMsg(hwnd, WM_SAVEAPPLICATION, MPVOID, MPVOID);
3522 if (LastDir == hwnd)
3523 LastDir = (HWND) 0;
3524 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
3525 if (dcd) {
3526 dcd->stopflag++;
3527 if (!dcd->dontclose && ParentIsDesktop(dcd->hwndFrame, (HWND) 0))
3528 PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
3529 if (dcd->hwndObject) {
3530 // Ensure object window destroy does not attempt duplicate clean up
3531 WinSetWindowPtr(dcd->hwndObject, QWL_USER, NULL);
3532 if (!PostMsg(dcd->hwndObject, WM_CLOSE, MPVOID, MPVOID))
3533 Win_Error(dcd->hwndObject, hwnd, pszSrcFile, __LINE__, "hwndObject WinPostMsg failed");
3534 }
3535 if (dcd->hwndRestore)
3536 WinSetWindowPos(dcd->hwndRestore,
3537 HWND_TOP,
3538 0,
3539 0,
3540 0,
3541 0,
3542 SWP_RESTORE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER);
3543 FreeList(dcd->lastselection);
3544 WinSetWindowPtr(hwnd, QWL_USER, NULL);
3545 DosPostEventSem(CompactSem);
3546 }
3547 DosReleaseMutexSem(hmtxFiltering);
3548 WinDestroyWindow(WinQueryWindow(WinQueryWindow(hwnd, QW_PARENT),
3549 QW_PARENT));
3550 return 0;
3551
3552 case WM_DESTROY:
3553# ifdef FORTIFY
3554 DbgMsg(pszSrcFile, __LINE__, "WM_DESTROY hwnd %p TID %u", hwnd, GetTidForThread()); // 18 Jul 08 SHL fixme
3555# endif
3556 if (DirMenu)
3557 WinDestroyWindow(DirMenu);
3558 if (DirCnrMenu)
3559 WinDestroyWindow(DirCnrMenu);
3560 if (FileMenu)
3561 WinDestroyWindow(FileMenu);
3562 DirMenu = DirCnrMenu = FileMenu = (HWND) 0;
3563 EmptyCnr(hwnd);
3564 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
3565 xfree(dcd, pszSrcFile, __LINE__);
3566 dcd = NULL;
3567 DosReleaseMutexSem(hmtxFiltering);
3568# ifdef FORTIFY
3569 Fortify_LeaveScope();
3570# endif
3571 break;
3572 } // switch
3573
3574 if (dcd && dcd->oldproc) {
3575# ifdef FORTIFY // 11 May 08 SHL fixme debug fortify
3576 if ((ULONG)dcd->oldproc == 0xa9a9a9a9)
3577 DbgMsg(pszSrcFile, __LINE__, "calling oldproc after dcd free msg %x mp1 %x mp2 %x",
3578 msg, mp1, mp2);
3579# endif
3580 return dcd->oldproc(hwnd, msg, mp1, mp2);
3581 }
3582 else
3583 return PFNWPCnr(hwnd, msg, mp1, mp2);
3584}
3585
3586/**
3587 * Search container for matching text
3588 * @return TRUE if key completely handled here
3589 */
3590
3591MRESULT EXPENTRY SearchContainer(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
3592{
3593 DIRCNRDATA *dcd = INSTDATA(hwnd);
3594 ULONG thistime;
3595 UINT len;
3596 SEARCHSTRING srch;
3597 PCNRITEM pci;
3598 USHORT key;
3599
3600 if (!dcd)
3601 return FALSE;
3602
3603 // Just to be safe, caller has probably already checked
3604 if (SHORT1FROMMP(mp1) & KC_KEYUP)
3605 return FALSE; // Let PM process key
3606
3607 // Just to be safe, caller has probably already cached
3608 shiftstate = (SHORT1FROMMP(mp1) & (KC_SHIFT | KC_ALT | KC_CTRL));
3609
3610 // If not plain character or suppressed
3611 // Shift toggles configured setting
3612 if (shiftstate & (KC_ALT | KC_CTRL) || (shiftstate & KC_SHIFT ? !fNoSearch : fNoSearch))
3613 return FALSE; // Let PM process key
3614
3615 if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
3616 key = SHORT2FROMMP(mp2);
3617 if (key == VK_BACKSPACE)
3618 key = '\x8';
3619 else if (key == VK_ESC)
3620 key = '\x1b';
3621 else
3622 return FALSE; // Let PM process key
3623 }
3624 else if (SHORT1FROMMP(mp1) & KC_CHAR)
3625 key = SHORT1FROMMP(mp2);
3626 else
3627 return FALSE;
3628
3629 thistime = WinQueryMsgTime(WinQueryAnchorBlock(hwnd));
3630 if (thistime > dcd->lasttime + 3000)
3631 *dcd->szCommonName = 0; // 3 seconds since last character
3632 dcd->lasttime = thistime;
3633
3634 switch (key) {
3635 case '\x1b': // Esc
3636 *dcd->szCommonName = 0;
3637 break;
3638 default:
3639 if (key == ' ' && !*dcd->szCommonName)
3640 break; // Let PM process space to allow select toggle
3641 len = strlen(dcd->szCommonName);
3642 if (key == '\x8') {
3643 // Backspace
3644 if (len) {
3645 len--;
3646 dcd->szCommonName[len] = 0; // Chop
3647 }
3648 }
3649 else {
3650 if (len >= CCHMAXPATH - 1) {
3651 if (!fErrorBeepOff)
3652 DosBeep(250,100);
3653 // WinAlarm(hwnd,WA_WARNING);
3654 }
3655 else {
3656 dcd->szCommonName[len] = toupper(key);
3657 dcd->szCommonName[len + 1] = 0;
3658 }
3659 }
3660 // Case insensitive search
3661 memset(&srch, 0, sizeof(SEARCHSTRING));
3662 srch.cb = (ULONG) sizeof(SEARCHSTRING);
3663 srch.pszSearch = (PSZ) dcd->szCommonName;
3664 srch.fsPrefix = TRUE;
3665 srch.fsCaseSensitive = FALSE;
3666 srch.usView = CV_ICON;
3667 pci = WinSendMsg(hwnd, CM_SEARCHSTRING, MPFROMP(&srch),
3668 MPFROMLONG(CMA_FIRST));
3669 if (pci && (INT) pci != -1) {
3670 // Got match make found item current item
3671 USHORT attrib = CRA_CURSORED;
3672 // 29 Mar 09 SHL fixme to clear other object select if not extended select
3673 if (!stricmp(pci->pszDisplayName, dcd->szCommonName))
3674 attrib |= CRA_SELECTED;
3675 WinSendMsg(hwnd, CM_SETRECORDEMPHASIS, MPFROMP(pci),
3676 MPFROM2SHORT(TRUE, attrib));
3677 // make sure that record shows in viewport
3678 ShowCnrRecord(hwnd, (PMINIRECORDCORE) pci);
3679 return (MRESULT)TRUE;
3680 }
3681 else {
3682 if (key == ' ')
3683 return FALSE; // Let PM process space to toggle select
3684 // No match
3685 // Erase non-matching last character, len is not yet incremented
3686 dcd->szCommonName[len] = 0;
3687 if (len == 0 && key != '\\') {
3688 // Let's see if user forgot leading backslash
3689 if (SearchContainer(hwnd, msg, mp1, MPFROM2SHORT('\\', 0))) {
3690 if (SearchContainer(hwnd, msg, mp1, mp2))
3691 return (MRESULT)TRUE; // Grab key from PM
3692 }
3693 }
3694 if (*dcd->szCommonName)
3695 return (MRESULT)TRUE; // Have partial match, grab key from PM
3696#if 0 // 15 Mar 09 SHL fixme to not hang
3697 if (!fErrorBeepOff)
3698 DosBeep(250,100);
3699 // WinAlarm(hwnd,WA_WARNING);
3700#endif
3701 }
3702 } // switch
3703
3704 return FALSE; // Let PM process key
3705}
3706
3707HWND StartDirCnr(HWND hwndParent, CHAR * directory, HWND hwndRestore,
3708 ULONG flags)
3709{
3710 /**
3711 * bitmapped flags:
3712 * 0x00000001 = don't close app when window closes
3713 * 0x00000002 = no frame controls
3714 */
3715
3716 HWND hwndFrame = (HWND) 0, hwndClient;
3717 ULONG FrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
3718 FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE;
3719 USHORT id;
3720 static USHORT idinc = 0;
3721 DIRCNRDATA *dcd;
3722 static BOOL first = FALSE;
3723
3724 if (flags & 2)
3725 FrameFlags &= (~(FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER |
3726 FCF_MINMAX | FCF_ICON));
3727 if (!idinc)
3728 idinc = (rand() % 100);
3729 if (!hwndParent)
3730 hwndParent = HWND_DESKTOP;
3731 if (ParentIsDesktop(hwndParent, hwndParent))
3732 FrameFlags |= (FCF_TASKLIST | FCF_MENU);
3733 if (!hwndMain && !first) {
3734 if (DirCnrMenu) {
3735 MENUITEM mi;
3736 memset(&mi, 0, sizeof(mi));
3737 WinSendMsg(DirCnrMenu,
3738 MM_DELETEITEM, MPFROM2SHORT(IDM_DRIVESMENU, FALSE), MPVOID);
3739 mi.iPosition = MIT_END;
3740 mi.afStyle = MIS_TEXT;
3741 mi.id = IDM_DRIVESMENU;
3742 WinSendMsg(DirCnrMenu,
3743 MM_INSERTITEM,
3744 MPFROMP(&mi), MPFROMP(GetPString(IDS_DRIVESMENUTEXT)));
3745 }
3746 first = TRUE;
3747 }
3748 if (directory) {
3749 hwndFrame = WinCreateStdWindow(hwndParent,
3750 WS_VISIBLE,
3751 &FrameFlags,
3752 (CHAR *) WC_DIRCONTAINER,
3753 NULL,
3754 WS_VISIBLE | fwsAnimate,
3755 FM3ModHandle, DIR_FRAME, &hwndClient);
3756 if (hwndFrame && hwndClient) {
3757 id = DIR_FRAME + idinc++;
3758 if (idinc > 99)
3759 idinc = 0;
3760 WinSetWindowUShort(hwndFrame, QWS_ID, id);
3761# ifdef FORTIFY
3762 Fortify_EnterScope();
3763# endif
3764 dcd = xmallocz(sizeof(DIRCNRDATA), pszSrcFile, __LINE__);
3765 if (!dcd) {
3766 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3767 hwndFrame = (HWND) 0;
3768 }
3769 else {
3770 dcd->size = sizeof(DIRCNRDATA);
3771 dcd->id = id;
3772 dcd->type = DIR_FRAME;
3773 dcd->hwndParent = (hwndParent) ? hwndParent : HWND_DESKTOP;
3774 dcd->hwndFrame = hwndFrame;
3775 dcd->hwndClient = hwndClient;
3776 dcd->hwndRestore = hwndRestore;
3777 dcd->dontclose = ((flags & 1) != 0);
3778 dcd->ds.detailslongname = dsDirCnrDefault.detailslongname;
3779 dcd->ds.detailssubject = dsDirCnrDefault.detailssubject;
3780 dcd->ds.detailsea = dsDirCnrDefault.detailsea;
3781 dcd->ds.detailssize = dsDirCnrDefault.detailssize;
3782 dcd->ds.detailsicon = dsDirCnrDefault.detailsicon;
3783 dcd->ds.detailsattr = dsDirCnrDefault.detailsattr;
3784 dcd->ds.detailscrdate = dsDirCnrDefault.detailscrdate;
3785 dcd->ds.detailscrtime = dsDirCnrDefault.detailscrtime;
3786 dcd->ds.detailslwdate = dsDirCnrDefault.detailslwdate;
3787 dcd->ds.detailslwtime = dsDirCnrDefault.detailslwtime;
3788 dcd->ds.detailsladate = dsDirCnrDefault.detailsladate;
3789 dcd->ds.detailslatime = dsDirCnrDefault.detailslatime;
3790 strcpy(dcd->directory, directory);
3791 add_udir(FALSE, directory);
3792 {
3793 PFNWP oldproc;
3794
3795 oldproc = WinSubclassWindow(hwndFrame, (PFNWP) DirFrameWndProc);
3796 WinSetWindowPtr(hwndFrame, QWL_USER, (PVOID) oldproc);
3797 }
3798 dcd->hwndCnr = WinCreateWindow(hwndClient,
3799 WC_CONTAINER,
3800 NULL,
3801 CCS_AUTOPOSITION | CCS_MINIICONS |
3802 CCS_MINIRECORDCORE | ulCnrType,
3803 0,
3804 0,
3805 0,
3806 0,
3807 hwndClient,
3808 HWND_TOP, (ULONG) DIR_CNR, NULL, NULL);
3809 if (!dcd->hwndCnr) {
3810 Win_Error(hwndClient, hwndClient, pszSrcFile, __LINE__,
3811 PCSZ_WINCREATEWINDOW);
3812 PostMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
3813 DosRequestMutexSem(hmtxFiltering, SEM_INDEFINITE_WAIT);
3814 free(dcd);
3815 DosReleaseMutexSem(hmtxFiltering);
3816 hwndFrame = (HWND) 0;
3817 }
3818 else {
3819# ifdef FORTIFY
3820 Fortify_ChangeScope(dcd, -1);
3821# endif
3822 RestorePresParams(dcd->hwndCnr, PCSZ_DIRCNR);
3823 WinSetWindowPtr(dcd->hwndCnr, QWL_USER, (PVOID) dcd);
3824 dcd->oldproc = WinSubclassWindow(dcd->hwndCnr,
3825 (PFNWP) DirCnrWndProc);
3826 {
3827 USHORT ids[] = { DIR_TOTALS, DIR_SELECTED, DIR_VIEW, DIR_SORT,
3828 DIR_FILTER, DIR_FOLDERICON, DIR_MAX, 0
3829 };
3830
3831 if (!(flags & 2))
3832 ids[6] = 0;
3833 CommonCreateTextChildren(dcd->hwndClient,
3834 WC_DIRSTATUS, ids);
3835 }
3836 if (!PostMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID))
3837 WinSendMsg(dcd->hwndCnr, UM_SETUP, MPVOID, MPVOID);
3838 if (FrameFlags & FCF_TASKLIST) {
3839
3840 SWP swp, swpD;
3841 ULONG size = sizeof(swp);
3842 LONG cxScreen, cyScreen;
3843
3844 WinQueryTaskSizePos(WinQueryAnchorBlock(hwndFrame), 0, &swp);
3845 if (PrfQueryProfileData(fmprof, appname, "VDirSizePos", &swpD, &size)) {
3846 cxScreen = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
3847 cyScreen = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
3848 if (swp.x + swpD.cx > cxScreen)
3849 swp.x = cxScreen - swpD.cx;
3850 if (swp.y + swpD.cy > cyScreen)
3851 swp.y = cyScreen - swpD.cy;
3852 swp.cx = swpD.cx;
3853 swp.cy = swpD.cy;
3854 }
3855 WinSetWindowPos(hwndFrame,
3856 HWND_TOP,
3857 swp.x,
3858 swp.y,
3859 swp.cx,
3860 swp.cy,
3861 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER |
3862 SWP_ACTIVATE);
3863 }
3864 WinShowWindow(dcd->hwndCnr, TRUE);
3865 }
3866 }
3867# ifdef FORTIFY
3868 Fortify_LeaveScope();
3869# endif
3870 }
3871 }
3872 return hwndFrame;
3873}
3874
3875#pragma alloc_text(DIRCNRS,DirCnrWndProc,DirObjWndProc,DirClientWndProc)
3876#pragma alloc_text(DIRCNRS,DirTextProc,DirFrameWndProc)
3877#pragma alloc_text(STARTUP,StartDirCnr)
Note: See TracBrowser for help on using the repository browser.